Почему Date.new не вызывает инициализацию? - PullRequest
6 голосов
/ 29 января 2012

Я хочу создать подкласс Date.

Нормальный, здоровый, молодой рубинист, не пострадавший от идиосинкразии реализации Дейта, поступил бы следующим образом:

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

И продолжайте использовать его самым ожидаемым образом ...

require 'my_date'

mdt = MyDate.new(2012, 1, 28)

puts mdt.to_s

... только для того, чтобы быть в двойном смысле из-за того факта, что метод Date :: new на самом деле является псевдонимом Date :: civil, который не никогда не вызывает инициализацию. В этом случае последний фрагмент кода печатает «2012-01-28» вместо ожидаемого «2012-12-25».

Уважаемое Ruby-сообщество, что это такое?

Есть ли очень веская причина для наложения псевдонима new , чтобы он игнорировал initialize и, как следствие, какой-либо здравый смысл и внимание к психическому здоровью программиста клиента?

1 Ответ

6 голосов
/ 29 января 2012

Вы определяете initialize, но вы создаете новый экземпляр с new. new возвращает новый экземпляр класса, а не результат initialize.

Вы можете сделать:

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

Примечание: @original_month и @original_day недоступны в этом решении. Следующее решение расширяет дату, поэтому вы можете получить доступ к исходному месяцу и дню. Для обычных дат значения будут равны нулю.

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

Но я бы порекомендовал:

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

или

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...