所以,我想为一个对象定义一个单例方法,但我想用一个闭包来做。

例如,

def define_say(obj, msg)
  def obj.say
    puts msg
  end
end

o = Object.new
define_say o, "hello world!"
o.say

这不起作用,因为通过“def”定义单例方法。不是一个闭包,所以我得到一个“msg”的例外。是一个未定义的变量或方法。

我想要做的就是使用“define_method”。 Module类中的方法,但据我所知,这只能用于在类上定义一个方法......但我想要一个Singleton方法...

所以,我很乐意写这样的东西:

def define_say(obj, msg)
  obj.define_singleton_method(:say) {
    puts msg
  }
end

有没有人知道如何在不创建存储Proc的方法然后在单例方法中使用Proc的情况下实现这一目标? (基本上,我想要一个干净,非hacky这样做的方式)

有帮助吗?

解决方案

这是一个能够满足您需求的答案

def define_say(obj, msg)
  # Get a handle to the singleton class of obj
  metaclass = class << obj; self; end 

  # add the method using define_method instead of def x.say so we can use a closure
  metaclass.send :define_method, :say do
    puts msg
  end
end

用法(从IRB粘贴)

>> s = "my string"
=> "my string"
>> define_say(s, "I am S")
=> #<Proc:0xb6ed55b0@(irb):11>
>> s.say
I am S
=> nil

有关更多信息(以及一个使其不那么混乱的小库)请阅读:

http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html

顺便说一句,如果你是一个红宝石程序员,而你还没有读过,那么现在就去做吧!

其他提示

Object#define_singleton_method 顺便添加到ruby-1.9.2:

def define_say(obj, msg)
  obj.define_singleton_method(:say) do
    puts msg
  end
end
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top