The hashie gem provide a class
Hashie::Mash which is a subclass of Hash,
allow you use dot syntax to access value of a hash, so you can do
things like this:
>> mash = Hashie::Mash.new({:user => {:name => 'Rainux'}, :version => '0.1'})
=> <#Hashie::Mash user=<#Hashie::Mash name="Rainux"> version="0.1">
>> mash.user.name
=> "Rainux"
When I use Hashie::Mash to store data for my Rails
3 app, and use respond_with(@mash) in a
show action, it always fails since @mash
was treated as an Hash options and be extracted by
Array#extract_options!, here is the code in in
actionpack-3.0.0.beta/lib/action_controller/meta/mime_responds.rb.
def respond_with(*resources, &block)
raise "In order to use respond_with, first you need to declare the formats your " <<
"controller responds to in the class level" if self.class.mimes_for_respond_to.empty?
if response = retrieve_response_from_mimes(&block)
options = resources.extract_options!
options.merge!(:default_response => response)
(options.delete(:responder) || self.class.responder).call(self, resources, options)
end
end
Here is the code of Array#extract_options! in
activesupport-3.0.0.beta/lib/active_support/core_ext/array/extract_options.rb:
def extract_options!
last.is_a?(::Hash) ? pop : {}
end
So the question is how do we handle this kind of problems? I
think we can't just change the condition to
last.instance_of?(Hash) since another subclass of
Hash, HashWithIndifferentAccess also
widely used as options.
This problem also exists in Rails 2.