In my recent project, I need, that a class knows about their instances.
So after
class MyClass
…
end
a,b=MyClass.new,Myclass.new
I except MyClass.instances to give me an array [a,b]
Or I would be happy, if I can do
MyClass.each{|a| … }
I can do it in one class, BUT, I need it as a module, because I cannot
subclass my class from that class?
BTW Is the latter solution “cheaper” (memory, execution time…)
And, another question, which is more general:
Has ruby a set type?
Implementing them with an array is not appropiate, because lookup is
slow in an array. And, I’m confused about the set methods in the array
classes. When I need sets, I always use hashes with dummy values, but I
think a separate class would be nice.
I ran into a similar problem using Madeleine. In Madeleine, you need to
have the objects referenced all the time, so ObjectSpace won’t work.
My 5 minute solution (a bit of a hack) required class methods, which are not inherited when you include a module into a class, so I don’t think it
would work in your case. Here it is, anyway. Anyone have any more elegant
ideas?
class Parent
def self.create (*params)
obj = new :afdifw489r3k4jge98 # Just bang on the keyboard.
# Set constant in child class.
if const_get(:INSTANCES).nil?
const_set(:INSTANCES,[])
end
const_get(:INSTANCES) << obj
obj.init (*params)
end
def initialize fromCreateKey
raise 'Illegal object creation.' if fromCreateKey !=
:afdifw489r3k4jge98
end
end
class Child < Parent
def init foo, bar, whatever
# Initialization code moved to here.
# Don’t override `initialize’.
end
end
Good. And YAQ (Yet Another Question): how can I find documentation about
1.8 features? Ok, I can peek into the code, but I hope something more
appropiate…
My 5 minute solution (a bit of a hack) required class methods, which are
*not* inherited when you include a module into a class, so I don't think it
would work in your case.
extend Module
a stupid example with 1.8
pigeon% cat b.rb
#!/usr/bin/ruby
module Viv
def create(*args, &block)
obj = allocate
if ! const_defined?(:INSTANCES)
const_set(:INSTANCES,)
end
const_get(:INSTANCES) << obj
obj.init (*args, &block)
obj
end
def self.extend_object(a)
a.instance_eval {define_method(:initialize) { raise "error"}}
super
end
end
FWIW, I believe the normal way of doing this is simply to make ‘new’
private (unless I’m missing some reason why this can’t be done) - or in this
case protected because there are multiple classes involved:
class Parent
class <<self
protected :new
end
def self.create(*params)
obj = self.new(*params)
# Set constant in child class.
begin
const_get(:INSTANCES) << obj
rescue NameError
const_set(:INSTANCES,[obj])
end
end
end
class Child < Parent
def initialize(foo=“foo”) @foo = foo
end
end
Child.create
Child.create(“bar”)
p Child::INSTANCES
But it should be possible to refactor this as a module which you include
into a class to keep track of instances. For example, stealing shamelessly
from singleton.rb:
module Tracker
def Tracker.append_features(klass)
klass.private_class_method(:new) @instances = nil
klass.instance_eval %{
@instances =
def instances
@instances
end
def create(*params)
obj = new(*params)
@instances << obj
obj
end
}
end
end
class Thingy
include Tracker
def initialize(foo=“foo”) @foo = foo
end
end
Thingy.create
Thingy.create(“bar”)
p Thingy.instances
Regards,
Brian.
···
On Mon, Apr 14, 2003 at 10:44:57PM +0900, Chris Pine wrote:
def initialize fromCreateKey
raise 'Illegal object creation.' if fromCreateKey !=
I ran into a similar problem using Madeleine. In Madeleine, you need to
have the objects referenced all the time, so ObjectSpace won’t work.
My 5 minute solution (a bit of a hack) required class methods, which are not inherited when you include a module into a class, so I don’t think it
would work in your case. Here it is, anyway. Anyone have any more elegant
ideas?
class Parent
def self.create (*params)
obj = new :afdifw489r3k4jge98 # Just bang on the keyboard.
# Set constant in child class.
if const_get(:INSTANCES).nil?
const_set(:INSTANCES,[])
end
const_get(:INSTANCES) << obj
obj.init (*params)
end
def initialize fromCreateKey
raise 'Illegal object creation.' if fromCreateKey !=
:afdifw489r3k4jge98
end
end
class Child < Parent
def init foo, bar, whatever
# Initialization code moved to here.
# Don’t override `initialize’.
end
end
Good. And YAQ (Yet Another Question): how can I find documentation about
1.8 features? Ok, I can peek into the code, but I hope something more
appropiate...