LoginSignup
12

More than 5 years have passed since last update.

Ruby open-uri の open の戻り値

Last updated at Posted at 2018-02-16

Ruby open-uri の open の戻り値

Ruby open-uri ライブラリの open メソッド

open メソッドは引数に URL を取り、通常呼び出し or ブロック呼び出しのいずれかのスタイルを取ります。

require 'open-uri'

file = open('https://hogehoge.com/image.jpg')
# 何らかの処理
file.close
require 'open-uri'

open('https://hogehoge.com/image.jpg') do |file|
  # 何らかの処理
end

open メソッド戻り値の型

ここで戻り値 (上記の場合 file) は、実は開こうとしたファイルのサイズによって、戻り値の型が以下のように変わるようです。

  • 10 kb (10,240 bytes) より大きい場合、 Tempfile
  • 10 kb (10,240 bytes) 以下の場合、 StringIO

これは結構罠で、例えば Tempfile であることを期待して file.path なんて呼んでしまうと、以下のような例外が出てしまうケースがあります。

undefined method `path' for #<StringIO:0x00005583b538edc8>

対策

なら、どうするかということで、 10kb のしきい値を決めている OpenURI::Buffer の定数 StringMax を無理やり書き換えるなんで荒業もあるようですが、いい方法とは思えません。
もし常に Tempfile であることを期待したいのであれば、素直に手動で Tempfile を作るしか無いのかなぁという、現在までの結論です。

temp_file = Tempfile.new('test_')
temp_file.binmode
open('https://hogehoge.com/image.jpg') do |file|
  # read は Tempfile でも StringIO でも duck typing でいけます。
  # 本来ならこれを handling すれば問題ないのですが、あくまで Tempfile であることを期待したい場合は...
  temp_file.write(file.read)
end
temp_file.rewind

# 何らかの処理

temp_file.close

References

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12