Ruby koan:为什么我的测试用例结果与 irb 结果不同?

问题描述 投票:0回答:1

我关注 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>

enter image description here

我的代码(通过测试用例)

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

enter image description here

为什么在源代码中,它不是

assert_equal false, symbols_as_strings.include?("test_method_names_become_symbols")
ruby
1个回答
0
投票

您所看到的差异是因为

test_method_names_become_symbols
方法名称不会自动转换为符号,直到以某种方式调用或引用它。 Ruby 解释器在使用方法名称之前不会将其作为符号进行实习。

当您调用或定义方法时,Ruby 不会立即将方法的名称转换为符号。相反,它会等到该方法被实际调用或引用为止。这意味着简单地定义方法

test_method_names_become_symbols
并不会立即为其名称创建符号。

这里有一个解释来澄清为什么你的测试通过,而公案的例子就是这样:

  1. 调用该方法之前:

    首次运行测试时,

    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")
    
  2. 调用方法后:

    如果调用

    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
中。这演示了方法名称如何在调用时变成符号的过程。

© www.soinside.com 2019 - 2024. All rights reserved.