In Ruby, is there a way to redefine a method of a particular instance of a class using a proc? For example:
class Foo
def bar()
return "hello"
end
end
x = Foo.new
y = Foo.new
(Something like):
y.method(:bar) = lambda { return "goodbye" }
x.bar
y.bar
Producing:
hello
goodbye
Thanks.
def define_singleton_method_by_proc(obj, name, block)
metaclass = class << obj; self; end
metaclass.send(:define_method, name, block)
end
p = proc { "foobar!" }
define_singleton_method_by_proc(y, :bar, p)
or, if you want to monkey-patch Object to make it easy
class Object
# note that this method is already defined in Ruby 1.9
def define_singleton_method(name, callable = nil, &block)
block ||= callable
metaclass = class << self; self; end
metaclass.send(:define_method, name, block)
end
end
p = proc { "foobar!" }
y.define_singleton_method(:bar, p)
#or
y.define_singleton_method(:bar) do
"foobar!"
end
or, if you want to define your proc inline, this may be more readable
class << y
define_method(:bar, proc { "foobar!" })
end
or,
class << y
define_method(:bar) { "foobar!" }
end
this is the most readable, but probably doesn't fit your needs
def y.bar
"goodbye"
end
This question is highly related
I'm not sure what version of Ruby this was added in (at least 1.8.7), but there seems to be an even simpler way of doing this:
str1 = "Hello"
str2 = "Goodbye"
def str1.to_spanish
"Hola"
end
puts str1 # => Hello
puts str1.to_spanish # => Hola
puts str2 # => Goodbye
puts str2.to_spanish # => Throws a NoMethodError
Learnt about this whilst reading the Ruby Koans (about_class_methods.rb lesson). I'm still not entirely sure what the purpose of this is since it seems a bit dangerous to me.
You can use the syntax class <<object
to get an object's "singleton class" (that's a special parent class belonging only to that object) and define methods only for that instance. For example:
str1 = "Hello"
str2 = "Foo"
class <<str1
def to_spanish
'Hola'
end
end
Now if you do str1.to_spanish
, it will return "Hola", but str2.to_spanish
will give you a NoMethodFound exception.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With