我正在尝试跟踪super中数组中所有实例化的子类对象,以便我可以从super调用一个方法来迭代它们。我想我差不多了,但我无法弄清楚我错过了什么。目前,当我调用super.my_array时,它只返回一个空数组,因此我的initialize方法必定存在问题。这是我到目前为止的抽象版本:
class Klass
attr_reader :my_array
@@my_array = []
def initialize
@@my_array << self if super.class == Klass
end
def self.iterate_over_sub
@@my_array.each { |x| x.sub_method }
end
def sub_method
puts "#{self.class} is being called by super"
end
end
答案 0 :(得分:2)
我将为你的问题提供另一种答案......
老实说,我可能会稍微改变你的方法并创建一个单独的类(包括Singleton模块),你的Klass会注册它,例如。
class Klass
def initialize
KlassTracker.instance.track(self)
end
end
require 'singleton'
class KlassTracker
include Singleton
def initialize
@instances = []
end
def track(instance)
@instances << []
end
end
此外,这本质上就像疯了一样泄漏内存,所以我建议使用WeakRef或像ref这样的库存储弱/软引用(我没有用过)或者之前看过,但看起来像你想要的那样)并且只跟踪KlassTracker类中的弱/软引用。
最后,如果我没有提到你要求做的事情,坦率地说,有点疯狂,那将是我的疏忽。我不知道你要做什么,但可能有更好的方法。
答案 1 :(得分:1)
不确定您要实现的目标,但我发现了一些潜在的问题。
attr_reader在实例级别定义了一个访问器,因此它与类变量无关。基本上当你说attr_reader :my_array
时,它定义了一个像这样的方法
def my_array
@my_array
end
其次你会更好地检查这样的类型:
@@my_array << self if self.is_a?(Klass)
如果我理解正确的话,这是一个做你需要的例子。
class Klass
@@my_array = []
def self.my_array
@@my_array
end
def initialize
@@my_array << self if self.is_a?(Klass)
end
def self.iterate_over_sub
@@my_array.each { |x| x.sub_method }
end
def sub_method
puts "#{self.class} is being called by super"
end
end
class SubKlass < Klass
end
sk = SubKlass.new
#<SubKlass:0x007f8ecb861eb8>
Klass.my_array
#[#<SubKlass:0x007f8ecb861eb8>]
答案 2 :(得分:0)
要迭代特定类的实例,可以使用ObjectSpace::each_object
:
class Foo; end
class Bar < Foo; end
class Baz < Foo; end
Foo.new
Bar.new
Baz.new
ObjectSpace.each_object(Foo) { |x| p x }
<强>输出:强>
#<Baz:0x007fc213859710>
#<Bar:0x007fc213859738>
#<Foo:0x007fc213859760>
或作为班级方法:
class Foo
def self.each_instance(&block)
ObjectSpace.each_object(self, &block)
end
end
Foo.each_instance { |x| p x }
答案 3 :(得分:0)
这会满足您的需求吗?
class A
@@instances = []
def self.new
a = super
@@instances << a
a
end
def self.tryit
@@instances.each {|e| e.test}
end
end
class B < A
def test
puts "hi"
end
end
b = B.new
c = B.new
b.test # => 'hi'
A.tryit # => 'hi\nhi'