tags:

views:

49

answers:

1

When I use ruby 1.8.7 Net::HTTP.post_form(URI.parse(URL), params), I found it has a bug, see :

http://stackoverflow.com/questions/3214502/how-to-send-an-array-with-nethttp-post-form

My code is a regular ruby script, and I want to override that method(net/http.rb#set_form_data) like this:

require 'net/http'
require 'uri'

module Net
  module HTTPHeader
    def set_form_data(params, sep = '&')
      params_array = params.map do |k,v|
        v.inject([]){|c, val| c << "#{urlencode(k.to_s)}=#{urlencode(val.to_s)}"}.join(sep)
      end
      self.body = params_array.join(sep)
      self.content_type = 'application/x-www-form-urlencoded'
    end
  end
end

res = Net::HTTP.post_form(URI.parse(URL),
                 {'type'=>'flowers',
                  'colors[]' => %w[red white blue] })

But it seems my set_form_data method has not been invoked(I debuged). Is there anything wrong in my code?

+3  A: 

You've been bit by a quirk in the way "alias" works. In net/http.rb, we find:

def set_form_data(params, sep = '&')
  ...
end

alias form_data= set_form_data

The caller is using the alias to call this method:

req.form_data = params

When you redefine the method, the alias is still stuck to the original definition, so your redefined method never gets called. To get around this, you can re-do the alias after redefining the method:

module Net
  module HTTPHeader
    def set_form_data(params, sep = '&')
      ..
    end
    alias form_data= set_form_data
  end
end
Wayne Conrad
@Wayne, thank you!!
Freewind