Camping: HashWithReallyIndifferentAccess

by Gregory Brown

This came up in #camping today and I figured it was worth at least a mention:

Vanilla HashWithIndifferentAccess is slightly more choosy than Camping's.

A quick irb session with each shows the difference.

From active_support




>> require "active_support"
=> true
>> a = HashWithIndifferentAccess.new
=> {}
>> a.apple
NoMethodError: undefined method `apple' for {}:HashWithIndifferentAccess
from (irb):4
>> a.apple "bar"
NoMethodError: undefined method `apple' for {}:HashWithIndifferentAccess
from (irb):5
>> a.apple = "bar"
NoMethodError: undefined method `apple=' for {}:HashWithIndifferentAccess
from (irb):6


From camping



>> require "camping"
=> true
>> a = HashWithIndifferentAccess.new
=> {}
>> a.apple
=> nil
>> a.apple "bar"
NoMethodError: apple
from /usr/local/lib/ruby/gems/1.8/gems/camping-1.5/lib/camping.rb:51:in `method_missing'
from (irb):5
>> a.apple = "bar"
=> "bar"


This is not a complaint, just an observation I hope will be helpful. :)

6 Comments

Daniel Berger
2007-03-26 07:08:10
Looks suspiciously like OpenStruct. What's the difference?
Greg
2007-03-26 07:16:27
Well, the active_support one is just a hash that can use strings or symbols interchangably as keys (AFAIK)


The camping one is like OStruct combined with active_support HashWithIndifferentAccess, adding a #[]



# from camping, not active_support
>> a = HashWithIndifferentAccess.new
=> {}
>> b = OpenStruct.new
=> #
>> a.foo = 10
=> 10
>> a["foo"]
=> 10
>> a[:foo]
=> 10
>> b.foo = 10
=> 10
>> b["foo"]
NoMethodError: undefined method `[]' for #
from (irb):13
Daniel Berger
2007-03-26 11:30:02
Ah, ok. OpenStruct is implemented with a Hash, so I'm actually surprised it doesn't work. I haven't looked at the source, but it looks like the easiest solution would be:

class HashWithIndifferentAccess < OpenStruct
def[](key)
send(key.to_sym)
end
end

Hm, it's not preserving whitespace. What's the markup for this site anyway? Is it linked somewhere?


Anyway, maybe there's something else it does that would prevent the use of that code.

Greg
2007-03-26 11:32:56
In ruport, I hack OpenStruct.



module Ruport
class Renderer::Options < OpenStruct
def to_hash
@table
end
end
end


But your solution is better because it preserves indifferent access.

Greg
2007-03-26 11:34:24
Oh, you don't need to_sym.


That's probably just a memory leak for no reason. :)

Daniel Berger
2007-03-26 12:28:38
Oops, yeah, get rid of the .to_sym call.