RestClientの返り値はStringとちょっと違う
インターフェースが簡潔で使いやすいRestClientだけれども、各種HTTPメソッドの返り値をto_i
するとステータスコードを返すみたいだ。
たとえば次のようなSinatraアプリが起動していたとする。
get '/' do
"1"
end
このgetルーティングに対してRestClientでアクセスすると、次のような結果が得られる。
require "rest_client"
res = RestClient.get("http://localhost:9292/")
#=> "1"
# Stringなのにto_iはステータスコード200を返す
res.class #=> String
res.to_i #=> 200
# to_strしても変わらない
str = res.to_str #=> "1"
str.to_i #=> 200
res.class #=> String
# 期待される値はと言うと
"1".to_i #=> 1
内部でどうやっているかまでは確認できていないけど、 このようにRestClientの返り値のto_iはステータスコードを返す。
で、具体的にどんなときに不具合があるかというと、
- Web APIからRestClientを使って取得した値をActiveRecord::Base.findに渡す
- 内部的にto_iしているのか、毎回
id=200
を探しに行く - json gemによるエスケープ処理
JSON.generate([val])
が無限ループしてしまう
ではどうやっていつものStringとして扱うのかというと、Stringで包みなおせばいい。
res = RestClient("http://localhost:9292")
str = String.new(res)
str.to_i #=> 1
str.class #=> String
なんでこんな変な仕様になってるんだろう。 せめて返り値には別のクラスを使用して欲しかった。
そんな感じで、RestClientは変なところではまるので要注意。