Apoorv Saxena
Apoorv Saxena

Reputation: 4236

How to intercept the call to constructor of class Hash?

I want to execute a function when a constructor of class Hash is called or when a Hash object is initialized. I have implemented my objective using

class Hash
  def initialize
    p "Constructor call"
  end
end

The code above works fine when a Hash object is initialized as follows:

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

However, when I use the following code:

a = {:a1 => "Hi"}

Then, it fails or the constructor is not called. So, how to intercept the call made in the second code snippet?

Thanks in advance.

Upvotes: 2

Views: 365

Answers (2)

Jörg W Mittag
Jörg W Mittag

Reputation: 369554

Unfortunately, just like in almost every other language, you cannot override literals in Ruby. You'll have to use one of the few languages that allow this, like Ioke:

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

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

(In fact, Ioke is the only language I can think of right now which allows literal overloading / overriding. I suppose Ioke's cousin Seph will support it, and a couple of years of ago there was some discussion about allowing it in Newspeak, but that's about it.)

Upvotes: 2

Marc-André Lafortune
Marc-André Lafortune

Reputation: 79592

I'm afraid you can't in MRI, but could probably manage something in Rubinius / JRuby.

Upvotes: 2

Related Questions