Ruby中的自我成语
class << self
在Ruby中做了什么?
首先, class << foo
语法打开foo
的单例类(本征类)。 这使您可以专门化在该特定对象上调用的方法的行为。
a = 'foo' class << a def inspect '"bar"' end end a.inspect # => "bar" a = 'foo' # new object, new singleton class a.inspect # => "foo"
现在,为了回答这个问题: class << self
打开了self
的singleton类,这样就可以重新定义当前self
对象(类或模块内部是类或模块本身 )的方法。 通常,这用于定义类/模块(“静态”)方法:
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
因此,在上面的例子中, StateMachineExample
每个实例的process_hook
别名为process_state_1
,但是请注意,在后者中,它可以重新定义process_hook
(仅用于self
,不会影响其他StateMachineExample
实例) process_state_2
。 因此,每次调用者调用process
方法(调用可重定义的process_hook
)时,行为都会根据它所处的状态而改变。
在这个博客中 ,我发现了一个关于class << self
,本Eigenclass
class << self
和不同types的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
什么课“的东西:
class Hi self #=> Hi class << self #same as 'class << Hi' self #=> #<Class:Hi> self == Hi.singleton_class #=> true end end
[它 在块的上下文 self == thing.singleton_class
] 。
什么是thing.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
inheritance#methods
,然后从#class.instance_methods
。
在这里,我们给你hi
的单例类实例方法:a
。 可以用类<< hi来完成。
hi
的#singleton_class
有所有的实例方法hi
的#class
有,可能还有一些( :a
在这里)。
[事物的 #class
和 #singleton_class
实例方法 可以直接应用于事物。 当ruby看到thing.a时,它首先查找:thing.singleton_class.instance_methods中的方法定义,然后是thing.class.instance_methods中的方法定义]
顺便说一句 – 他们调用对象的单例类 == metaclass == eigenclass 。
通常,实例方法是全局方法。 这意味着它们在所有定义它们的类中都是可用的。 相比之下,单一的方法是在一个对象上实现的。
Ruby将方法存储在类中,并且所有方法都必须与类相关联。 单体方法定义的对象不是一个类(它是一个类的实例)。 如果只有类可以存储方法,一个对象如何存储一个单例方法? 当创build单例方法时,Ruby会自动创build一个匿名类来存储该方法。 这些匿名类被称为元类,也称为单例类或特征类。 单例方法与元类关联,后者又与定义单例方法的对象相关联。
如果在单个对象中定义了多个单例方法,则它们都存储在同一个元类中。
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 << z1改变了当前的self指向z1对象的元类; 然后,它定义了元类中的say_hello方法。
类也是对象(称为Class的内置类的实例)。 类方法只不过是与类对象相关的单例方法。
class Zabuton class << self def stuff puts "Stuffing zabuton…" end end end
所有对象都可能有元类。 这意味着类也可以有元类。 在上面的例子中,类<< self自我修改自己,所以它指向Zabuton类的元类。 当一个方法被定义为没有明确的接收者(方法将被定义的类/对象)时,它在当前范围内隐式定义,即self的当前值。 因此,stuff方法在Zabuton类的元类中定义。 上面的例子是定义类方法的另一种方法。 恕我直言,最好使用def self.my_new_clas_method语法来定义类方法,因为它使代码更容易理解。 上面的例子包含在内,所以我们理解当我们遇到类“自我”的语法时会发生什么。
其他信息可以在这篇文章中find关于Ruby类 。
单态方法是一种仅为单个对象定义的方法。
例:
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
Singleton的SomeClass的方法
testing
Singleton的test_obj方法
test_2
test_3
事实上,如果你为Ruby项目编写C扩展,实际上只有一种方法来定义一个Module方法。
rb_define_singleton_method
我知道这个自营业务只是开辟了各种其他问题,所以你可以通过search每一个部分做得更好。
对象第一。
foo = Object.new
我可以为foo做一个方法吗?
当然
def foo.hello 'hello' end
我该怎么办?
foo.hello ==>"hello"
只是另一个对象。
foo.methods
你得到所有的对象方法加上你的新的。
def foo.self self end foo.self
只是foo对象。
试着看看会发生什么,如果你从类和模块等其他对象foo。 所有答案的例子都很好玩,但你必须用不同的想法或概念来真正理解代码的写法。 所以现在你有很多条件去看看。
Singleton,Class,Module,self,Object和Eigenclass被提出来,但是Ruby并没有这样命名对象模型。 这更像Metaclass。 Richard或__why在这里向你展示了这个想法。 http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html如果打击你,然后尝试在search中查找Ruby对象模型。; 我知道YouTube上的两个video是Dave Thomas和Peter Cooper。 他们也试图解释这个概念。 戴夫花了很长时间才得到它,所以不用担心。 我仍然在努力。 为什么我会在这里? 感谢您的问题。 也看看标准库。 它有一个单一的模块,只是一个供参考。