open-uriはとても便利。

Rubyに標準でついてくるopen-uriは大変理解しやすく、たった1行でHTTP通信をそつなく書けるのが魅力です。
ですが、残念なことにコードを読むとGETメソッドによるリクエストしかできないようになっています。

そこで調べてみた。

kitajさんの記事で知ったopen-uri-post.rbが素敵です。
ちょっとコードを足せば機能を補充できる動的言語ならではの解決策。

でも、RESTなWeb APIをペシペシ叩きたくなって、PUTやらDELETEやらHEADやらをサポートしようと改造したりしてみたのですが、調べているうちに素敵なパッチ発見。
これをopen-uri.rbに適用してみたら、open-uriでHTTPのリクエストメソッドが全て使えるようになりました

サンプルコード:

require 'open-uri'
open('http://example.com', {:method => :post, :body => 'a=123&b=456' }) {|f|
  puts f.read
}

:put, :delete, や :headも利用できます。

ちなみに

パッチを当てたコードを見ると、Methodsの初期化がやや冗長になっています。
Methods = {
  :copy => Net::HTTP::Copy,
  :delete => Net::HTTP::Delete,
  :get => Net::HTTP::Get,
  ...(snip)...
  :unlock => Net::HTTP::Unlock,
}
なので、こんな書き方どう?みたいなコメントが出てます。
method_classes = Net::HTTP.constants.map {|m|
Net::HTTP.const_get(m)
}.select {|c|
c.is_a? Class and c.ancestors.include? Net::HTTPRequest
}
Methods = Hash[*method_classes.inject([]) {|a,m|
a.push m.to_s.split("::").last.downcase.to_sym, m
}]
Net::HTTPRequestに書かれているから全部もってこい、と。

参考までにパッチのあて方の例。

僕の環境はRuby 1.8で、以下にインストールされていますので、以下のようにしました。
$ cd ~/
$ wget http://rubyforge.org/tracker/download.php/426/1700/6321/890/diff-1.8
$ cd /usr/lib/ruby/1.8/
$ patch open-uri.rb ~/diff-1.8

元に戻したくなったら、バックアップされたopen-uri.rb.origがあると思うので、そいつでopen-uri.rbを上書きするなどしてみてください。