我在blog找到了一个关于 class << self , Eigenclass 和不同类型的 methods 的超级简单解释 .
在Ruby中,有三种类型的方法可以应用于类:
实例方法
单身方法
类方法
实例方法和类方法几乎与其他编程语言中的同义词类似 .
class Foo
def an_instance_method
puts "I am an instance method"
end
def self.a_class_method
puts "I am a class method"
end
end
foo = Foo.new
def foo.a_singleton_method
puts "I am a singletone method"
end
访问 Eigenclass (包括单例方法)的另一种方法是使用以下语法( class << ):
foo = Foo.new
class << foo
def a_singleton_method
puts "I am a singleton method"
end
end
现在你可以为 self 定义一个单例方法,它在这个上下文中是类 Foo 本身:
class Foo
class << self
def a_singleton_and_class_method
puts "I am a singleton method for self and a class method for Foo"
end
end
end
815
什么类<<东西做:
class Hi
self #=> Hi
class << self #same as 'class << Hi'
self #=> #<Class:Hi>
self == Hi.singleton_class #=> true
end
end
[it makes** self == thing.singleton_class **in the context of its block] .
what.singleton_class是什么?
hi = String.new
def hi.a
end
hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true
hi 对象从其 #singleton_class.instance_methods 继承其 #methods ,然后从其 #class.instance_methods 继承 . 这里我们给了 hi 的 singleton class 实例方法 :a . 它可以用 class << hi 代替 . hi 的 #singleton_class 有所有实例方法 hi 的 #class 有,可能还有一些(这里是 :a ) .
[instance methods of thing's** #classand#singleton_class **can be applied directly to thing. when ruby sees thing.a, it first looks for :a method definition in thing.singleton_class.instance_methods and then in thing.class.instance_methods]
顺便说一下 - 他们调用对象的 singleton class == metaclass == eigenclass .
12
首先, class << foo 语法打开 foo 的单例类(eigenclass) . 这允许您专门化在该特定对象上调用的方法的行为 .
a = 'foo'
class << a
def inspect
'"bar"'
end
end
a.inspect # => "bar"
a = 'foo' # new object, new singleton class
a.inspect # => "foo"
class String
class << self
def value_of obj
obj.to_s
end
end
end
String.value_of 42 # => "42"
这也可以写成速记:
class String
def self.value_of obj
obj.to_s
end
end
甚至更短:
def String.value_of obj
obj.to_s
end
在函数定义中, self 指的是调用函数的对象 . 在这种情况下, class << self 打开该对象的单例类;一个用途就是实现穷人的状态机:
class StateMachineExample
def process obj
process_hook obj
end
private
def process_state_1 obj
# ...
class << self
alias process_hook process_state_2
end
end
def process_state_2 obj
# ...
class << self
alias process_hook process_state_1
end
end
# Set up initial state
alias process_hook process_state_1
end
class Zen
end
z1 = Zen.new
z2 = Zen.new
class << z1
def say_hello
puts "Hello!"
end
end
z1.say_hello # Output: Hello!
z2.say_hello # Output: NoMethodError: undefined method `say_hello'…
class SomeClass
class << self
def test
end
end
end
test_obj = SomeClass.new
def test_obj.test_2
end
class << test_obj
def test_3
end
end
puts "Singleton's methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton's methods of test_obj"
puts test_obj.singleton_methods
6 回答
我在blog找到了一个关于
class << self
,Eigenclass
和不同类型的methods
的超级简单解释 .在Ruby中,有三种类型的方法可以应用于类:
实例方法
单身方法
类方法
实例方法和类方法几乎与其他编程语言中的同义词类似 .
访问
Eigenclass
(包括单例方法)的另一种方法是使用以下语法(class <<
):现在你可以为
self
定义一个单例方法,它在这个上下文中是类Foo
本身:什么类<<东西做:
[it makes**
self == thing.singleton_class
**in the context of its block] .what.singleton_class是什么?
hi
对象从其#singleton_class.instance_methods
继承其#methods
,然后从其#class.instance_methods
继承 .这里我们给了
hi
的 singleton class 实例方法:a
. 它可以用 class << hi 代替 .hi
的#singleton_class
有所有实例方法hi
的#class
有,可能还有一些(这里是:a
) .[instance methods of thing's**
#class
and#singleton_class
**can be applied directly to thing. when ruby sees thing.a, it first looks for :a method definition in thing.singleton_class.instance_methods and then in thing.class.instance_methods]顺便说一下 - 他们调用对象的 singleton class == metaclass == eigenclass .
首先,
class << foo
语法打开foo
的单例类(eigenclass) . 这允许您专门化在该特定对象上调用的方法的行为 .现在,回答这个问题:
class << self
打开self
的单例类,以便可以为当前的self
对象重新定义方法(在类或模块体内部是类或模块本身) . 通常,这用于定义类/模块("static")方法:这也可以写成速记:
甚至更短:
在函数定义中,
self
指的是调用函数的对象 . 在这种情况下,class << self
打开该对象的单例类;一个用途就是实现穷人的状态机:因此,在上面的示例中,
StateMachineExample
的每个实例都有process_hook
别名为process_state_1
,但请注意后者如何将process_hook
(仅适用于self
,不影响其他StateMachineExample
实例)重新定义为process_state_2
. 因此,每次调用者调用process
方法(调用可重定义的process_hook
)时,行为都会根据其所处的状态而变化 .通常,实例方法是全局方法 . 这意味着它们可以在定义它们的类的所有实例中使用 . 相反,单个方法是在单个对象上实现的 .
Ruby在类中存储方法,所有方法都必须与类相关联 . 定义单例方法的对象不是类(它是类的实例) . 如果只有类可以存储方法,那么对象如何存储单例方法?创建单例方法时,Ruby会自动创建一个匿名类来存储该方法 . 这些匿名类称为元类,也称为单例类或特征类 . 单例方法与元类相关联,而元类又与定义单例方法的对象相关联 .
如果在单个对象中定义了多个单例方法,则它们都存储在同一个元类中 .
在上面的例子中,类<< z1将当前self改为指向z1对象的元类;然后,它定义了元类中的say_hello方法 .
类也是对象(称为Class的内置类的实例) . 类方法只不过是与类对象关联的单例方法 .
所有对象都可能有元类 . 这意味着类也可以有元类 . 在上面的例子中,类<< self修改self,因此它指向Zabuton类的元类 . 如果定义的方法没有显式接收器(将在其上定义方法的类/对象),则在当前作用域内隐式定义它,即self的当前值 . 因此,stuff方法是在Zabuton类的元类中定义的 . 上面的示例只是定义类方法的另一种方法 . 恕我直言,最好使用def self.my_new_clas_method语法来定义类方法,因为它使代码更容易理解 . 包含上面的例子,因此我们了解当我们遇到类<< self syntax时发生的事情 .
其他信息可在this post about Ruby Classes找到 .
实际上,如果为Ruby项目编写任何C扩展,实际上只有一种方法可以定义Module方法 .
我知道这种自我创业只会打开各种其他问题,所以你可以通过搜索每个部分来做得更好 .
对象首先 .
我可以为foo制作一个方法吗?
当然
我该怎么办?
只是另一个对象 .
你得到了所有Object方法加上你的新方法 .
只是foo对象 .
试着看看如果你从其他对象如类和模块中创建foo会发生什么 . 所有答案中的示例都很好用,但您必须使用不同的想法或概念才能真正理解代码编写方式的变化 . 所以现在你有很多术语要看 .
Singleton,Class,Module,self,Object和Eigenclass被提出来但Ruby并不像Metaclass那样 . 理查德或__why在这里向您展示了这个想法 . http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html如果打击你,那么尝试在搜索中查找Ruby对象模型 . 我在YouTube上看到的两个视频是Dave Thomas和Peter Cooper . 他们也试图解释这个概念 . 戴夫需要很长时间才能得到它,所以不要再努力了 . 为什么我会在这里呢?谢谢你的提问 . 另请查看标准库 . 它有一个Singleton模块就像一个FYI .
这很不错 . https://www.youtube.com/watch?v=i4uiyWA8eFk
А singleton method 是仅为单个对象定义的方法 .
例:
Singleton的SomeClass方法
test
Singleton的test_obj方法
test_2
test_3