Techioz Blog

Ruby koan: テスト ケースの結果が IRB の結果と異なるのはなぜですか?

概要

Ruby Koan https://github.com/edgecase/ruby_koans/blob/master/src/about_symbols.rb#L26-L29 をフォローしています

私の診断書

irb(main):006> symbols_as_strings.include?("test_method_names_become_symbols")
=> false
irb(main):007> symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
=>
["!",
...
irb(main):008> symbols_as_strings.include?("test_method_names_become_symbols")
=> false
irb(main):009>

私のコード (パステストケース)

def test_method_names_become_symbols
  symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
  assert_equal true, symbols_as_strings.include?("test_method_names_become_symbols")
end

なぜソースコードではそうではないのか

assert_equal false, symbols_as_strings.include?("test_method_names_become_symbols")

解決策

コードは、:test_method_names_become_symbols シンボルの存在をチェックします。 irb で false が返された場合は、:test_method_names_become_symbols シンボルが定義されていないことが原因です。

symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
symbols_as_strings.include?("test_method_names_become_symbols")
#=> false

事前に定義すると、true が返されます。

:test_method_names_become_symbols

symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
symbols_as_strings.include?("test_method_names_become_symbols")
#=> true

メソッド定義をスキップしているため、irb のコードはテストとは異なる動作をします。メソッドを定義すると、対応するシンボルも作成され、メソッド定義の結果としても返されます。

def test_method_names_become_symbols
end
#=> :test_method_names_become_symbols

symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
symbols_as_strings.include?("test_method_names_become_symbols")
#=> true

また、シンボルはメソッド定義の先頭に作成されるため、メソッド内でコードを実行することもできます。

def test_method_names_become_symbols
  symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
  symbols_as_strings.include?("test_method_names_become_symbols")
end

test_method_names_become_symbols
#=> true