# Class returns value without method or attribute

**URL:** <https://www.ruby-forum.com/t/class-returns-value-without-method-or-attribute/59091>\
**Category:** Ruby\
**Created:** [April 28, 2006, 4:39pm UTC](https://www.ruby-forum.com/t/class-returns-value-without-method-or-attribute/59091 "2006-04-28T16:39:32Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/82dd89/32.png) [@kris](https://www.ruby-forum.com/u/kris)\
**Post date:** [April 28, 2006, 4:39pm UTC](https://www.ruby-forum.com/t/class-returns-value-without-method-or-attribute/59091/1 "2006-04-28T16:39:32Z")

</div>

If I have a class how do I get it to return a value without specifying a  
method or attribute:

class Money  
attr\_writer :value  
end

money = Money.new(5)

money.value =\> 5

but what if I want:

money =\> 5

So the actual object returns a value instead of a method or attribute,  
like the base classes do.

Many thanks, K.

---

<div class="post-metadata">

**Author:** ![kris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/82dd89/32.png) [@kris](https://www.ruby-forum.com/u/kris)\
**Post date:** [April 28, 2006, 5:00pm UTC](https://www.ruby-forum.com/t/class-returns-value-without-method-or-attribute/59091/2 "2006-04-28T17:00:51Z")

</div>

You could overload the methods you require. For instance if you want  
to be able to add two Money objects togeter and get a Money object as  
the result using the expression ‘money1 + money2’ you could do

> > class Money  
> > attr\_accessor :value  
> > def+(other)  
> > Money.new(@value + other.value)  
> > end  
> > def initialize(value)  
> > @value = value  
> > end  
> > end  
> > =\> nil
> 
> > m1 = Money.new(5)  
> > =\> #\<Money:0x2dbb018 @value=5\>
> 
> > m2 = Money.new(10)  
> > =\> #\<Money:0x2db9098 @value=10\>
> 
> > m1 + m2  
> > =\> #\<Money:0x2db17d8 @value=15\>

Farrel

---

<div class="post-metadata">

**Author:** ![kris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/82dd89/32.png) [@kris](https://www.ruby-forum.com/u/kris)\
**Post date:** [April 28, 2006, 5:19pm UTC](https://www.ruby-forum.com/t/class-returns-value-without-method-or-attribute/59091/3 "2006-04-28T17:19:11Z")

</div>

> If I have a class how do I get it to return a value without specifying a  
> method or attribute:

You want to overload the inspect method:

class Money  
attr\_accessor :value

def initialize(value)  
@value = value  
end

def inspect  
@value  
end

end

irb(main):001:0\> require ‘money’  
=\> true  
irb(main):002:0\> money = Money.new(5)  
=\> 5  
irb(main):003:0\> money  
=\> 5

---

<div class="post-metadata">

**Author:** ![kris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/82dd89/32.png) [@kris](https://www.ruby-forum.com/u/kris)\
**Post date:** [April 28, 2006, 5:19pm UTC](https://www.ruby-forum.com/t/class-returns-value-without-method-or-attribute/59091/4 "2006-04-28T17:19:17Z")

</div>

Hi,

Here is my approach (similar, but longer):

$ cat money.rb

class Money  
attr\_accessor :value

def initialize(value)  
@value = value  
end

def to\_s  
@value.to\_s  
end

def +(other)  
case other  
when Money:  
Money.new(@value + other.value)  
when Numeric:  
Money.new(@value + other)  
else  
raise “Money can be added to Money or Numeric”  
end  
end  
end

irb(main):002:0\> money = Money.new 5  
=\> #\<Money:0x2ba41c8 @value=5\>  
irb(main):004:0\> puts money  
5  
irb(main):005:0\> puts money + money  
10  
irb(main):006:0\> puts money + 100  
105  
irb(main):007:0\> puts money + ‘money’  
RuntimeError: Money can be added to Money or Numeric  
from ./money.rb:19:in `+’  
from (irb):7

–  
Martins

---

<div class="post-metadata">

**Author:** ![kris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/82dd89/32.png) [@kris](https://www.ruby-forum.com/u/kris)\
**Post date:** [April 28, 2006, 5:28pm UTC](https://www.ruby-forum.com/t/class-returns-value-without-method-or-attribute/59091/5 "2006-04-28T17:28:35Z")

</div>

On Fri, 2006-04-28 at 23:39 +0900, kris wrote:

> money.value =\> 5
> 
> but what if I want:
> 
> money =\> 5
> 
> So the actual object returns a value instead of a method or attribute,  
> like the base classes do.

Another way to get this kind of behaviour is:

require ‘delegate’  
Money = DelegateClass(Float)  
m = Money.new(30.0)

p m

> > 30.0  
> > p m + 30.0
> 
> > 60.0  
> > p m + Money.new(30.0)
> 
> > 60.0  
> > p m.class
> 
> > Money  
> > p m. **getobj**.class
> 
> > Float  
> > p m + “notmoney”

---

<div class="post-metadata">

**Author:** ![kris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/82dd89/32.png) [@kris](https://www.ruby-forum.com/u/kris)\
**Post date:** [May 3, 2006, 7:08pm UTC](https://www.ruby-forum.com/t/class-returns-value-without-method-or-attribute/59091/6 "2006-05-03T19:08:24Z")

</div>

2006/4/29, kris [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> I like the idea of using inspect, will this also allow me to assign  
> value like:  
> money = Money.new  
> money = 5

No, inspect will only affect output with p (or in IRB).

> Also do I need to add a method for + and -, is there not a module like  
> Comparable that I can mixin to get this functionality?

Comparation and arithmetic are two orthogonal concepts, i.e.  
completely unrelated. If you want arithmetic in your class, you need  
to override +, - and coerce.

> **[WebMD - Better information. Better health.](https://www.webmd.com/?CoerceExplanation)**
>
> The leading source for trustworthy and timely health and medical news and information. Providing credible health information, supportive community, and educational services by blending award-winning expertise in content, community services, expert...

> **[WebMD - Better information. Better health.](https://www.rubygarden.org/?terms=coerce&submit=SEARCH&handler=searching)**
>
> The leading source for trustworthy and timely health and medical news and information. Providing credible health information, supportive community, and educational services by blending award-winning expertise in content, community services, expert...

For ordering there is mixin Comparable  
[http://ruby-doc.org/core/classes/Comparable.html](http://ruby-doc.org/core/classes/Comparable.html)  
[http://www.rubycentral.com/book/ref\_m\_comparable.html](http://www.rubycentral.com/book/ref_m_comparable.html)

> Are there any other typical methods I should be adding? Excluding the  
> money specific stuff I have to\_s.

to\_int is an option, too, if your instance is equivalent to an int.  
Additionally you should implement to\_i and to\_f.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![kris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/82dd89/32.png) [@kris](https://www.ruby-forum.com/u/kris)\
**Post date:** [April 29, 2006, 11:52am UTC](https://www.ruby-forum.com/t/class-returns-value-without-method-or-attribute/59091/7 "2006-04-29T11:52:03Z")

</div>

I like the idea of using inspect, will this also allow me to assign  
value like:  
money = Money.new  
money = 5

Also do I need to add a method for + and -, is there not a module like  
Comparable that I can mixin to get this functionality?

Are there any other typical methods I should be adding? Excluding the  
money specific stuff I have to\_s.

Many thanks for all the replies they have been really helpful.

Gordon T. wrote:

> > If I have a class how do I get it to return a value without specifying a  
> > method or attribute:
> 
> You want to overload the inspect method:
> 
> class Money  
> attr\_accessor :value
> 
> def initialize(value)  
> @value = value  
> end
> 
> def inspect  
> @value  
> end
> 
> end
> 
> irb(main):001:0\> require ‘money’  
> =\> true  
> irb(main):002:0\> money = Money.new(5)  
> =\> 5  
> irb(main):003:0\> money  
> =\> 5
