# Instance and Related Class Methods

**URL:** <https://www.ruby-forum.com/t/instance-and-related-class-methods/65043>\
**Category:** Ruby\
**Created:** [August 15, 2006, 8:21pm UTC](https://www.ruby-forum.com/t/instance-and-related-class-methods/65043 "2006-08-15T20:21:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mgreenly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85f322/32.png) [@mgreenly](https://www.ruby-forum.com/u/mgreenly)\
**Post date:** [August 15, 2006, 8:21pm UTC](https://www.ruby-forum.com/t/instance-and-related-class-methods/65043/1 "2006-08-15T20:21:20Z")

</div>

I have a class with a lot of instance methods which are related to  
class methods from within the same class.

Example:

class A  
def initialize(start\_date, end\_date)  
@start\_date, @end\_date = start\_date, end\_date  
end

def total\_hours  
A.total\_hours(@start\_date, @end\_date)  
end

def self.total\_hours(start\_date, end\_date)  
self.sum(:hours, :conditions =\> between(start\_date, end\_date))  
end

def total\_incoming  
A.total\_incoming(@start\_date, @end\_date)  
end

def self.total\_incoming(start\_date, end\_date)  
self.sum(:incoming, :conditions =\> between(start\_date, end\_date))  
end

def total\_outgoing  
A.total\_outgoing(@start\_date, @end\_date)  
end

def self.total\_outgoing(start\_date, end\_date)  
self.sum(:outgoing, :conditions =\> between(start\_date, end\_date))  
end  
end

Everything works as expected. However, I am wondering if there is a  
more Rubyish way of accomplishing this so I can avoid the repetition.  
Any other suggestions are welcome. Thanks in advance.

Michael G.

---

<div class="post-metadata">

**Author:** ![mgreenly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85f322/32.png) [@mgreenly](https://www.ruby-forum.com/u/mgreenly)\
**Post date:** [August 15, 2006, 8:34pm UTC](https://www.ruby-forum.com/t/instance-and-related-class-methods/65043/2 "2006-08-15T20:34:41Z")

</div>

Michael G. wrote:

> I have a class with a lot of instance methods which are related to  
> class methods from within the same class.
> 
> Example:
> 
> Everything works as expected. However, I am wondering if there is a  
> more Rubyish way of accomplishing this so I can avoid the repetition.  
> Any other suggestions are welcome. Thanks in advance.

The simplest thing would be to eliminate these calls on  
the instances completely since no instance data is needed.

If you do want to do this, you can automate it by creating  
a #method\_missing handler for the instance methods–it will  
check whether a class method by the same name exists and  
then forward to it (falling back on the normal #method\_missing  
on failure).

> Michael G.

---

<div class="post-metadata">

**Author:** ![mgreenly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85f322/32.png) [@mgreenly](https://www.ruby-forum.com/u/mgreenly)\
**Post date:** [August 15, 2006, 8:48pm UTC](https://www.ruby-forum.com/t/instance-and-related-class-methods/65043/3 "2006-08-15T20:48:30Z")

</div>

On 8/15/06, Eero S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > more Rubyish way of accomplishing this so I can avoid the repetition.  
> > Any other suggestions are welcome. Thanks in advance.
> 
> The simplest thing would be to eliminate these calls on  
> the instances completely since no instance data is needed.

I’m not sure I understand. I would like to have access to both class  
and  
instance methods. Basically some of my code looks like this.

day = A.new(1.days.ago, Time.now)  
hour = A.new(1.hour.ago, Time.now)

Then I would also like to be able to use arbitrary starting and ending  
ranges with the class method, without the need to create an instance.

total\_incoming = A.total\_incoming(1.year.ago, Time.now)

If you do want to do this, you can automate it by creating

> a #method\_missing handler for the instance methods–it will  
> check whether a class method by the same name exists and  
> then forward to it (falling back on the normal #method\_missing  
> on failure).

---

<div class="post-metadata">

**Author:** ![mgreenly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85f322/32.png) [@mgreenly](https://www.ruby-forum.com/u/mgreenly)\
**Post date:** [August 15, 2006, 9:24pm UTC](https://www.ruby-forum.com/t/instance-and-related-class-methods/65043/4 "2006-08-15T21:24:59Z")

</div>

Michael G. wrote:

> On 8/15/06, Eero S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > > more Rubyish way of accomplishing this so I can avoid the repetition.  
> > > Any other suggestions are welcome. Thanks in advance.
> > 
> > The simplest thing would be to eliminate these calls on  
> > the instances completely since no instance data is needed.
> 
> I’m not sure I understand. I would like to have access to both class  
> and  
> instance methods. Basically some of my code looks like this.

Yes, I apologise, I misread this as a simpler scenario.  
In your case, there is no simple automation unless you  
can generalise how the mapping from instance- to class  
methods would work (for example, if all the methods pass  
@start\_date and @end\_date you could map it easily).

Alternately you could modify the class methods to accept  
an instance and extract the data from it–while of course  
still accepting the times when no instance is available.  
This way you can automate a missing instance method mapping  
to call the class method with the instance as the argument.  
The #method\_missing, er, method works for this.

There is no built-in way to achieve this, though.

> day = A.new(1.days.ago, Time.now)  
> hour = A.new(1.hour.ago, Time.now)
> 
> Then I would also like to be able to use arbitrary starting and ending  
> ranges with the class method, without the need to create an instance.
> 
> total\_incoming = A.total\_incoming(1.year.ago, Time.now)
> 
> If you do want to do this, you can automate it by creating
> 
> > a #method\_missing handler for the instance methods–it will  
> > check whether a class method by the same name exists and  
> > then forward to it (falling back on the normal #method\_missing  
> > on failure).
