使用 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 别名

从单个Lambda调用多个Lambda

在单个 S3 对象上传事件上触发多个 lambda

匿名函数lambda

如何在单个 lambda 表达式中同时使用更新和加入 [关闭]

单个 EC2 实例上的多个网站(或 VPC 分步指南!)