[Q] A class, that knows about it's instances + Sets

Hi!

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.

···


±[ Kontra, Gergelykgergely@mcl.hu PhD student Room IB113 ]---------+

http://www.mcl.hu/~kgergely “Olyan langesz vagyok, hogy |
Mobil:(+36 20) 356 9656 ICQ: 175564914 poroltoval kellene jarnom” |
±–Magyar php mirror es magyar php dokumentacio: http://hu.php.net---+

I except MyClass.instances to give me an array [a,b]
Or I would be happy, if I can do
MyClass.each{|a| ... }

Look at ObjectSpace::each_object

Has ruby a set type?

1.8 has a library set.rb

Guy Decoux

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

Chris

module Instance_Iterator
include Enumerable
def each(&block)
ObjectSpace.each_object(self, &block)
end
end

MyClass.extend(Instance_Iterator)

···

On Mon, 14 Apr 2003, KONTRA Gergely wrote:

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?

Thanx for the quick answers!

1.8 has a library set.rb

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…

Gergo

···


±[ Kontra, Gergelykgergely@mcl.hu PhD student Room IB113 ]---------+

http://www.mcl.hu/~kgergely “Olyan langesz vagyok, hogy |
Mobil:(+36 20) 356 9656 ICQ: 175564914 poroltoval kellene jarnom” |
±–Magyar php mirror es magyar php dokumentacio: http://hu.php.net---+

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

class A
   extend Viv
   def init(a)
      @a = a
   end
end

A.new rescue p $!
p A.create(12)

pigeon%

pigeon% ruby b.rb
#<RuntimeError: error>
#<A:0x401ab678 @a=12>
pigeon%

Guy Decoux

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 !=

:afdifw489r3k4jge98

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.

why not self.class.id?

···

Chris Pine (nemo@hellotree.com) wrote:

  #  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

Chris


Eric Hodel - drbrain@segment7.net - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

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...

See http://raa.ruby-lang.org/list.rhtml?name=shim-ruby16_18

Guy Decoux

To learn more about Set:

http://www.rubygarden.org/ruby?ProgrammingRubyTwo/Set

Chris

Oops, spurious line, ignore that one.

···

On Mon, Apr 14, 2003 at 03:22:48PM +0100, Brian Candler wrote:

  @instances = nil