Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Array#extract_options! treat Hashie::Mash data as options

#4145

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.

Reported by Rainux · March 10th, 2010 @ 01:40 PM

State: resolved
Milestone: none
Assigned to: Yehuda Katz (wycats) Yehuda Katz (wycats)
Importance: none

Activity

  1. Repository
    Repository
    • State changed from new to resolved

    (from [a24a888afe5652e391ce2ea682596686af5ec58b]) Limit Array#extract_options! to directl instances of Hash and HWIA. Add extractable_options? to Hash so that subclasses of Hash can opt-into extractable behavior. This fixes an issue where respond_with wasn't working with subclasses of Hash that were provided by other libraries (such as CouchDB or Mashie) [#4145 Array#extract_options! treat Hashie::Mash data as options state:resolved] http://github.com/rails/rails/commit/a24a888afe5652e391ce2ea6825966...

    March 27th, 2010 @ 09:59 AM