执行一些对象的一些实例的代码块:
如果我很好理解,用方法
operational
如果您想在 Criature 等某些类的主体中执行,您想标记它们的实例,并说“嘿,在执行 operation 时给我一个电话。”
来自The Pickaxe:
ObjectSpace.each_object(‹ class_or_mod›)
为这个 Ruby 进程中的每个活的、非立即的对象调用一次块。如果指定了 class_or_mod,则只为与 class_or_mod 匹配(或者是其子类)的类或模块调用块。
使用ObjectSpace 可以迭代某个类的对象。这给了我一个想法,签名,你想给某些实例的这个标志,可以用一个超类来完成。
ObjectSpace.each_object(Operational)
将收集具有此“签名”的类的所有实例。
文件tc.rb:
class Operational
end
class Criature < Operational
def initialize(p_name)
@name = p_name
@level = 0
end
def level_up
@level+=1
puts "level is now #{@level}"
end
end
class XYZ < Operational
def initialize(p_name)
@name = p_name
end
end
文件to.rb:
require_relative 'tc'
class Operator
def operation(&block)
#execution of a block in some object
Special.currently_operational.each do | obj |
puts "operation on #{obj.inspect}"
block.call(obj) if obj.respond_to? 'level_up'
end
end
end
class Special
def self.currently_operational
operationals = []
ObjectSpace.each_object(Operational) do | object |
operationals << object
end
puts "#{operationals.size} objects are flagged as operational"
operationals
end
end
Criature.new('c1')
Criature.new('c2')
Criature.new('c3')
block = Proc.new{ | x | x.level_up }
puts 'first round'
Operator.new.operation(&block)
# later ...
XYZ.new('x1')
XYZ.new('x2')
puts 'second round'
Operator.new.operation(&block)
执行:
$ ruby -w to.rb
first round
3 objects are flagged as operational
operation on #<Criature:0x007fc45683d2f0 @name="c3", @level=0>
level is now 1
operation on #<Criature:0x007fc45683d368 @name="c2", @level=0>
level is now 1
operation on #<Criature:0x007fc45683d3b8 @name="c1", @level=0>
level is now 1
second round
5 objects are flagged as operational
operation on #<XYZ:0x007fc45683cad0 @name="x2">
operation on #<XYZ:0x007fc45683cb48 @name="x1">
operation on #<Criature:0x007fc45683d2f0 @name="c3", @level=1>
level is now 2
operation on #<Criature:0x007fc45683d368 @name="c2", @level=1>
level is now 2
operation on #<Criature:0x007fc45683d3b8 @name="c1", @level=1>
level is now 2