Requiring a gem with a system class naming conflict

103 views Asked by At

I'm writing a build script in Rake that uses a couple of 3rd party gems. One of these gem defines a class called Hash.

class Hash
  alias hkeys keys

  def keys
    hkeys.sort {|a,b| a.to_s <=> b.to_s }
  end

  def each
    keys.each { |k| yield k, self[k] }
  end
end

This is breaking enumeration, resulting in no block given (yield) (LocalJumpError). I read that I can use ::Hash to reference the core ruby type, but how would this fit with code like

bucket.objects.each do |obj|
  puts "#{obj.key} => #{obj.etag}"
end 
1

There are 1 answers

0
Jörg W Mittag On

One of these gem defines a class called Hash.

No, it doesn't. It modifies the existing Hash class.

I read that I can use ::Hash to reference the core ruby type

That is complete nonsense. ::Hash simply says that constant lookup should start at the root (i.e. Object) instead of the current scope. This would only help if there were two constants named Hash and you wanted to disambiguate them. But in your case, there is only one constant named Hash and the gem is modifying the class referenced by that constant.

There is simply nothing you can do except don't use such crappy gems.