Forum: Ruby Subclassing Date

Posted by Damián M. González (igorjorobus)
on 2012-09-26 18:02
Ey guys, can't understand what's happening here:

 require 'date'

 class Dia < Date
  def initialize(ano, mes, dia, obj_mes)
   @mes = obj_mes
   super(ano, mes, dia)
  end
 end

 a = Dia.new
 => #<Dia: -4712-01-01 ((0j,0s,0n),+0s,2299161j)>
 #Was expecting an error, no arguments has been passed
 a = Dia.new(2012, 6, 21, "foo")
 => TypeError: no implicit conversion to float from string
        from (irb):31:in `new'
        from (irb):31
        from C:/Ruby193/bin/irb:12:in `<main>'
 #Seems that the 4th argument is taked by...super too?? WTF
 a = Dia.new(2012, 5, 26)
 => #<Dia: 2012-05-26 ((2456074j,0s,0n),+0s,2299161j)>
 a = Dia.new(2012, 5, 26, Date::ITALY)
 => #<Dia: 2012-05-26 ((2456074j,0s,0n),+0s,2299161j)>
 #Obvious is taked by super...but why? I don't expect that

 We can see that new() doesn't matter if it is no receive parameters, or
if it receive, it behave like make Date.new, but why? I'm re-defining
the method initialize in Dia, it sholud(am I wrong?) take exactly 4
parameters and asign the last one to the instance variable @mes. Why is
this happening? I've tried putting super in the first line of the
definition but the same's returned. Thanks for your time.
Posted by "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> (Guest)
on 2012-09-26 18:27
(Received via mailing list)
On Wed, Sep 26, 2012 at 6:02 PM, Damin M. Gonzlez
<lists@ruby-forum.com> wrote:
>
>  a = Dia.new
>  => #<Dia: -4712-01-01 ((0j,0s,0n),+0s,2299161j)>
>  #Was expecting an error, no arguments has been passed

1.9.2p290 :001 > require 'date'
 => true
1.9.2p290 :002 >
1.9.2p290 :003 >    class Dia < Date
1.9.2p290 :004?>     def initialize(ano, mes, dia, obj_mes)
1.9.2p290 :005?>        @mes = obj_mes
1.9.2p290 :006?>        super(ano, mes, dia)
1.9.2p290 :007?>       end
1.9.2p290 :008?>    end
 => nil
1.9.2p290 :009 > Dia.new
ArgumentError: wrong number of arguments (3 for 4)
  from (irb):4:in `initialize'
  from 
/home/jesus/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/date.rb:811:in
`new'
  from 
/home/jesus/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/date.rb:811:in
`civil'
  from (irb):9
  from /home/jesus/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'

What version of Ruby are you using?

Jesus.
Posted by Damián M. González (igorjorobus)
on 2012-09-26 18:46
> What version of Ruby are you using?

Microsoft Windows XP SP3 [Versión 5.1.2600]
ruby 1.9.3p194 (2012-04-20) [i386-mingw32]
Posted by 7stud -- (7stud)
on 2012-09-26 21:30
$ ruby --version
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin10.8.0]


require 'date'

class Dia < Date
  def initialize
    #@mes = obj_mes
    #super(ano, mes, dia)
    puts 'init'
  end
end

Dia.new

--output:--
<nothing>

So that means Dia#initialize is not being called by Dia.new, which is a
bit confounding.  Apparently, the date module does some aliasing
which causes new() (which Dia inherits) to call Date#initialize.
Your subclassing of Date problem was discussed in 2001, by none other
than Matz, and supposedly that behavior was going to be fixed:

https://groups.google.com/forum/?fromgroups=#!topi...

It seems to have been unfixed in ruby 1.9.3.
Posted by Damián M. González (igorjorobus)
on 2012-09-26 23:33
Oh ok! now I'll have to seek another way, thanks for deal.
Posted by Robert Klemme (robert_k78)
on 2012-09-27 09:17
Damián M. González wrote in post #1077685:
> Oh ok! now I'll have to seek another way, thanks for deal.

Why are you subclassing Date in the first place?

Kind regards

robert
Posted by Gianfranco Bozzetti (gfb)
on 2012-09-27 11:52
Damián M. González wrote in post #1077685:
> Oh ok! now I'll have to seek another way, thanks for deal.

You can use composition instead of subclassing, as in

require 'date'

 class Dia
  def initialize(ano, mes, dia, obj_mes)
    @mes=obj_mes
    @d = Date.new(ano,mes,dia)
  end
  def print()
    printf "date = %04d-%02d-%02d : obj_mes = %-s\n ",
      @d.year, @d.month, @d.day, @mes
  end
 end

a = Dia.new(2012, 6, 21,"foo")
a.print()

__END__

Output:
[2012/09/27] [11:17:47.31] [C:\_MyPrg\Ruby\Exper\Forum]
ruby subdate.rb
date = 2012-06-21 : obj_mes = foo

HTH gfb
Posted by Damián M. González (igorjorobus)
on 2012-09-27 14:30
> Why are you subclassing Date in the first place?

 Well, the class Dia(It's day in spanish) represent a day. Each instance
of this class have like 10 inst. variables. I wanted to subclass Date
because I want to be available +() or -() or cweek() to a Dia instance,
in the way that it behave like a Date object does.

>You can use composition instead of subclassing, as in
>
>require 'date'
>
> class Dia
>  def initialize(ano, mes, dia, obj_mes)
>    @mes=obj_mes
>    @d = Date.new(ano,mes,dia)
>  end
>  def print()
>    printf "date = %04d-%02d-%02d : obj_mes = %-s\n ",
>      @d.year, @d.month, @d.day, @mes
>  end
> end
>
>a = Dia.new(2012, 6, 21,"foo")
>a.print()
>
>__END__
>
>Output:
>[2012/09/27] [11:17:47.31] [C:\_MyPrg\Ruby\Exper\Forum]
>ruby subdate.rb
>date = 2012-06-21 : obj_mes = foo
>
>HTH gfb

 Yes, I'll have to go for something like that, thanks.
Posted by Robert Klemme (robert_k78)
on 2012-09-27 18:42
(Received via mailing list)
On Thu, Sep 27, 2012 at 2:30 PM, Damin M. Gonzlez
<lists@ruby-forum.com> wrote:
>> Why are you subclassing Date in the first place?
>
>  Well, the class Dia(It's day in spanish) represent a day. Each instance
> of this class have like 10 inst. variables. I wanted to subclass Date
> because I want to be available +() or -() or cweek() to a Dia instance,
> in the way that it behave like a Date object does.

Then better use composition as has been suggested.  Inheriting core
classes is rarely a good idea.  What you have is actually something
else which happens to have a data attached to it as well.  If you need
numeric operations one of my blog articles might help you to implement
operators properly:

http://blog.rubybestpractices.com/posts/rklemme/01...

Cheers

robert
Posted by Damián M. González (igorjorobus)
on 2012-09-28 05:21
Thank you Robert :)
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.