Ruby 3.2 - IO / FileUtils

Ruby 3.2 アドベントカレンダーの8日目の記事です。

qiita.com


IO

IO#timeout 追加

Feature #18630: Introduce general IO#timeout and IO#timeout= for blocking operations. - Ruby master - Ruby Issue Tracking System

IO#timeout でタイムアウトを設定できるようになった。

$stdin.timeout = 1
gets
#=> Blocking operation timed out! (IO::TimeoutError)
r, w = IO.pipe
w.timeout = 1
loop{w.write("hoge"*100)}
#=> Blocking operation timed out! (IO::TimeoutError)

Timeout.timeout とかを使わなくてもよくて便利。 Timeout.timeout は使うとスレッドを消費してしまってコストが高かったり、例外の扱いが特殊だったりするので。

IO#wait / IO#wait_readable / IO#wait_writable が組み込みになった

これ書いてて気づいたんだけど、IO#wait* メソッドが組み込みになってた。NEWS には書いてないな。 Ruby 3.1 までは require 'io/wait' しないといけなかった。

これはこれで便利。

FileUtils

FileUtils.ln_s に relative オプション追加

Feature #18925: Add FileUtils.ln_sr to create symbolic links relative to link location - Ruby master - Ruby Issue Tracking System

FileUtils には Unix のファイル操作系コマンドに似たメソッドが含まれてる。 FileUtils.ln_sln -s コマンドのようにシンボリックリンクを作成する。

require 'fileutils'
FileUtils.ln_s('/tmp/a/b/c', 'hoge')
puts File.readlink('hoge')  #=> "/tmp/a/b/c"

ln -s コマンドは普通は第1引数に指定したパスをそのまま使うけど、

% cd /tmp/a/b
% ln -s /tmp/a/b/c hoge
% ls -l hoge
lrwxrwxrwx 1 tommy tommy 10 126 22:06 hoge -> /tmp/a/b/c

ln -s-r オプションを追加すると第2引数のファイルらの相対パスが使われる。

% cd /tmp/a/b
% ln -sr /tmp/a/b/c hoge
% ls -l hoge
lrwxrwxrwx 1 tommy tommy 10 126 22:06 hoge -> c

FileUtils.ln_s にも -r と同じように振る舞う relative オプションが追加された。

require 'fileutils'
FileUtils.ln_s('/tmp/a/b/c', 'hoge', relative: true)
puts File.readlink('hoge')  #=> "c"

これと同じ振る舞いをする ln_sr メソッドも追加された。

require 'fileutils'
FileUtils.ln_sr('/tmp/a/b/c', 'hoge')
puts File.readlink('hoge')  #=> "c"