2011-03-18 2 views
11

В about_symbols.rb Руби Коана (https://github.com/edgecase/ruby_koans), у меня есть следующий код:Рубин Koan: Константы становятся символами

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 было показать, что константы становятся символами (по крайней мере, это то, что я выводил из метода имя). Поскольку RubyConstant является константой со значением "What is the sound of one hand clapping?", почему в список символов не входит "What is the sound of one hand clapping?".to_sym? Единственное объяснение, о котором я могу думать, это то, что, вопреки имени метода, константы на самом деле не становятся символами.

Благодарим за помощь!

+0

Этот вопрос задан здесь: http: //stackoverflow.com/questions/13295776/ruby-koans-75-test-constants-become-symbols-correct-answer? Lq = 1 – ZenBalance

ответ

7

hoha имеет право, но я попытаюсь немного расширить и уточнить.

Интерпретатор создает символ :nonexistent, когда он анализирует test_constants_become_symbols. Затем, когда вы запустите его, вызывается 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 clapping?" символ не будет видно анализатором и поэтому он не будет в all_symbols массиве. Вызов метода .to_sym в следующей строке выполняется, когда выполняется test_constants_become_symbols; Итак, :"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 может помочь вам разобраться, что происходит.

+0

Насколько я знаю, суть этого Ruby Koan должен был продемонстрировать, что константы становятся символами (по крайней мере, это то, что я выводил из имени метода). Поскольку RubyConstant объявлен, почему это не '' Какое звучание одной руки хлопает? ". To_sym' включен в список символов? Единственное объяснение, о котором я могу думать, это то, что, вопреки имени метода, константы на самом деле не становятся символами. Есть предположения? – dskang

+13

Это не значение константы, которая становится символом. Это имя константы. Итак, 'Symbol.all_symbols.include? : RubyConstant' будет правдой. –

+2

_name_ константы становится символом, но не _value_ константы. Попробуйте это: 'Zoo =" Zee "; p Symbol.all_symbols.grep (/^Z /) # => [: ZeroDivisionError,: Zoo] ' – Phrogz

3

Я не гуру Ruby, но похоже, что интерпретатор создал эти символы во время оценки выражения def. Вот почему эти символы уже существуют, когда вы вызываете Symbol.all_symbols. Третий assert не работает, а второй закомментирован, потому что "string".to_sym создает символ во время выполнения методов, т. Е. После того, как вы получили доступные символы с all_symbols = Symbol.all_symbols.

Смежные вопросы