使用 lambda 在单个实例上重新定义单个 ruby 方法
Posted
技术标签:
【中文标题】使用 lambda 在单个实例上重新定义单个 ruby 方法【英文标题】:redefining a single ruby method on a single instance with a lambda 【发布时间】:2010-10-22 15:03:30 【问题描述】:在 Ruby 中,有没有办法使用 proc 重新定义类的特定实例的方法?例如:
class Foo
def bar()
return "hello"
end
end
x = Foo.new
y = Foo.new
(类似):
y.method(:bar) = lambda return "goodbye"
x.bar
y.bar
制作:
hello
goodbye
谢谢。
【问题讨论】:
【参考方案1】:我不确定这是在哪个版本的 Ruby 中添加的(至少 1.8.7),但似乎有一种更简单的方法:
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
在阅读Ruby Koans(about_class_methods.rb 课程)时了解了这一点。 我仍然不完全确定这样做的目的是什么,因为这对我来说似乎有点危险。
【讨论】:
感谢您发布这个(更多)最新答案! 假设str.to_spanish
已经定义并且我想“重新定义”它,我如何从新定义的str.to_spanish
中调用“原始”str.to_spanish
?
如果str
是你的实例对象,String
是你的类,你可以通过String.to_spanish
调用类的方法版本
上帝我爱鲁比【参考方案2】:
您可以使用语法class <<object
来获取对象的“单例类”(这是仅属于该对象的特殊父类)并仅为该实例定义方法。例如:
str1 = "Hello"
str2 = "Foo"
class <<str1
def to_spanish
'Hola'
end
end
现在如果您执行str1.to_spanish
,它将返回“Hola”,但str2.to_spanish
会给您一个NoMethodFound 异常。
【讨论】:
如果他在一个简单的变量中有一个外部定义的proc,很难将它放入class创建的新范围 【参考方案3】: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)
或者,如果您想对对象进行猴子修补以使其变得容易
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
或者,如果你想定义你的 proc 内联,这可能更具可读性
class << y
define_method(:bar, proc "foobar!" )
end
或者,
class << y
define_method(:bar) "foobar!"
end
这是最易读的,但可能不符合您的需要
def y.bar
"goodbye"
end
This question is highly related
【讨论】:
想知道为什么最后一个解决方案“可能不符合您的需求”? 两者:``` class Foo end obj = Foo.new class @AbdulRahmanK 因为他问如何使用 lambda 来实现,而这种方式不使用 lambda,但我还是想包含它以上是关于使用 lambda 在单个实例上重新定义单个 ruby 方法的主要内容,如果未能解决你的问题,请参考以下文章
在定义单个 AWS::Serverless::Function 的 SAM 模板中指定多个 API 阶段和 Lambda 别名