Module that keeps track of instance count?

  • Thread starter francisrammeloo
  • Start date
F

francisrammeloo

Hi,

I need some of my classes to keep track of their number of instances.
To avoid duplication I thought it was a good idea to put this
functionality in a separate module:

module InstanceCounter
def initialize(*args)
super
@count = 0
end

def increase_count()
@count += 1
return @count - 1
end

end

class Widget

def initalize(name)
@name = name
end

end

class Caption < Widget

include InstanceCounter

def initialize()
super("Widget_Nr" + increase_count().to_s)
end

end

The problem seems to be that I need the functionality of
InstanceCounter when is has not you been initialized. Does anybody see
some light here? Perhaps a different approach will do?


Best regards,
Francis
 
A

Austin Ziegler

I need some of my classes to keep track of their number of
instances. To avoid duplication I thought it was a good idea to
put this functionality in a separate module:
module InstanceCounter
def initialize(*args)
super
@count =3D 0
end
=20
def increase_count()
@count +=3D 1
return @count - 1
end
end

I think you want, instead:

module InstanceCounter
def increase_count
@@count ||=3D 0
@@count +=3D 1
(@@count - 1)
end
end

Note that this isn't thread-safe. It also won't help in cases where
you subclass your class that includes InstanceCounter. What you'd
probably want is something that deals with a class-instance variable
rather than a class variable, and that would be able to be dealt
with using #append_features (I think). Additionally, under the
current scheme, #increase_count is a public method that anyone can
call on an instance.

There are examples of how to get create this count safely somewhere,
I just can't recall where offhand. ;)

The main trick you're after, though, is @@count ||=3D 0.

-austin
--=20
Austin Ziegler * (e-mail address removed)
* Alternate: (e-mail address removed)
 
S

Szymon Rozga

I don't know how this conforms to Ruby programming style, but you can
extend the singleton design pattern and have a class method that
controls the initialization of Caption.

class Widget
attr_reader :name

def initialize(name)
@name = name
end
end

class Caption < Widget
def Caption.get_new_instance
@@count ||= 0
@@count += 1
return Caption.new
end

private

def initialize
super("Widget_Nr" + (@@count-1).to_s)
end
end

a = Array.new
(1..10).to_a.each do |i|
a << Caption.get_new_instance
end

a.each do |e|
puts e.name
end

output:
Widget_Nr0
Widget_Nr1
Widget_Nr2
Widget_Nr3
Widget_Nr4
Widget_Nr5
Widget_Nr6
Widget_Nr7
Widget_Nr8
Widget_Nr9

The private initialize method makes sure that no one ever calls
Caption.new explicitly and you can only get new instances of Caption by
calling the get_new_instance class method.
 
D

Dave Burt

Hi,

I need some of my classes to keep track of their number of instances.
To avoid duplication I thought it was a good idea to put this
functionality in a separate module:
<snip counting code>

Here's a different way to do it:

module InstanceCounter
def instance_count(include_subclasses = true)
count = 0
GC.start # <- this line is optional
ObjectSpace.each_object do |obj|
count += 1 if obj.class == self || include_subclasses &&
obj.kind_of?(self)
end
count
end
end

class Foo
extend InstanceCounter
end

class Bar < Foo
end

Foo.instance_count #=> 0
Bar.instance_count #=> 0
a = [Foo.new, Bar.new, Bar.new]
Foo.instance_count #=> 3
Foo.instance_count(false) #=> 1
Bar.instance_count #=> 2

Cheers,
Dave
 
F

francisrammeloo

This works for me:

module InstanceCounter

def increase_count( type_name )
@@instance_counter ||= Hash.new
@@instance_counter[type_name] ||= 0
@@instance_counter[type_name] += 1
return @@instance_counter[type_name] - 1
end

end
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top