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中,有三种可以应用于类的方法:

  1. 实例方法
  2. 单例方法
  3. 类方法

实例方法和类方法与其他编程语言中的同名方法几乎相似。

 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_methodsinheritance#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。 他们也试图解释这个概念。 戴夫花了很长时间才得到它,所以不用担心。 我仍然在努力。 为什么我会在这里? 感谢您的问题。 也看看标准库。 它有一个单一的模块,只是一个供参考。

这很好。 https://www.youtube.com/watch?v=i4uiyWA8eFk

Interesting Posts