From: "Mauricio Fernández" Date: 2003-02-23T17:16:24+09:00 Subject: Re: Style question: using 'block_given?' On Sun, Feb 23, 2003 at 08:46:22AM +0900, Phil Tomson wrote: > >It's probably most useful in an accessor. For example, if you want to > >keep a running tally of how many instances of a class have been > >created: > > > > class C > > class << self; protected; attr_accessor :instances; end > > @instances = 0 > > > > def initialize > > self.class.instances += 1 > > end > > end > > > > p C.instances # 0 > > C.new > > C.new > > p C.instances # 2 > > Why wouldn't I just use a class variable to do this (which is how I > usually do it when I need to keep track of how many instances have been > created): > > class C > @@instances = 0 > def initialize > @@instances += 1 > end > def C.number_of_instances > @@instances > end > end > > C.new > C.new > p C.number_of_instances #2 You're right on the distinction instances of this class (class instance variables) vs. instances of this and all derived (class variables). I'd however rather do batsman@tux-chan:/tmp$ expand -t 2 i.rb module CountInstances def new(*args, &p) @instances ||= 0 @instances += 1 super(*args, &p) end def instances @instances ||= 0 end end module CountHierarchyInstances def new(*args, &p) increment_count super(*args, &p) end def increment_count @instances ||= 0 @instances += 1 superclass.increment_count if superclass.kind_of? CountHierarchyInstances end def instances @instances ||= 0 end protected :increment_count end class A extend CountInstances def initialize puts "Creating instance of #{self.class}" end end class B < A # can have that functionality by subclassing A or using #extend CountInstances end puts "Made #{A.instances} instances of A." puts "Made #{B.instances} instances of B." 2.times { A.new; B.new } 1.times { B.new } puts "Made #{A.instances} instances of A." puts "Made #{B.instances} instances of B." class A2 extend CountHierarchyInstances def initialize puts "Creating instance of #{self.class}" end end class B2 < A2 end puts "Made #{A2.instances} instances of A2." puts "Made #{B2.instances} instances of B2." 2.times { A2.new; B2.new } 1.times { B2.new } puts "Made #{A2.instances} instances of A2 or derived classes." puts "Made #{B2.instances} instances of B2 or derived classes." batsman@tux-chan:/tmp$ ruby i.rb Made 0 instances of A. Made 0 instances of B. Creating instance of A Creating instance of B Creating instance of A Creating instance of B Creating instance of B Made 2 instances of A. Made 3 instances of B. Made 0 instances of A2. Made 0 instances of B2. Creating instance of A2 Creating instance of B2 Creating instance of A2 Creating instance of B2 Creating instance of B2 Made 5 instances of A2 or derived classes. Made 3 instances of B2 or derived classes. ...as this way you don't have to keep using super all the time. Moreover CountHierarchyInstances implements yet another valid semantic for instance counting. -- _ _ | |__ __ _| |_ ___ _ __ ___ __ _ _ __ | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ | |_) | (_| | |_\__ \ | | | | | (_| | | | | |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_| Running Debian GNU/Linux Sid (unstable) batsman dot geo at yahoo dot com There are 3 kinds of people: those who can count & those who can't. -- Unknown source