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:
-
Why does the first assert pass?
:"nonexistent"should not be included in all_symbols but it is included so I must be misunderstanding something. -
When I comment out the second assert, the test fails because
"What is the sound of one hand clapping?".to_symis 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?) -
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_symincluded 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!
hoha has it right but I’ll try to expand and clarify a bit.
The interpreter will create the
:nonexistentsymbol when it parsestest_constants_become_symbols. Then, when you run it,Symbol.all_symbolsis called to get a list of all known symbols and:nonexistentis in the list. Also note that the double quotes on"nonexistent"are a syntax issue rather than an internal representation issue so:nonexistentand:"nonexistent"are the same thing.If you comment out this one:
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 theall_symbolsarray. The.to_symmethod call on the following line is executed whentest_constants_become_symbolsis executed; so, the:"What is the sound of one hand clapping?"symbol is created after you get yourall_symbolsand this will fail:If you execute
test_constants_become_symbolsagain in the same interpreter instance (with the secondassert_equalstill commented out) then both uncommentedassert_equalcalls will pass as the first run throughtest_constants_become_symbolswill create the:"What is the sound of one hand clapping?"and the secondSymbol.all_symbolswill include it in the returned array.Running your code in
irbwithout wrapping it in adefmight help you see what’s going on.