Ruby Koan:常数成为符号

在about_symbols.rb Ruby Koan(https://github.com/edgecase/ruby_koans)中,我有以下代码:

RubyConstant = "What is the sound of one hand clapping?" def test_constants_become_symbols all_symbols = Symbol.all_symbols assert_equal true, all_symbols.include?(:"nonexistent") assert_equal true, all_symbols.include?(:"What is the sound of one hand clapping?") assert_equal true, all_symbols.include?("What is the sound of one hand clapping?".to_sym) end 

按原样,测试通过。

三个问题:

  1. 为什么第一个断言通过? :"nonexistent"不应该包括在all_symbols中,但它包括在内,所以我必须误解一些东西。

  2. 当我注释掉第二个断言时,测试失败了,因为"What is the sound of one hand clapping?".to_sym不包含在all_symbols中,而是:"What is the sound of one hand clapping?" 已经包括了。 既然它们是等价的,为什么最后一个断言失败了? 另外,为什么第二个断言未被注释时它会通过? (为什么第二个断言对第三个断言有影响?)

  3. 据我所知,这个Ruby Koan的观点是certificate常量成为符号(至少,这是我从方法名称推断的)。 因为RubyConstant是一个常数,其值为"What is the sound of one hand clapping?" ,为什么不是"What is the sound of one hand clapping?".to_sym包含在符号列表中? 我能想到的唯一解释是,与方法名称相反,常量实际上不会成为符号。

谢谢你的帮助!

hoha说的没错,但我会尝试扩展并澄清一下。

解析器在解析test_constants_become_symbols时将创建:nonexistent符号。 然后,当您运行它时,将调用Symbol.all_symbols以获取所有已知符号的列表,并且:nonexistent列表中:nonexistent 。 另请注意, "nonexistent"上的双引号是语法问题而不是内部表示问题,因此:nonexistent:"nonexistent"是相同的事情。

如果你注释掉这个:

  assert_equal true, all_symbols.include?(:"What is the sound of one hand clapping?") 

那么:"What is the sound of one hand clapping?" 解析器不会看到符号,因此它不会出现在all_symbols数组中。 执行test_constants_become_symbols ,执行以下行上的.to_sym方法调用; 所以, :"What is the sound of one hand clapping?" 获得all_symbols后创建符号,这将失败:

  assert_equal true, all_symbols.include?("What is the sound of one hand clapping?".to_sym) 

如果你在同一个解释器实例中再次执行test_constants_become_symbols (第二个assert_equal仍然被注释掉),那么两个未注释的assert_equal调用将在第一次运行时通过test_constants_become_symbols将创建:"What is the sound of one hand clapping?" 第二个Symbol.all_symbols将它包含在返回的数组中。

irb运行代码而不将其包装在def可能有助于您了解正在发生的事情。

我不是Ruby大师,但看起来解释器在def表达式评估期间创建了这个符号。 这就是当你调用Symbol.all_symbols时这些符号已经存在的原因。 第三个assert失败,第二个被注释掉,因为"string".to_sym在方法执行期间创建符号,即在获得带有all_symbols = Symbol.all_symbols符号all_symbols = Symbol.all_symbols