How to derive from DateTime?

L

luisealvarezb

Hi, everybody:

I have been tring to derive a class from DateTime and in doing so have
come across some nasty problems: it turns out overriding the
constructor is not straight forward at all. I was looking for some
pointers, anyone????
Here is what I have:

require 'rubygems'
#~ require 'ruby-debug'

require 'date'
class Event < DateTime
class << self
alias :eek:ld_new :new
def new summary, due_date, long_text='', alarm_time=0
dt = DateTime.parse( due_date )
obj = old_new(dt.year, dt.month, dt.day, dt.hour, dt.min, dt.sec,
dt.sg)
obj.send :initialize, summary, long_text, alarm_time
obj
end
end

attr_accessor :summary, :long_text, :alarm_time

def initialize summary, long_text='', alarm_time=0
@summary = summary
@long_text = long_text
@alarm_time = alarm_time
end
end

e = Event.new "something to do", "2009-10-10T00:00"
puts e.summary
puts e.year

e is an event at the end of the code, it has a summary and what ever
else I pass in but the DateTime structures are not initialized
correctly. In other words e.year gives me an error and here it is:

/usr/lib/ruby/1.8/date.rb:492:in `ajd_to_jd': undefined method `+' for
nil:NilClass (NoMethodError)
from /usr/lib/ruby/1.8/date.rb:1051:in `__21105__'
from (eval):4:in `jd'
from /usr/lib/ruby/1.8/date.rb:1066:in `__21521__'
from (eval):4:in `civil'
from /usr/lib/ruby/1.8/date.rb:1081:in `year'
from D:/workspace/todo/lib/tester.rb:29

I have tryed some other variants of the code as well and it gets even
worse. Can any one help, please?
Bye, Luis
 
E

Ehsanul Hoque

It looks to me that this is a case where you might be better served by us= ing
composition and delegation rather than inheritance: instead of an Event
being a specialized DateTime=2C it would have a DateTime instance as an
instance variable and delegate certain methods (e.g.=2C year=2C etc.) to = that
instance variable.
=20

I agree with Christopher here. What you want is a proxy class. Here's a way=
you might implement it:

class Event

def self.new( *args )


class << datetime =3D DateTime.new(*args)

def sweet

"what a sweet method"

end

end

datetime


end

end


You could also try this way:


class Event
instance_methods.each { |m| undef_method m unless m =3D~ /(^__|^send$|^=
object_id$)/ }

def initialize(*args)


@date_time =3D DateTime.new(*args)


end

def method_missing(name=2C *args=2C &block)
@date_time.send(name=2C *args=2C &block)
end
end


I'm sure you can figure out what's happening here=2C and how to merge it wi=
th your own code.

- Ehsan
=0A=
_________________________________________________________________=0A=
Bing=99 brings you maps=2C menus=2C and reviews organized in one place. =
Try it now.=0A=
http://www.bing.com/search?q=3Drestaurants&form=3DMLOGEN&publ=3DWLHMTAG&cre=
a=3DTEXT_MLOGEN_Core_tagline_local_1x1=
 
L

luisealvarezb

I agree with Christopher here. What you want is a proxy class. Here's a way you might implement it:

class Event

  def self.new( *args )

    class << datetime = DateTime.new(*args)

      def sweet

        "what a sweet method"

      end

    end

    datetime

  end

end

You could also try this way:

class Event
    instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$)/ }

def initialize(*args)

  @date_time = DateTime.new(*args)

end

        def method_missing(name, *args, &block)
          @date_time.send(name, *args, &block)
        end
end

I'm sure you can figure out what's happening here, and how to merge it with your own code.

- Ehsan

_________________________________________________________________
Bing™  brings you maps, menus, and reviews organized in one place.   Try it now.http://www.bing.com/search?q=restaurants&form=MLOGEN&publ=WLHMTAG&cre...

Thank you for that code it looks like a good solution and will use
it. However, I am left wondering why this anomaly with the
constructors in DateTime, does that not violate OO practices. How can
you not be able to inherit from a Class X and redefine it.

Thanks a lot...
 
E

Ehsanul Hoque

=20
Thank you for that code it looks like a good solution and will use
it. However=2C I am left wondering why this anomaly with the
constructors in DateTime=2C does that not violate OO practices. How can
you not be able to inherit from a Class X and redefine it.
=20
Thanks a lot...
=20

Actually=2C there's no anomaly really=2C as far as I know. There's some bug=
in the code. I have no idea where=2C your code seems fine to me=2C and it =
could just be because of the way the DateTime class was implemented. But yo=
u can in fact redefined constructors=2C and it works fine. Try this for exa=
mple (just an adaptation of your code):

class Foo
def initialize(x)
@x =3D x
@message =3D "message from foo"
end
attr_accessor :message=2C :x
end

class Bar < Foo
class << self
alias :eek:ld_new :new
def new(x)
obj =3D old_new
obj.send :initialize
obj
end
end
=20
def initialize
@message =3D "message from bar"
end
=20
attr_accessor :message
end



f =3D Foo.new(0)


f.message #=3D> "message from foo"

f.x #=3D> 0

b =3D Bar.new(0)

b.message #=3D> "message from bar"
b.x #=3D> nil (I actually don't understand why this is=2C someone=
else might be able to explain)

=0A=
_________________________________________________________________=0A=
Bing=99 brings you maps=2C menus=2C and reviews organized in one place. =
Try it now.=0A=
http://www.bing.com/search?q=3Drestaurants&form=3DMLOGEN&publ=3DWLHMTAG&cre=
a=3DTEXT_MLOGEN_Core_tagline_local_1x1=
 
L

luisealvarezb

Actually, there's no anomaly really, as far as I know. There's some bug in the code. I have no idea where, your code seems fine to me, and it could just be because of the way the DateTime class was implemented. But you can in fact redefined constructors, and it works fine. Try this for example (just an adaptation of your code):

class Foo
  def initialize(x)
    @x = x
    @message = "message from foo"
  end
  attr_accessor :message, :x
end

class Bar < Foo
  class << self
    alias :eek:ld_new :new
    def new(x)
      obj = old_new
      obj.send :initialize
      obj
    end
  end

  def initialize
    @message = "message from bar"
  end

  attr_accessor :message
end

f = Foo.new(0)

f.message   #=> "message from foo"

f.x       #=> 0

b = Bar.new(0)

b.message       #=> "message from bar"
b.x         #=> nil   (I actually don't understand why this is, someone else might be able to explain)

_________________________________________________________________
Bing™  brings you maps, menus, and reviews organized in one place.   Try it now.http://www.bing.com/search?q=restaurants&form=MLOGEN&publ=WLHMTAG&cre...

Specializing other classes works fine but DateTime fails...I see, yeah
I can't explain it either. Ok, I will just go with what I have.
Thanks a lot.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top