类<< self在Ruby中做什么?
当前回答
首先,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 << self打开了self的单例类,这样就可以为当前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指向调用函数的对象。在这种情况下,类<< 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_state_1的process_hook,但注意在后者中,它可以将process_hook(仅用于自身,不影响其他StateMachineExample实例)重新定义为process_state_2。因此,每次调用者调用process方法(该方法调用可重定义的process_hook)时,行为都会根据它所处的状态而改变。
其他回答
首先,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 << self打开了self的单例类,这样就可以为当前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指向调用函数的对象。在这种情况下,类<< 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_state_1的process_hook,但注意在后者中,它可以将process_hook(仅用于自身,不影响其他StateMachineExample实例)重新定义为process_state_2。因此,每次调用者调用process方法(该方法调用可重定义的process_hook)时,行为都会根据它所处的状态而改变。
什么类<< thing做:
class Hi
self #=> Hi
class << self #same as 'class << Hi'
self #=> #<Class:Hi>
self == Hi.singleton_class #=> true
end
end
[它使自己==东西。]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继承它的#方法。然后从它的#class.instance_methods。 这里我们给出了hi的单例类实例方法:a。它可以用类<< hi来代替。 Hi 's #singleton_class拥有Hi 's #class拥有的所有实例方法,可能还有更多(:a here)。
[事物的#class和#singleton_class的实例方法可以直接应用于事物。]露比看到的时候。首先,它在thing.singleton_class中查找方法定义。Instance_methods然后在thing。class。Instance_methods中
顺便说一下,他们调用对象的singleton class == metaclass == eigenclass。
通常,实例方法是全局方法。这意味着它们在定义它们的类的所有实例中都可用。相反,单例方法是在单个对象上实现的。
Ruby stores methods in classes and all methods must be associated with a class. The object on which a singleton method is defined is not a class (it is an instance of a class). If only classes can store methods, how can an object store a singleton method? When a singleton method is created, Ruby automatically creates an anonymous class to store that method. These anonymous classes are called metaclasses, also known as singleton classes or eigenclasses. The singleton method is associated with the metaclass which, in turn, is associated with the object on which the singleton method was defined.
如果在单个对象中定义了多个单例方法,则它们都存储在同一个元类中。
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'…
在上面的例子中,类<< z1将当前self更改为指向z1对象的元类;然后,它在元类中定义say_hello方法。
类也是对象(称为class的内置类的实例)。类方法不过是与类对象相关联的单例方法。
class Zabuton
class << self
def stuff
puts "Stuffing zabuton…"
end
end
end
All objects may have metaclasses. That means classes can also have metaclasses. In the above example, class << self modifies self so it points to the metaclass of the Zabuton class. When a method is defined without an explicit receiver (the class/object on which the method will be defined), it is implicitly defined within the current scope, that is, the current value of self. Hence, the stuff method is defined within the metaclass of the Zabuton class. The above example is just another way to define a class method. IMHO, it's better to use the def self.my_new_clas_method syntax to define class methods, as it makes the code easier to understand. The above example was included so we understand what's happening when we come across the class << self syntax.
更多关于Ruby类的信息可以在这篇文章中找到。
我发现了一个超级简单的解释类<< self,本征类和不同类型的方法。
在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
另一种访问本征类(包括单例方法)的方法是使用以下语法(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
А singleton方法是仅为单个对象定义的方法。
例子:
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
SomeClass的单例方法
test
test_obj的单例方法
test_2
test_3
推荐文章
- 我如何在Ruby中解析YAML文件?
- Rails中的OO设计:在哪里放置东西
- 给定一个类,查看实例是否有方法(Ruby)
- 在日历应用程序中建模重复事件的最佳方法是什么?
- 如何创建一个私有类方法?
- 无法安装pg gem
- 双* (splat)操作符做什么
- 如何使用Ruby on Rails进行HTTP请求?
- 如何从rake任务中提前返回?
- 什么&。(&点)在Ruby中是什么意思?
- 是什么阻碍了Ruby和Python获得V8的Javascript速度?
- 运行pod设置给我“坏的解释器:没有这样的文件或目录”错误
- 在Ubuntu上安装sqlite3-ruby错误
- Ruby有什么Python没有的,反之亦然?
- find_spec_for_exe':无法找到gem bundle (>= 0.a) (gem::GemNotFoundException)