Как перехватить вызов конструктора класса Hash?

Я хочу выполнить функцию, когда вызывается конструктор класса Hash или когда инициализируется объект Hash. Я реализовал свою цель, используя

class Hash
  def initialize
    p "Constructor call"
  end
end

Приведенный выше код прекрасно работает, когда объект Hash инициализируется следующим образом:

a = Hash.new(:a1 => "Hi")

Тем не менее, когда я использую следующий код:

a = {:a1 => "Hi"}

Затем происходит сбой или конструктор не вызывается. Итак, как перехватить вызов, сделанный во втором фрагменте кода?

Заранее спасибо.

2 ответа

Решение

Боюсь, что вы не можете в МРТ, но, вероятно, могли бы что-то сделать в Рубиниусе / JRuby.

К сожалению, как и почти во всех других языках, вы не можете переопределить литералы в Ruby. Вам придется использовать один из немногих языков, которые позволяют это, например Ioke:

cell(:{}) = method(+x, "Literal {} called with #{x inspect}" println)

{ :a1 => "Hi" }
;; Literal {} called with [:a1 => "Hi"]

(На самом деле, Ioke - единственный язык, о котором я могу думать сейчас, который допускает буквальную перегрузку / переопределение. Я предполагаю, что двоюродный брат Ioke Seph поддержит его, и пару лет назад была некоторая дискуссия о разрешении этого в Newspeak, но это об этом.)

Другие вопросы по тегам