我关注 ruby koan https://github.com/edgecase/ruby_koans/blob/master/src/about_symbols.rb#L26-L29
我的IRB
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
方法名称不会自动转换为符号,直到以某种方式调用或引用它。 Ruby 解释器在使用方法名称之前不会将其作为符号进行实习。
当您调用或定义方法时,Ruby 不会立即将方法的名称转换为符号。相反,它会等到该方法被实际调用或引用为止。这意味着简单地定义方法
test_method_names_become_symbols
并不会立即为其名称创建符号。
这里有一个解释来澄清为什么你的测试通过,而公案的例子就是这样:
调用该方法之前:
首次运行测试时,
Symbol.all_symbols
不包括"test_method_names_become_symbols"
,因为该方法尚未被调用或引用。
symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
assert_equal false, symbols_as_strings.include?("test_method_names_become_symbols")
调用方法后:
如果调用
test_method_names_become_symbols
,则方法的名称将被保留为符号。因此,再次运行 Symbol.all_symbols
将包含 "test_method_names_become_symbols"
。
以下是如何修改测试以使其更加明确:
in_ruby_version("mri") do
def test_method_names_become_symbols
symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
# Before the method is called, it should not be included
assert_equal false, symbols_as_strings.include?("test_method_names_become_symbols")
# Now, call the method to intern the symbol
test_method_names_become_symbols_internal
symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
# After the method is called, it should be included
assert_equal true, symbols_as_strings.include?("test_method_names_become_symbols_internal")
end
def test_method_names_become_symbols_internal
# This is the method being checked
end
end
在此示例中,在
test_method_names_become_symbols_internal
内调用 test_method_names_become_symbols
,确保符号被保留并包含在 Symbol.all_symbols
中。这演示了方法名称如何在调用时变成符号的过程。