yucatio@システムエンジニア

趣味で作ったものいろいろ

Rubyでは、メソッド引数のカッコはメソッド名の直後に書くこと。空白を入れちゃだめ

引き続き、『プロを目指す人のためのRuby入門』(伊藤淳一[著])を読んでいます。

問題発生

本の中のコードを(間違って)写して、下記を実行したところ、

class DeepFreezableTest < Minitest::Test
  def test_deep_freeze_to_hash
    # ハッシュの値は正しいか
    assert_equal (
        {'Japan' => 'yen', 'US' => 'dollar', 'India' => 'rupee'},
        Bank::CURRENCIES
    )
  end
end
syntax error, unexpected ',', expecting ')' (SyntaxError)

ハッシュの直後にあるカンマで文法エラーが発生しました。

解決方法

assert_equal(の間の空白(半角スペース)を削除する

class DeepFreezableTest < Minitest::Test
  def test_deep_freeze_to_hash
    # ハッシュの値は正しいか
    assert_equal(
        {'Japan' => 'yen', 'US' => 'dollar', 'India' => 'rupee'},
        Bank::CURRENCIES
    )
  end
end

なぜエラーが発生したのか

assert_equalとメソッド引数のカッコに半角スペースを入れたことにより、({'Japan' => 'yen', 'US' => 'dollar', 'India' => 'rupee'}, Bank::CURRENCIES)全体が1つ目の引数と解釈されてしまいました。どうやら、メソッド名の後に空白があるとメソッド呼び出しのカッコが省略されたと解釈されるらしいです。

{'Japan' => 'yen', 'US' => 'dollar', 'India' => 'rupee'}, Bank::CURRENCIES自体は式として解釈されないので、文法エラーになりました。

あとがき

空白の有無でSyntaxErrorになってしまうのは予想外でした。 エラーが出た時にtypoかと思って本と見比べるも、空白の有無は見逃してしまい、解決に時間がかかってしまいました。 RubyMineでこの文法エラーとしては表示されませんでした。よく見たら警告出てました。見逃してました。

f:id:yucatio:20180617171129p:plain

googleでエラーメッセージを検索しましたが、なにせ記号が入っているため、別のエラーメッセージが検索結果に出てしまい、なかなか同じエラーメッセージが出ているページにたどり着けなかったです。

色々試した結果、解決してよかったです。どんなエディタでも空白文字を表示しておくのはおすすめです。

yucatio.hatenablog.com

補足

念のため書いておきますが、本に書いてあるコードを間違わずに写せばエラーは出ません。

環境