Class returns value without method or attribute

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.

···

--
Posted via http://www.ruby-forum.com/.

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

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

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.

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"

···

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

-:9: String can't be coerced into Float (TypeError)

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

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

On 4/28/06, Farrel Lifson <farrel.lifson@gmail.com> wrote:

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

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 Thiesfeld 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

--
Posted via http://www.ruby-forum.com/\.

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.

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

···

2006/4/29, kris <krisleech@interkonect.com>:

--
Have a look: http://www.flickr.com/photos/fussel-foto/