objects - ruby scripting
redefiniendo un solo método ruby en una sola instancia con un lambda (3)
No estoy seguro de en qué versión de Ruby se agregó (al menos 1.8.7), pero parece que hay una forma aún más sencilla de hacer esto:
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
Aprendí sobre esto mientras leía los Ruby Koans (lección about_class_methods.rb). Todavía no estoy del todo seguro de cuál es el propósito de esto, ya que me parece un poco peligroso.
En Ruby, ¿hay alguna manera de redefinir un método de una instancia particular de una clase utilizando un proceso? Por ejemplo:
class Foo
def bar()
return "hello"
end
end
x = Foo.new
y = Foo.new
(Algo como):
y.method(:bar) = lambda { return "goodbye" }
x.bar
y.bar
Productor:
hello
goodbye
Gracias.
Puede usar la class <<object
sintaxis class <<object
para obtener la "clase singleton" de un objeto (que es una clase padre especial que pertenece solo a ese objeto) y definir métodos solo para esa instancia. Por ejemplo:
str1 = "Hello"
str2 = "Foo"
class <<str1
def to_spanish
''Hola''
end
end
Ahora si lo hace str1.to_spanish
, devolverá "Hola", pero str2.to_spanish
le dará una excepción NoMethodFound.
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)
o, si quieres aplicar el parche de monos Objeto para hacerlo más fácil
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
o, si desea definir su proc en línea, esto puede ser más legible
class << y
define_method(:bar, proc { "foobar!" })
end
o,
class << y
define_method(:bar) { "foobar!" }
end
este es el más legible, pero probablemente no se ajuste a tus necesidades
def y.bar
"goodbye"
end