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 `<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 via http://www.ruby-forum.com/.

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.

···

On Wed, Sep 26, 2012 at 6:02 PM, Damián M. González <lists@ruby-forum.com> wrote:

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

$ 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 complex aliasing
which causes Class.new (which Dia inherits) not to call 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

It seems to have been unfixed in ruby 1.9.3.

···

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

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

···

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

Thank you Robert :slight_smile:

···

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

What version of Ruby are you using?

Microsoft Windows XP [Versión 5.1.2600]
ruby 1.9.3p194 (2012-04-20) [i386-mingw32]

···

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

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 via http://www.ruby-forum.com/\.

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 via http://www.ruby-forum.com/\.

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 via http://www.ruby-forum.com/\.

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

···

On Thu, Sep 27, 2012 at 2:30 PM, Damián M. González <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.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/