Ruby 将方法添加到实例化对象
这样行。但是,我需要在现有方法中执行相同的操作:Ruby 将方法添加到实例化对象,ruby,Ruby,这样行。但是,我需要在现有方法中执行相同的操作: obj = SomeObject.new def obj.new_method "do some things" end puts obj.new_method > "do some things" 也可以,但是在一个方法中有一个方法看起来非常可怕。问题是,有没有其他方法可以添加这种方法?使用Mixin def some_random_method def obj.new_method "do some things"
obj = SomeObject.new
def obj.new_method
"do some things"
end
puts obj.new_method
> "do some things"
也可以,但是在一个方法中有一个方法看起来非常可怕。问题是,有没有其他方法可以添加这种方法?使用Mixin
def some_random_method
def obj.new_method
"do some things"
end
end
您可以使用模块
module AdditionalMethods
def new_method
"do some things"
end
end
obj = SomeObject.new
obj.extend(AdditionalMethods)
puts obj.new_method
> "do some things"
现在,如果需要向该对象添加更多方法,只需在模块中实现这些方法即可。需要注意的一点是: 如果你去了:
module ObjSingletonMethods
def new_method
"do some things"
end
end
obj.extend ObjSingletonMethods
puts obj.new_method # => do some things
然后,my\u other\u方法
实际上将在对象的类上定义,尽管my\u方法
的接收者是一个实例
但是,如果您(像您那样)去:
然后在实例的特征类上定义my\u other\u方法
与您的问题不直接相关,但还是有点有趣;) 我很久没有问这个问题了。在ruby 1.9+中,有一种更好的方法,使用define_singleton_method
,如下所示:
def my_method
def self.my_other_method; end
end
在Ruby中,一切都是一个对象,甚至是类self
这里有一个Math class
本身的对象(您可以使用Math.class
访问该对象)。因此语法class有几种方法可以实现这一点,它们都与singleton类相关:
obj = Object.new
obj.define_singleton_method(:my_new_method) do
...
end
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
您可以使用class使用instance\u eval
:
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)
使用Mixin的另一种方法
obj = SomeObject.new
obj.instance_eval do
def new_method
puts 'do something new'
end
end
obj.new_method
> "do something new"
obj=SomeObject.new
类您确定第二段代码有效吗?因为我想它应该首先接受obj
作为一个方法参数,在它上面定义一个单例方法。所以他的算法有时会把最新的答案放在最前面。很有趣。我以后会看得更远。如果我在这个do
块中使用@field
,会发生什么?我会从当前类访问一个字段,还是它会使用obj
的字段?还没有真正正确地测试过这一点,但据我所知,mixin和这种方法是不等价的。这可以访问外部值,而mixin不能。您好,有拼写错误。define_sigleton_方法,在2的代码中应该是define_singleton_方法。@fanjieqi已修复。谢谢
Math.cos(1)
obj = Object.new
class << obj
def my_new_method
...
end
end
obj = Object.new
obj.define_singleton_method(:my_new_method) do
...
end
obj = Object.new
obj.singleton_class.define_method(:my_new_method) do
...
end
obj = Object.new
def obj.my_new_method
...
end
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)
obj = SomeObject.new
obj.instance_eval do
def new_method
puts 'do something new'
end
end
obj.new_method
> "do something new"
obj = SomeObject.new
class << obj
include AnotherModule
end