Inheriting from / Delegating to Integer - Currency class implementation

Discussion in 'Ruby' started by Pascal Ehlert, Feb 9, 2008.

  1. Howdy folks.

    I'm currently working on a Currency class which I'd like to behave
    exactly like Integer with some additional methods like #to_currency and
    and overridden #to_s method etc.

    My first approach was to inherit from Integer directly which failed,
    because there is no constructor for this class. After some more
    research I found the DelegateClass method which seemed to be exactly
    what I need, however there was one major problem with it: Methods like
    #+ and #- returned Integer, not Currency objects. So "(Currency.new(20)
    + Currency.new(30)).class" evaled to Integer and my custom methods have
    been gone.

    The latest approach was not to inherit at all but write the class from
    scratch, carrying around a @value instance variable which stores an
    Integer representation of the currency.
    Unfortunately that idea didn't work to good either because I couldn't
    add Currency objects to Fixnums anymore, "20 + Currency.new(30)" raised
    a TypeError ("Currency can't be coerced into Fixnum"), although my
    class implements a #to_i method.

    I actually like best the second way, using DelegateClass.
    Are there any ways to make the calculation methods return a Currency
    object then?
    Or do you at least have an idea how to solve the problem with the
    latest approach?

    Thank you

    -- Pascal
     
    Pascal Ehlert, Feb 9, 2008
    #1
    1. Advertising

  2. Re: Inheriting from / Delegating to Integer - Currency classimplementation

    On 2/9/08, Pascal Ehlert <> wrote:
    > Howdy folks.
    >
    > I'm currently working on a Currency class which I'd like to behave
    > exactly like Integer with some additional methods like #to_currency and
    > and overridden #to_s method etc.
    >
    > My first approach was to inherit from Integer directly which failed,
    > because there is no constructor for this class. After some more
    > research I found the DelegateClass method which seemed to be exactly
    > what I need, however there was one major problem with it: Methods like
    > #+ and #- returned Integer, not Currency objects. So "(Currency.new(20)
    > + Currency.new(30)).class" evaled to Integer and my custom methods have
    > been gone.
    >
    > The latest approach was not to inherit at all but write the class from
    > scratch, carrying around a @value instance variable which stores an
    > Integer representation of the currency.
    > Unfortunately that idea didn't work to good either because I couldn't
    > add Currency objects to Fixnums anymore, "20 + Currency.new(30)" raised
    > a TypeError ("Currency can't be coerced into Fixnum"), although my
    > class implements a #to_i method.
    >
    > I actually like best the second way, using DelegateClass.
    > Are there any ways to make the calculation methods return a Currency
    > object then?
    > Or do you at least have an idea how to solve the problem with the
    > latest approach?

    class Currency

    attr_reader :base_value

    def initialize(value)
    @base_value = value
    end

    def +(other)
    Currency.new(@base_value + other.to_currency.base_value)
    end

    def to_currency
    self
    end

    def coerce(other)
    [self, other.to_currency]
    end

    end

    class Numeric
    def to_currency
    Currency.new(self)
    end
    end

    Currency.new(10) + Currency.new(5) # => #<Currency:0x23ab4 @base_value=15>
    10 + Currency.new(5) # => #<Currency:0x238e8 @base_value=15>

    HTH


    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
     
    Rick DeNatale, Feb 9, 2008
    #2
    1. Advertising

  3. Re: Inheriting from / Delegating to Integer - Currency class implementation

    On 2/9/2008 Rick DeNatale wrote:
    > def coerce(other)
    > [self, other.to_currency]
    > end


    Whoa, that looks really interesting.
    Thanks a lot, Rick!

    However, is there another way to implement the Currency class using
    DelegateClass?
    It still feels wrong to me to write +, -, * and / on my own, although
    they are exactly the same as in the Integer class.

    -- Pascal
     
    Pascal Ehlert, Feb 9, 2008
    #3
  4. Re: Inheriting from / Delegating to Integer - Currency class implementation

    On 09.02.2008 15:25, Pascal Ehlert wrote:
    > On 2/9/2008 Rick DeNatale wrote:
    >> def coerce(other)
    >> [self, other.to_currency]
    >> end

    >
    > Whoa, that looks really interesting.
    > Thanks a lot, Rick!
    >
    > However, is there another way to implement the Currency class using
    > DelegateClass?


    There might be but you will have to handle type differences anyway. You
    will have to implement #coerce, #+ etc. in any case. I recommend to use
    Rick's approach because it is much cleaner.

    > It still feels wrong to me to write +, -, * and / on my own, although
    > they are exactly the same as in the Integer class.


    Actually, they are not the same. Adding currencies is significantly
    more complex than adding ints. What happens if you add 5 EUR and 12
    USD? All sorts of issues are lurking here. A currency value is (at
    least) a decimal value and a currency identifier - at least this is the
    most straightforward definition I can think of. You are doing yourself
    a favor by doing it properly - it's not that difficult.

    Kind regards

    robert
     
    Robert Klemme, Feb 9, 2008
    #4
  5. Pascal Ehlert

    Alex Shulgin Guest

    Re: Inheriting from / Delegating to Integer - Currency classimplementation

    On Feb 9, 4:25 pm, Pascal Ehlert <> wrote:
    > On 2/9/2008 Rick DeNatale wrote:
    >
    > >   def coerce(other)
    > >     [self, other.to_currency]
    > >   end

    >
    > Whoa, that looks really interesting.
    > Thanks a lot, Rick!
    >
    > However, is there another way to implement the Currency class using
    > DelegateClass?
    > It still feels wrong to me to write +, -, * and / on my own, although
    > they are exactly the same as in the Integer class.


    Huh?.. And what is the result for $5 divided by $1? ;)

    --
    Cheers,
    Alex
     
    Alex Shulgin, Feb 10, 2008
    #5
  6. On 2/10/08, Alex Shulgin <> wrote:
    > On Feb 9, 4:25 pm, Pascal Ehlert <> wrote:
    > > On 2/9/2008 Rick DeNatale wrote:
    > >
    > > > def coerce(other)
    > > > [self, other.to_currency]
    > > > end

    > >
    > > Whoa, that looks really interesting.
    > > Thanks a lot, Rick!
    > >
    > > However, is there another way to implement the Currency class using
    > > DelegateClass?
    > > It still feels wrong to me to write +, -, * and / on my own, although
    > > they are exactly the same as in the Integer class.

    >
    > Huh?.. And what is the result for $5 divided by $1? ;)


    What, do you want me to do all of the OP's work for him for free?


    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
     
    Rick DeNatale, Feb 10, 2008
    #6
  7. Re: Inheriting from / Delegating to Integer - Currency classimplementation

    On 2/10/08, Rick DeNatale <> wrote:
    > On 2/10/08, Alex Shulgin <> wrote:

    they are exactly the same as in the Integer class.
    > >
    > > Huh?.. And what is the result for $5 divided by $1? ;)

    >
    > What, do you want me to do all of the OP's work for him for free?


    Actually, I rather blithely skipped over the real point in Alex's question.

    Although my code shows how to do coercion via double dispatching in
    Ruby, it ignores the domain question of what does it mean to add an
    integer to a currency.

    $5 + 1 what?

    It's not clear that an integers and currency really SHOULD be
    compatible in this way.

    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
     
    Rick DeNatale, Feb 10, 2008
    #7
  8. Re: Inheriting from / Delegating to Integer - Currency class

    Alex Shulgin wrote:
    > On Feb 9, 4:25�pm, Pascal Ehlert <> wrote:
    >> DelegateClass?
    >> It still feels wrong to me to write +, -, * and / on my own, although
    >> they are exactly the same as in the Integer class.

    >
    > Huh?.. And what is the result for $5 divided by $1? ;)


    Hrm, I don't know why my answer via google didn't show up. Maybe a
    mistake on my part. So here again:
    That would be a mathematically sound: 5.
    If you need an example to see that this even makes sense, consider: You
    have $5 in $1 pieces. How many $1 pieces do you have? Answer: $5/$1 = 5.

    With $1*$5 it's a bit different as powers other than 0 and 1 of $ as I
    can't find anything where that'd make sense :)

    Regards
    Stefan
    --
    Posted via http://www.ruby-forum.com/.
     
    Stefan Rusterholz, Feb 10, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Johannes Eble

    Delegating Events between User Controls?

    Johannes Eble, May 25, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    684
    Johannes Eble
    May 27, 2004
  2. Brian J. Sayatovic

    Sorting a JTable with a delegating TableModel

    Brian J. Sayatovic, Jul 10, 2003, in forum: Java
    Replies:
    2
    Views:
    1,564
    Kleopatra
    Jul 15, 2003
  3. Randy Smith

    Re: delegating constructors

    Randy Smith, Sep 25, 2003, in forum: Java
    Replies:
    5
    Views:
    435
    Thomas G. Marshall
    Sep 29, 2003
  4. abc

    Delegating class methods

    abc, Mar 1, 2009, in forum: Ruby
    Replies:
    18
    Views:
    266
    Robert Dober
    Mar 3, 2009
  5. Ken Coar
    Replies:
    1
    Views:
    97
    Ken Coar
    Feb 13, 2010
Loading...

Share This Page