Ruby Koan:常量变成符号

发布于 2024-10-24 04:51:03 字数 1077 浏览 3 评论 0原文

在 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. 当我注释掉第二个断言时,测试失败,因为 "一只手拍手的声音是什么?".to_sym 未包含在 all_symbols 中,而 :"What is the sound一只手拍手?”包括在内。既然它们是等价的,为什么最后一个断言会失败呢?另外,为什么当第二个断言没有注释掉时它会通过? (为什么第二个断言对第三个断言有影响?)

  3. 据我所知,这个 Ruby Koan 的目的是证明常量变成了符号(至少,这是我从方法名称中推断出来的) 。由于 RubyConstant 是一个值为 “一只手拍手的声音是什么?” 的常量,为什么不是 “一只手拍手的声音是什么?”.to_sym 包含在符号列表中吗?我能想到的唯一解释是,与方法名称相反,常量实际上不会变成符号。

感谢您的帮助!

In the about_symbols.rb Ruby Koan (https://github.com/edgecase/ruby_koans), I have the following code:

    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

As is, the test passes.

Three questions:

  1. Why does the first assert pass? :"nonexistent" should not be included in all_symbols but it is included so I must be misunderstanding something.

  2. When I comment out the second assert, the test fails because "What is the sound of one hand clapping?".to_sym is not included in all_symbols whereas :"What is the sound of one hand clapping?" is included. Since they are equivalent, why does the last assert fail? Also, why does it pass when the second assert is not commented out? (Why does the second assert have any effect on the third assert?)

  3. To my knowledge, the point of this Ruby Koan was to demonstrate that constants become symbols (at least, that's what I'm inferring from the method name). Since RubyConstant is a constant with the value "What is the sound of one hand clapping?", why isn't "What is the sound of one hand clapping?".to_sym included in the list of symbols? The only explanation that I can think of is that, contrary to the method name, constants do not in fact become symbols.

Thanks for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦年海沫深 2024-10-31 04:51:03

哈哈说得对,但我会尝试扩展和澄清一下。

解释器在解析 test_constants_become_symbols 时将创建 :nonexistent 符号。然后,当您运行它时,将调用 Symbol.all_symbols 以获取所有已知符号的列表,并且 :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 laplap?" 符号,因此它不会出现在 all_symbols< /代码> 数组。当执行test_constants_become_symbols时,会执行下面一行的.to_sym方法调用;因此,在获得 all_symbols 后,将创建 :"What is the sound of one hand laplaps?" 符号,这将失败:

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

如果执行 test_constants_become_symbols< /code> 再次在同一个解释器实例中(第二个 assert_equal 仍被注释掉),然后两个未注释的 assert_equal 调用将作为第一次运行通过 test_constants_become_symbols 传递code> 将创建 :"What is the sound of one hand laplaps?" ,第二个 Symbol.all_symbols 会将其包含在返回的数组中。

irb 中运行代码而不将其包装在 def 中可能会帮助您了解发生了什么。

hoha has it right but I'll try to expand and clarify a bit.

The interpreter will create the :nonexistent symbol when it parses test_constants_become_symbols. Then, when you run it, Symbol.all_symbols is called to get a list of all known symbols and :nonexistent is in the list. Also note that the double quotes on "nonexistent" are a syntax issue rather than an internal representation issue so :nonexistent and :"nonexistent" are the same thing.

If you comment out this one:

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

then the :"What is the sound of one hand clapping?" symbol will not be seen by the parser and so it won't be in the all_symbols array. The .to_sym method call on the following line is executed when test_constants_become_symbols is executed; so, the :"What is the sound of one hand clapping?" symbol is created after you get your all_symbols and this will fail:

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

If you execute test_constants_become_symbols again in the same interpreter instance (with the second assert_equal still commented out) then both uncommented assert_equal calls will pass as the first run through test_constants_become_symbols will create the :"What is the sound of one hand clapping?" and the second Symbol.all_symbols will include it in the returned array.

Running your code in irb without wrapping it in a def might help you see what's going on.

幸福不弃 2024-10-31 04:51:03

我不是 Ruby 专家,但看起来解释器在 def 表达式求值期间创建了这个符号。这就是为什么当您调用 Symbol.all_symbols 时这些符号已经存在。第三个 assert 失败,第二个被注释掉,因为 "string".to_sym 在方法执行期间创建符号,即在使用 all_symbols = Symbol.all_symbols< 获得可用符号之后/代码>。

I'm not a Ruby guru but it looks like interpreter created this symbols during def expression evaluation. That's why these symbols are already there when you call Symbol.all_symbols. Third assert fails with second one being commented out because "string".to_sym creates symbol during methods execution i.e. after you got available symbols with all_symbols = Symbol.all_symbols.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文