[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

instance counter

Pierre Lebrun

10/17/2008 3:37:00 AM

Please forgive the trite nature of this question, I'm new to ruby and OO
programming in general. I'm looking to create a counter that keeps track
of the number of instances created from one class (++ would we access
this from the class or the instace?).

I've made a few lame attempts myself so far but nothing functional :-P

Also, why does ruby return an error for:

Class Bob
attr_reader :count
@count = 0
def initialize
@count += 1
end
end

Cheers!
--
Posted via http://www.ruby-....

20 Answers

Owein Herrmann

10/17/2008 3:49:00 AM

0

Pierre Lebrun wrote:
> Also, why does ruby return an error for:
> Class Bob

keyword 'class' must be lowercase, not capitalized.

also, @count is an instance variable. In order to get a variable for
which only one copy exists for the class, use @@count

class Bob
@@count=0
def initialize
@@count+=1
end
def Bob.count
@@count
end
end

a = Bob.new
b = Bob.new
puts Bob.count
#=> 2
~Owein
--
Posted via http://www.ruby-....

Tommy Nordgren

10/17/2008 3:49:00 AM

0


On Oct 17, 2008, at 5:36 AM, Pierre Lebrun wrote:

> Please forgive the trite nature of this question, I'm new to ruby
> and OO
> programming in general. I'm looking to create a counter that keeps
> track
> of the number of instances created from one class (++ would we access
> this from the class or the instace?).
>
> I've made a few lame attempts myself so far but nothing functional :-P
>
> Also, why does ruby return an error for:
>
> Class Bob
> attr_reader :count
> @count = 0
> def initialize
> @count += 1
> end
> end
>
> Cheers!
> --
> Posted via http://www.ruby-....
>
You need to write @@count = 0.
and
def Bob.count
return @@count
end
------
What is a woman that you forsake her, and the hearth fire and the home
acre,
to go with the old grey Widow Maker. --Kipling, harp song of the Dane
women
Tommy Nordgren
tommy.nordgren@comhem.se




Pierre Lebrun

10/17/2008 4:11:00 AM

0

Excellent, thanks for the classy help!
--
Posted via http://www.ruby-....

Mike Gold

10/17/2008 5:19:00 AM

0

Tommy Nordgren wrote:
> def Bob.count
> return @@count
> end

I avoid @@. Why should metaclasses have a different syntax? @@ also
has different scoping rules which I find vexing. Be consistent, I say.

class Bob
@count = 0

class << self
attr_reader :count
end

def initialize
Bob.instance_eval { @count += 1 }
end
end

a = Bob.new
b = Bob.new
puts Bob.count # => 2

And in general,

def new_instance_counted_class
Class.new {
count = 0

(class << self ; self ; end).instance_eval {
define_method(:count) {
count
}
}

define_method(:initialize) {
count += 1
}
}
end

class Bob < new_instance_counted_class
# ...
end

a = Bob.new
b = Bob.new
puts Bob.count # => 2

To those who were asking about Class.new{} from one of my previous
posts, here is a good example.

The local variable "count" lives in the closure, and is private in the
ultimate sense. There are no scoping rules to worry about, no efforts
are needed to choose a @hopefully_unused_variable_name, no surprising
subclass behavior, and no possibility that an instance_eval can rape the
count.

Try writing the above using the conventional Java-like "blub"
constructs. You'll have some or all the problems I just mentioned.
--
Posted via http://www.ruby-....

Tommy Nordgren

10/17/2008 7:42:00 AM

0

[Note: parts of this message were removed to make it a legal post.]


On Oct 17, 2008, at 7:19 AM, Mike Gold wrote:

> Tommy Nordgren wrote:
>> def Bob.count
>> return @@count
>> end
>
> I avoid @@. Why should metaclasses have a different syntax? @@ also
> has different scoping rules which I find vexing. Be consistent, I
> say.
>
An instance counter have to be assosiated with the class itself, and
not
an instance. How else can it count the total number of allocated
instances?
You plainly did not read the original posters message.
> ------------------------------------------------------

"Home is not where you are born, but where your heart finds peace" -
Tommy Nordgren, "The dying old crone"
tommy.nordgren@comhem.se



Jesús Gabriel y Galán

10/17/2008 8:21:00 AM

0

On Fri, Oct 17, 2008 at 9:41 AM, Tommy Nordgren
<tommy.nordgren@comhem.se> wrote:
>
> On Oct 17, 2008, at 7:19 AM, Mike Gold wrote:
>
>> Tommy Nordgren wrote:
>>>
>>> def Bob.count
>>> return @@count
>>> end
>>
>> I avoid @@. Why should metaclasses have a different syntax? @@ also
>> has different scoping rules which I find vexing. Be consistent, I say.
>>
> An instance counter have to be assosiated with the class itself, and
> not
> an instance. How else can it count the total number of allocated instances?
> You plainly did not read the original posters message.

A Class is also an object that can have its own instance variables,
which are different
from the instance variables of instances of that class. People usually
discourage the
use of class variables (@@x) because they have "weird" semantics when it comes
to inheritance, and using class instance variables is usually better
and covers most
cases:

irb(main):001:0> class B
irb(main):002:1> @count = 0
irb(main):003:1> class << self
irb(main):004:2> attr_accessor :count
irb(main):005:2> end
irb(main):006:1> attr_accessor :count
irb(main):007:1> def initialize
irb(main):008:2> B.count += 1
irb(main):009:2> end
irb(main):010:1> end
=> nil
irb(main):011:0>
irb(main):012:0*
irb(main):013:0* B.count
=> 0
irb(main):014:0> b = B.new
=> #<B:0xb7b77188>
irb(main):015:0> B.count
=> 1
irb(main):016:0> b.count
=> nil
irb(main):017:0> b.count = 55
=> 55
irb(main):018:0> b.count
=> 55
irb(main):019:0> B.count
=> 1

So, B.count and b.count are different things. B.count accesses an
instance variable of B, while b.count accesses instance variables of B
instances.

Jesus.

Robert Klemme

10/17/2008 9:28:00 AM

0

On 17.10.2008 07:19, Mike Gold wrote:
> Tommy Nordgren wrote:
>> def Bob.count
>> return @@count
>> end
>
> I avoid @@. Why should metaclasses have a different syntax? @@ also
> has different scoping rules which I find vexing. Be consistent, I say.
>
> class Bob
> @count = 0
>
> class << self
> attr_reader :count
> end
>
> def initialize
> Bob.instance_eval { @count += 1 }
> end
> end
>
> a = Bob.new
> b = Bob.new
> puts Bob.count # => 2
>
> And in general,
>
> def new_instance_counted_class
> Class.new {
> count = 0
>
> (class << self ; self ; end).instance_eval {
> define_method(:count) {
> count
> }
> }
>
> define_method(:initialize) {
> count += 1
> }
> }
> end
>
> class Bob < new_instance_counted_class
> # ...
> end
>
> a = Bob.new
> b = Bob.new
> puts Bob.count # => 2
>
> To those who were asking about Class.new{} from one of my previous
> posts, here is a good example.
>
> The local variable "count" lives in the closure, and is private in the
> ultimate sense. There are no scoping rules to worry about, no efforts
> are needed to choose a @hopefully_unused_variable_name, no surprising
> subclass behavior, and no possibility that an instance_eval can rape the
> count.
>
> Try writing the above using the conventional Java-like "blub"
> constructs. You'll have some or all the problems I just mentioned.

I nevertheless believe there is a more Rubyish solution to achieve what
you did above with new_instance_counted_class:

module InstanceCounted
module InstanceCounter
attr_accessor :count
end

def initialize(*a,&b)
super
self.class.count += 1
end

def self.included(cl)
cl.extend InstanceCounter
cl.count = 0
end
end

class Foo
include InstanceCounted
end

Note though that this approach (as yours above) has some shortcomings:
the count is not adjusted when objects are garbage collected. And you
must invoke super if you define Foo#initialize (a good habit anyway) -
in your case you need to alias the old initialize and call that if you
redefine it.

There is another option though: you can get the current count via
ObjectSpace:

count = 0
ObjectSpace.each_object(Foo) { c += 1 }

Kind regards

robert

Sebastian Hungerecker

10/17/2008 12:59:00 PM

0

Tommy Nordgren wrote:
> > I avoid @@. =A0Why should metaclasses have a different syntax? =A0@@ al=
so
> > has different scoping rules which I find vexing. =A0Be consistent, I =A0
> > say.
>
> =A0=A0=A0=A0=A0=A0=A0=A0An instance counter have to be assosiated with th=
e class itself,
> and =A0 not
> an instance. How else can it count the total number of allocated =A0
> instances?
> You plainly did not read the original posters message.

It seems to me that he did read the OP, but you did not fully read his=20
message. His code defines an instance variable on the class, so it *is*=20
associated with the class and not with any particular instance of that
class.

HTH,
Sebastian
=2D-=20
Jabber: sepp2k@jabber.org
ICQ: 205544826

Mike Gold

10/19/2008 7:45:00 PM

0

Robert Klemme wrote:
>> Try writing the above using the conventional Java-like "blub"
>> constructs. You'll have some or all the problems I just mentioned.
>
> I nevertheless believe there is a more Rubyish solution to achieve what
> you did above with new_instance_counted_class:
>
> module InstanceCounted
> module InstanceCounter
> attr_accessor :count
> end
>
> def initialize(*a,&b)
> super
> self.class.count += 1
> end
>
> def self.included(cl)
> cl.extend InstanceCounter
> cl.count = 0
> end
> end
>
> class Foo
> include InstanceCounted
> end

I said that one would have some or all the problems I mentioned, not
that it couldn't be done. Indeed since you've made an attr_accessor,
anyone is free to modify count. Had you used attr_reader instead,
anyone could still modify it with instance_eval (as in my first
example). Of more importance is the looming conflict with @count.

I've spent too much time tracking down the bewildering bugs caused by
naming conflicts. No doubt others will think, "Oh, it's so unlikely,
don't bother." I used to believe that too. Now I am more careful. I
remove all these problems with one fell swoop.
--
Posted via http://www.ruby-....

Marc Heiler

10/19/2008 8:25:00 PM

0

> I've spent too much time tracking down the bewildering bugs caused by
> naming conflicts.

I once had a bug caused by my misuse of @@ when there was no need for
it.

Since then I have become more sceptical - i like every feature I can
use, but when I can achieve something without using something, i.e. @@
all the better for my poor little brain. I would even go as far as to
claim in 95% of the cases, there is no real need to use @@ at all.
--
Posted via http://www.ruby-....