Class returns value without method or attribute


#1

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.


#2

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


#3

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


#4

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


#5

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”


#6

2006/4/29, kris 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.

http://www.rubygarden.org/ruby?CoerceExplanation
http://www.rubygarden.org/?terms=coerce&submit=SEARCH&handler=searching

For ordering there is mixin Comparable
http://ruby-doc.org/core/classes/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


#7

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