So, I want to define a singleton method for an object, but I want to do it using a closure.
所以,我想为一个对象定义一个单例方法,但我想用一个闭包来做。
For example,
例如,
def define_say(obj, msg)
def obj.say
puts msg
end
end
o = Object.new
define_say o, "hello world!"
o.say
This doesn't work because defining a singleton method via "def" is not a closure, so I get an exception that "msg" is an undefined variable or method.
这不起作用,因为通过“def”定义单例方法不是闭包,所以我得到一个例外,“msg”是一个未定义的变量或方法。
What I would like to do is something like using the "define_method" method in the Module class, but as far as I can tell, this can only be used to define a method on a class... but I want a Singleton Method...
我想做的就是在Module类中使用“define_method”方法,但据我所知,这只能用于在类上定义方法......但我想要一个Singleton方法。 ..
So, I would love to write it something like this:
所以,我想写这样的东西:
def define_say(obj, msg)
obj.define_singleton_method(:say) {
puts msg
}
end
Does anyone know how I can achieve this without having to create a method to store a Proc and then use the Proc within a singleton method? (basically, I want a clean, non-hacky way of doing this)
有没有人知道如何实现这一点,而无需创建一个存储Proc的方法,然后在单例方法中使用Proc? (基本上,我想要一个干净,非hacky这样做的方式)
2 个解决方案
#1
8
Here's an answer which does what you're looking for
这是一个答案,可以满足您的需求
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
Usage (paste from IRB)
用法(从IRB粘贴)
>> s = "my string"
=> "my string"
>> define_say(s, "I am S")
=> #<Proc:0xb6ed55b0@(irb):11>
>> s.say
I am S
=> nil
For more info (and a little library which makes it less messy) read this:
有关更多信息(以及一个使其不那么混乱的小库)请阅读:
http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html
http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html
As an aside, If you're a ruby programmer, and you HAVEN'T read that, go do it now~!
顺便说一句,如果你是一个红宝石程序员,而你还没有读过,那就去吧〜!
#2
14
Object#define_singleton_method
was added to ruby-1.9.2 by the way:
对象#define_singleton_method顺便添加到ruby-1.9.2:
def define_say(obj, msg)
obj.define_singleton_method(:say) do
puts msg
end
end
#1
8
Here's an answer which does what you're looking for
这是一个答案,可以满足您的需求
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
Usage (paste from IRB)
用法(从IRB粘贴)
>> s = "my string"
=> "my string"
>> define_say(s, "I am S")
=> #<Proc:0xb6ed55b0@(irb):11>
>> s.say
I am S
=> nil
For more info (and a little library which makes it less messy) read this:
有关更多信息(以及一个使其不那么混乱的小库)请阅读:
http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html
http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html
As an aside, If you're a ruby programmer, and you HAVEN'T read that, go do it now~!
顺便说一句,如果你是一个红宝石程序员,而你还没有读过,那就去吧〜!
#2
14
Object#define_singleton_method
was added to ruby-1.9.2 by the way:
对象#define_singleton_method顺便添加到ruby-1.9.2:
def define_say(obj, msg)
obj.define_singleton_method(:say) do
puts msg
end
end