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 :(得分:74)
我问这个问题已经很久了。在ruby 1.9+中,使用define_singleton_method
有一种更好的方法,如下所示:
obj = SomeObject.new
obj.define_singleton_method(:new_method) do
"do some things"
end
答案 1 :(得分:50)
使用Mixin。
module AdditionalMethods
def new_method
"do some things"
end
end
obj = SomeObject.new
obj.extend(AdditionalMethods)
puts obj.new_method
> "do some things"
答案 2 :(得分:8)
只是一个有趣的注意事项:
如果你已经离开了:
def my_method
def my_other_method; end
end
然后my_other_method
实际上会在对象的CLASS上定义,而不是my_method
的接收者是一个实例。
但是如果你去(就像你一样):
def my_method
def self.my_other_method; end
end
然后在实例的本征类上定义my_other_method
。
与你的问题没有直接关系,但有点有趣;)
答案 3 :(得分:6)
您可以使用模块。
module ObjSingletonMethods
def new_method
"do some things"
end
end
obj.extend ObjSingletonMethods
puts obj.new_method # => do some things
现在,如果您需要向该对象添加更多方法,您只需要在模块中实现这些方法即可。
答案 4 :(得分:1)
@media all and (max-aspect-ratio: 100/68){
...
table#main td#mainLeft table#logoMoto{
width: 30vw;
height: 66vw;
font-family: Arial, Helvetica, sans-serif;
--> font-size: 1.98vw; // was font-size: 2vw;
vertical-align: top;
}
...
}
语法class Some
end
obj = Some.new
class << obj
def hello
puts 'hello'
end
end
obj.hello
obj2 = Some.new
obj2.hello # error
意味着我们正在为对象打开类的定义。您可能知道我们可以使用如下语法定义Ruby类方法:
class << obj
然后我们可以使用这样的方法:
class Math
class << self
def cos(x)
...
end
def sin(x)
...
end
end
end
在Ruby中,一切都是对象 - 甚至是类。 Math.cos(1)
此处是self
本身的对象(您可以使用Math class
访问该对象)。所以语法Math.class
意味着我们正在为class << self
打开课程。是的,这意味着Math class object
也有类(Math.class.class)。
答案 5 :(得分:1)
有几种语法可以实现这一点,它们都与单例类有关:
您可以使用class <<
惯用法打开单例类定义:
obj = Object.new
class << obj
def my_new_method
...
end
end
或者您可以在obj:
上使用define_singleton_method
obj = Object.new
obj.define_sigleton_method(:my_new_method) do
...
end
您也可以使用单身类中的define_method
:
obj = Object.new
obj.singleton_class.define_method(:my_new_method) do
...
end
或者您可以直接使用def
:
obj = Object.new
def obj.my_new_method
...
end
注意例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
这是因为每个对象都有自己的单例类:
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)
答案 6 :(得分:1)
使用instance_eval
:
obj = SomeObject.new
obj.instance_eval do
def new_method
puts 'do something new'
end
end
obj.new_method
> "do something new"
答案 7 :(得分:0)
使用Mixin的另一种方式
obj = SomeObject.new
class << obj
include AnotherModule
end
这包括从AnotherModule
到当前对象的所有方法。