obj = SomeObject.new
def obj.new_method
"do some things"
end
puts obj.new_method
> "do some things"
Run Code Online (Sandbox Code Playgroud)
这没问题.但是,我需要在现有方法中做同样的事情:
def some_random_method
def obj.new_method
"do some things"
end
end
Run Code Online (Sandbox Code Playgroud)
也可以正常工作,但在方法中使用方法看起来非常可怕.问题是,有没有其他方法可以添加这样的方法?
vis*_*ise 79
我问这个问题已经很久了.在ruby 1.9+中,有一种更好的方法可以通过使用define_singleton_method,如下所示:
obj = SomeObject.new
obj.define_singleton_method(:new_method) do
"do some things"
end
Run Code Online (Sandbox Code Playgroud)
小智 51
使用Mixin.
module AdditionalMethods
def new_method
"do some things"
end
end
obj = SomeObject.new
obj.extend(AdditionalMethods)
puts obj.new_method
> "do some things"
Run Code Online (Sandbox Code Playgroud)
只是一个有趣的注意事项:
如果你已经离开了:
def my_method
def my_other_method; end
end
Run Code Online (Sandbox Code Playgroud)
然后my_other_method实际上将在对象的CLASS上定义,而不是接收者my_method是一个实例.
但是如果你去(就像你一样):
def my_method
def self.my_other_method; end
end
Run Code Online (Sandbox Code Playgroud)
然后my_other_method在实例的本征类上定义.
与你的问题没有直接关系,但有点有趣;)
您可以使用模块.
module ObjSingletonMethods
def new_method
"do some things"
end
end
obj.extend ObjSingletonMethods
puts obj.new_method # => do some things
Run Code Online (Sandbox Code Playgroud)
现在,如果您需要向该对象添加更多方法,您只需要在模块中实现这些方法即可.
有几种方法可以实现此目的,它们都与单例类有关:
您可以使用class <<惯用语打开单例类定义:
obj = Object.new
class << obj
def my_new_method
...
end
end
Run Code Online (Sandbox Code Playgroud)或者您可以define_singleton_method在obj上使用:
obj = Object.new
obj.define_sigleton_method(:my_new_method) do
...
end
Run Code Online (Sandbox Code Playgroud)您也可以define_method在单例类中使用:
obj = Object.new
obj.singleton_class.define_method(:my_new_method) do
...
end
Run Code Online (Sandbox Code Playgroud)或者您可以def直接使用:
obj = Object.new
def obj.my_new_method
...
end
Run Code Online (Sandbox Code Playgroud)注意示例3,我认为单例类的概念在该类上更加清晰。这两个示例之间存在差异:
a = Object.new
b = Object.new
# -- defining a new method in the object's "class" --
a.class.define_method(:abc) do
puts "hello abc"
end
a.abc # prints "hello abc"
b.abc # also prints "hello abc"
# -- defining a new method in the object's "singleton class" --
a.singleton_class.define_method(:bcd) do
puts "hello bcd"
end
a.bcd # prints "hello bcd"
b.bcd # error undefined method
Run Code Online (Sandbox Code Playgroud)
这是因为每个对象都有其自己的单例类:
a = Object.new
b = Object.new
p a.class # prints "Object"
p a.singleton_class # prints "#<Class:#<Object:0x000055ebc0b84438>>"
p b.class # also prints "Object"
p b.singleton_class # prints "#<Class:#<Object:0x000055ebc0b84410>>" (a different reference address)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
34529 次 |
| 最近记录: |