I read that you can disable the did_you_mean gem (which is enabled by default) via the Ruby command line like so:
ruby --disable-did_you_mean script.rb
Is there a way to the same from within script.rb instead of the command line parameter?
The gem works by monkey patching NameError, and prepending DidYouMean::Correctable to its ancestors.
NameError.ancestors
#=> [DidYouMean::Correctable, NameError, StandardError, Exception, Object, Kernel, BasicObject]
You can work around this by redefining DidYouMean::Correctable#to_s as Wand Maker suggested, or you can remove the method from the module altogether:
module DidYouMean::Correctable
remove_method :to_s
end
which has the same outcome.
You can undo the module definition of DidYouMean by re-implementing in your script.rb, wherein you delegate the error handler to original Ruby implementation.
# Beginning of script.rb
module DidYouMean
module Correctable
prepend_features NameError
def to_s
super
end
end
end
ary = [1,2]
ary.att(0)
#=> undefined method `att' for [1, 2]:Array
# (repl):15:in `<main>'
Related
Article#to_archive is an alias for Article#archived!:
class Article
alias to_archive archived!
end
I need to ensure this, so I wrote this test:
describe '#to_archive' do
it 'is an alias to #archived!' do
expect(subject.method(:to_archive)).to eq(subject.method(:archived!))
end
end
However, I receive an error
Failure/Error: expect(subject.method(:to_archive)).to eq(subject.method(:archived!))
expected: #<Method: Article(#<Module:0x00000005a7c240>)#archived!>
got: #<Method: Article(#<Module:0x00000005a7c240>)#to_archive(archived!)>
It used to work in ruby < 2.3 IIRC. I tried alias_method, but it didn't help.
The definition of Method#== is not clear and/or useful, so you shouldn't rely on it.
To check that it is an alias, you can do this:
expect(subject.method(:to_archive).original_name).to eq(:archived!)
I need to use the prepend method, introduced in ruby 2.0, in ruby 1.9.3, where this method is not supported. Is there an equivalent method in ruby 1.9.3?
UPDATE
I need this working with ruby 1.9.3
module ActiveAdmin::Views::Pages::BaseExtension
def add_classes_to_body
super
#body.set_attribute "ng-app", "MyApp" #I need to add this line
end
end
class ActiveAdmin::Views::Pages::Base
prepend ActiveAdmin::Views::Pages::BaseExtension
end
prepend changes the core Ruby object model, specifically the way messages are dispatched, there is no way to do this in pure Ruby, therefore, there is no way to backport the prepend functionality.
In the bad old days before prepend we used to do this instead:
class ActiveAdmin::Views::Pages::Base
orig = instance_method(:add_classes_to_body)
define_method(:add_classes_to_body) do
orig.bind(self).()
#body.set_attribute "ng-app", "MyApp"
end
end
I could make it work using alias_method
class ActiveAdmin::Views::Pages::Base
alias_method :old_add_classes_to_body, :add_classes_to_body
def add_classes_to_body
old_add_classes_to_body
#body.set_attribute "ng-app", "MyApp"
end
end
I do the following in irb and have also tried out the same code in pry
class Number < Struct.new(:value)
end
class Number
def to_s
value.to_s
end
def inspect
"<<#{self}>>"
end
end
Now, if i do Number.new(2), it correctly returns <<2>> in irb, but in pry it incorrectly returns #<struct Number value=2> . Why is this so ?
Thank You
I'm not very familiar with pry (I've never used it until just now), but the obvious answer to your question is: because pry isn't calling inspect on your object. You can manually call it, and it works as expected:
Number.new(2).inspect
# => "<<2>>"
My question was: why isn't pry calling inspect, and what's it doing instead? Looking at the code, it looks like it calls pretty_inspect instead. There may be a smarter workaround, but the simplest thing that comes to mind for me is to just alias pretty_inspect to inspect for Number:
class Number
alias_method :pretty_inspect, :inspect
end
Number.new(2)
# => <<2>>
There is a Gem in my dependency list that is Monkey Patching to_json on String.
How can I figure where this monkey patching is happening?
Use source_location.
Returns the Ruby source filename and line number containing this method or nil if this method was not defined in Ruby (i.e. native)
$ cat monkey.rb
class String
def reverse
""
end
end
p String.instance_method(:reverse).source_location
$ ruby monkey.rb
["monkey.rb", 2]
puts String.instance_method(:to_json).source_location
I need to grab the name of the lexically enclosing method in Ruby 1.8; e.g.
def foo
this_method = __callee__ # => 'foo'
end
The above code is valid in Ruby 1.9, but fails in 1.8, since __callee__ was introduced in 1.9.
Any suggestions for doing this in 1.8? Kernel#caller looked promising, but seems to give me the call stack starting with the caller of the method, not the method itself.
I guess I could throw an exception, catch it, and grab the first element in the Exception#backtrace array, but my gut tells me that will be slow.
On Ruby 1.8.7 there is the __method__, not sure about 1.8.6.
Anyway, You can monkey patch the Kernel module:
module Kernel
# Defined in ruby 1.9
unless defined?(__callee__)
def __callee__
caller[0] =~ /`([^']*)'/ and $1
end
end
end
Have you checked whether the "backports" gem has it?