2009-12-11 27 views
41
obj = SomeObject.new 

def obj.new_method 
    "do some things" 
end 

puts obj.new_method 
> "do some things" 

此工作正常。不过,我需要做一个现有的方法中同样的事情:将方法添加到实例化对象

def some_random_method 
    def obj.new_method 
    "do some things" 
    end 
end 

确定工作为好,但有一个方法中的方法看起来相当可怕。问题是,是否有添加这种方法的替代方法?

+0

你确定代码的第二片段的作品?因为我想它应该首先接受'obj'作为方法参数来定义一个单例方法。 – Chirantan 2009-12-11 12:57:45

回答

66

这是一个很长的时间,因为我问这个。在红宝石1.9+,还有通过使用define_singleton_method这样做的更好的方法,具体如下:

obj = SomeObject.new 

obj.define_singleton_method(:new_method) do 
    "do some things" 
end 
+2

如果我在这个'do'块中使用'@ field',会发生什么?我会从当前类访问一个字段,还是会使用'obj'字段? – ciembor 2013-01-31 10:30:54

+1

还没有真正地测试过这个,但据我可以告诉mixin这种方法是不相同的。这可以访问外部值,而mixin则不会。 – vise 2013-01-31 13:10:53

43

使用Mixin。

module AdditionalMethods 
    def new_method 
    "do some things" 
    end 
end 

obj = SomeObject.new 
obj.extend(AdditionalMethods) 

puts obj.new_method 
> "do some things" 
6

您可以使用模块。

​​

现在,如果您需要向该对象添加更多方法,您只需要在模块中实现方法并完成即可。

7

只是一个有趣的一点:

,如果你已经代替了:

def my_method 
    def my_other_method; end 
end 

然后my_other_method实际上就没有顶住那的my_method接收机为实例对象的类定义。

但是如果你去(像你一样):

def my_method 
    def self.my_other_method; end 
end 

然后my_other_method是在实例的eigenclass定义。

没有直接关系到你的问题,但很有趣尽管如此;)