前提
- ruby 2.3.1
やったこと
sample1.rb
require 'active_support'
require 'active_support/core_ext/hash/slice'
{ 'key1' => 'hoge', 'key2' => 'fuga', 'key3' => 'piyo' }.slice(*%w( key1 key2 ))
#=> { "key1" => "hoge", "key2" => "fuga" }
のようにハッシュから指定したキーのみの部分ハッシュを取得したかった.
この際sliceに渡すキーを%w(...)
で指定していたつもりが下記のように%(...)
になってしまっていた
sample2.rb
require 'active_support'
require 'active_support/core_ext/hash/slice'
{ 'key1' => 'hoge', 'key2' => 'fuga', 'key3' => 'piyo' }.slice(%( key1 key2 ))
#=> { }
実行結果にもあるように,実はこれ文法エラーにならない.
区切り文字前が%のみの場合文字列として評価されてしまう.
sample3.rb
%w( a b c ) #=> ["a", "b", "c"]
%( a b c ) #=> " a b c "
なので,sample3.rbは実は下記と等価になり想定外の結果となっていたのでした.
require 'active_support'
require 'active_support/core_ext/hash/slice'
# キーを2つ指定したつもりが単なる文字列になってしまっていた...
{ 'key1' => 'hoge', 'key2' => 'fuga', 'key3' => 'piyo' }.slice(*" key1 key2 ")
#=> { }
文法上のエラーではないのでLintで気づかなくてハマった...
おまけ
日本語ドキュメントに%記法の区切り文字は%w、%W、%i、%I以外なら改行もいけると書いていたので試してみた
sample4.rb
x = %
This is a pen!
puts x
This is a pen!
これはキモい
参考
http://ruby-doc.org/core-2.3.1/doc/syntax/literals_rdoc.html#label-Percent+Strings
http://docs.ruby-lang.org/ja/2.3.0/doc/spec=2fliteral.html#percent