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
的单例类,以便可以为当前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
和不同类型的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
继承#methods
,然后从#class.instance_methods
。
在这里,我们给你hi
的单例类实例方法:a
。 它可以用class << hi来完成。
hi
的#singleton_class
拥有所有实例方法hi
的#class
了,可能还有一些更( :a
在这里)。
[事物的 #class
和 #singleton_class
实例方法 可以直接应用于事物。 当ruby看到thing.a时,它首先查找:thing.singleton_class.instance_methods中的方法定义,然后是thing.class.instance_methods中的方法定义]
顺便说一句 - 他们调用object的单例类 == metaclass == eigenclass 。
链接地址: http://www.djcxy.com/p/4359.html