Why does Date.new not cause initialization?

I want to subclass Date.

A normal, healthy young lawyer, unprotected from the idiosyncrasy of the Date implementation, will go as follows:

require 'date' class MyDate < Date def initialize(year, month, day) @original_month = month @original_day = day # Christmas comes early! super(year, 12, 25) end end 

And keep using it in the most expected way ...

 require 'my_date' mdt = MyDate.new(2012, 1, 28) puts mdt.to_s 

... just to be a double crossing of the fact that the Date :: new method is actually an alias of Date :: civil, which never calls initialization. In this case, the last code snippet prints "2012-01-28" instead of the expected "2012-12-25".

Dear Ruby community, wtf it?

Is there any very good reason to smooth out the new, so that it ignores initialization and, as a result, any common sense and attitude to the mental health of the client-programmer?

+6
source share
1 answer

You define initialize , but you create a new instance with new . new returns a new instance of the class, not the result of initialize .

You can:

 require 'date' class MyDate < Date def self.new(year, month, day) @original_month = month @original_day = day # Christmas comes early! super(year, 12, 25) end end mdt = MyDate.new(2012, 1, 28) puts mdt.to_s 

Note: @original_month and @original_day are not available in this solution. The following solution extends the date, so you can access the original months and days. For normal dates, the values ​​will be zero.

 require 'date' class Date attr_accessor :original_month attr_accessor :original_day end class MyDate < Date def self.new(year, month, day) # Christmas comes early! date = super(year, 12, 25) date.original_month = month date.original_day = day date end end mdt = MyDate.new(2012, 1, 28) puts mdt.to_s puts mdt.original_month 

But I would recommend:

 require 'date' class MyDate < Date def self.create(year, month, day) @original_month = month @original_day = day # Christmas comes early! new(year, 12, 25) end end mdt = MyDate.create(2012, 1, 28) puts mdt.to_s 

or

 require 'date' class Date def this_year_christmas # Christmas comes early! self.class.new(year, 12, 28) end end mdt = Date.new(2012, 1, 28).this_year_christmas puts mdt.to_s 
+6
source

Source: https://habr.com/ru/post/907129/


All Articles