Ruby 2.7 アドベントカレンダーの24日目の記事です。
StringScanner とか CSV は Ruby の標準ライブラリだけど本体の外で開発されているやつで、NEWSを見ても詳しくは書いてなかったので、調べてみました。
StringScanner
fixed anchor モード
StringScanner.new 時に fixed_anchor: true
を指定すると、\A
が現在の位置ではなく文字列の先頭にマッチするようになります。
require 'strscan' ss = StringScanner.new("hogefuga") ss.fixed_anchor? #=> false ss.scan(/hoge/) #=> "hoge" ss.scan(/\Afuga/) #=> "fuga" ss = StringScanner.new("hogefuga", fixed_anchor: true) ss.fixed_anchor? #=> true ss.scan(/hoge/) #=> "hoge" ss.scan(/\Afuga/) #=> nil
open-uri
Kernel.open で warning
open-uri ライブラリが拡張する Kernel.open
メソッド(URI.open
じゃなくてただの open
)で URL を開く時に warning が表示されるようになりました。
URI.open
を使いましょう。
require 'open-uri' open("http://example.com") #=> warning: calling URI.open via Kernel#open is deprecated, call URI.open directly or use URI#open URI.open("http://example.com") #=> warning が出ない
text/* のデフォルトの charset が UTF-8 に
open-uri で、Content-Type が text/* で charset 持たないデータを読んだ時に、エンコーディングが ASCII-8BIT になっていたのが UTF-8 になりました。
試してみます。
テキトーなテキストファイルを作って、
% echo abcdefg > a.txt % ruby -run -e httpd [2019-12-24 22:03:40] INFO WEBrick 1.4.2 [2019-12-24 22:03:40] INFO ruby 2.6.5 (2019-10-01) [x86_64-linux] [2019-12-24 22:03:40] INFO WEBrick::HTTPServer#start: pid=19499 port=8080
HTTP でアクセスすると charset を返さない状態で、
% curl -D- http://127.0.0.1:8080/a.txt HTTP/1.1 200 OK Etag: 721245-8-5e020c13 Content-Type: text/plain Content-Length: 8 Last-Modified: Tue, 24 Dec 2019 13:01:07 GMT Server: WEBrick/1.4.2 (Ruby/2.6.5/2019-10-01) Date: Tue, 24 Dec 2019 13:05:09 GMT Connection: Keep-Alive abcdefg
open-uri でアクセスすると、
require 'open-uri' URI.open("http://127.0.0.1:8080/a.txt").read.encoding # 2.6 => #<Encoding:ASCII-8BIT> # 2.7 => #<Encoding:UTF-8>
2.6 では ASCII-8BIT、2.7 では UTF-8 になってます。
CSV
quote_empty オプション
真の場合は空の値を "
で括ります。偽の場合は括りません。デフォルトは true
。
require 'csv' CSV.new($stdout).puts ["a", "", "z"] #=> a,"",z CSV.new($stdout, quote_empty: true).puts ["a", "", "z"] #=> a,"",z CSV.new($stdout, quote_empty: false).puts ["a", "", "z"] #=> a,,z
write_converters オプション
Procオブジェクトを指定すると、それを使用して値を変換します。配列で複数の Proc を指定することができます。
require 'csv' CSV.new($stdout, write_converters: ->(s){s.upcase}).puts ["a", "b", "c"] #=> A,B,C CSV.new($stdout, write_converters: [->(s){s.upcase}, ->(s){s*2}]).puts ["a", "b", "c"] #=> AA,BB,CC
write_nil_value オプション
値が nil
の場合に出力する文字列を指定します。
require 'csv' CSV.new($stdout, write_nil_value: "NULL").puts ["a", nil, "z"] #=> a,NULL,z
write_empty_value オプション
値が空の場合に出力する文字列(またはnil
)を指定します。
require 'csv' CSV.new($stdout).puts ["a", "", "z"] #=> a,"",z CSV.new($stdout, write_empty_value: "---").puts ["a", "", "z"] #=> a,---,z CSV.new($stdout, write_empty_value: nil).puts ["a", "", "z"] #=> a,,z
strip オプション
真を指定すると " \t\f\v" を削除します。文字を指定するとその文字を削除します。
require 'csv' CSV.parse(" value1 , value2 ") #=> [[" value1 ", " value2 "]] CSV.parse(" value1 , value2 ", strip: true) #=> [["value1", "value2"]] CSV.parse("===value1===,===value2===", strip: "=") #=> [["value1", "value2"]]