How to derive from DateTime?

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 :old_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:injd’
from /usr/lib/ruby/1.8/date.rb:1066:in __21521__' from (eval):4:incivil’
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

.

On Fri, Sep 18, 2009 at 1:15 PM, luisealvarezb
[email protected] wrote:

#~ require ‘ruby-debug’
obj
end
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?

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

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

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

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…

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 :old_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)

On Sep 19, 12:58 am, Ehsanul H. [email protected] wrote:

def initialize(x)
obj = old_new
end
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.restaurants - Search

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.

On Sep 18, 7:19 pm, Ehsanul H. [email protected] wrote:

def self.new( *args )

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.restaurants - Search

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…