Subclassing Date

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
#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.

On Wed, Sep 26, 2012 at 6:02 PM, Damin M. Gonzlez
[email protected] 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

What version of Ruby are you using?

Jesus.

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]

$ 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:–

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=#!topic/comp.lang.ruby/sDiFAuBjuwY/overview

It seems to have been unfixed in ruby 1.9.3.

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

Oh ok! now I’ll have to seek another way, thanks for deal.

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

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.

On Thu, Sep 27, 2012 at 2:30 PM, Damin M. Gonzlez
[email protected] 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/019-Complete_Numeric_Class.html

Cheers

robert

Thank you Robert :slight_smile: