首先,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
对象(在类或模块主体中是类或模块itself)重新定义方法.通常,这用于定义类/模块("静态")方法:
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
)时,行为都会根据其所处的状态而变化.