Kal
Kal

Reputation: 2674

Naming array method 'to_hash' causes 'stack level too deep' error

I tried to create a 'to_hash' array method, but kept getting 'stack level too deep' errors:

class Array
  def to_hash
    Hash[self.each_index.zip(self)]
  end
end

puts [50, 49, 53, 44].to_hash

# SystemStackError: stack level too deep

I finally worked out that the method name 'to_hash' is causing the problem. Simply changing it to 'to_hsh' makes it work as expected:

class Array
  def to_hsh
    Hash[self.each_index.zip(self)]
  end
end

puts [50, 49, 53, 44].to_hsh

# => {0=>50, 1=>49, 2=>53, 3=>44}

If I try to call a 'to_hash' method on an array (without writing my own method) I get:

NoMethodError: undefined method ‘to_hash’ for [50, 49, 53, 44]:Array

So if there's no built-in 'to_hash' method for arrays, why am I getting problems by naming my own array method 'to_hash'?

Upvotes: 2

Views: 247

Answers (1)

Arup Rakshit
Arup Rakshit

Reputation: 118299

Because Kernel#Hash method calls to_hash. Which results in recursive call.

Documentation says :

Converts arg to a Hash by calling arg.to_hash. Returns an empty Hash when arg is nil or [].

In the line Hash[self.each_index.zip(self)], self.each_index.zip(self) produces an array, on which Kernel#Hash is calling to_hash. Now this to_hash becomes your custom to_hash method, which is a recursive call and produced the error as stack level too deep (SystemStackError).

Upvotes: 3

Related Questions