2011-03-18 12 views
11

En la about_symbols.rb Rubí Koan (https://github.com/edgecase/ruby_koans), tengo el siguiente código:Rubí Koan: Constantes convertido en símbolos

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 

Como es, la prueba pasa.

tres preguntas:

  1. ¿Por qué pasar la primera aserción? :"nonexistent" no debe incluirse en all_symbols, pero está incluido, así que debo estar malinterpretando algo.

  2. Cuando comente la segunda afirmación, la prueba falla porque "What is the sound of one hand clapping?".to_sym no está incluido en all_symbols, mientras que :"What is the sound of one hand clapping?" está incluido. Como son equivalentes, ¿por qué falla la última afirmación? Además, ¿por qué pasa cuando la segunda afirmación no está comentada? (¿Por qué la segunda afirmación tiene algún efecto en la tercera afirmación?)

  3. Que yo sepa, el objetivo de este Ruby Koan era demostrar que las constantes se convierten en símbolos (al menos, eso es lo que estoy deduciendo del método nombre). Dado que RubyConstant es una constante con el valor "What is the sound of one hand clapping?", ¿por qué no se incluye "What is the sound of one hand clapping?".to_sym en la lista de símbolos? La única explicación que se me ocurre es que, contrariamente al nombre del método, las constantes no se convierten en símbolos.

¡Gracias por su ayuda!

+0

La misma pregunta hecha aquí: http: //stackoverflow.com/questions/13295776/ruby-koans-75-test-constants-become-symbols-correct-answer? Lq = 1 – ZenBalance

Respuesta

7

hoha tiene razón, pero trataré de ampliar y aclarar un poco.

El intérprete creará el símbolo :nonexistent al analizar test_constants_become_symbols. Luego, cuando lo ejecuta, se llama al Symbol.all_symbols para obtener una lista de todos los símbolos conocidos y :nonexistent está en la lista. También tenga en cuenta que las comillas dobles en "nonexistent" son un problema de sintaxis en lugar de un problema de representación interna por lo que :nonexistent y :"nonexistent" son lo mismo.

Si usted comenta a cabo éste:

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

entonces el símbolo :"What is the sound of one hand clapping?" no será visto por el analizador y lo que no habrá en la matriz all_symbols. La llamada al método .to_sym en la siguiente línea se ejecuta cuando se ejecuta test_constants_become_symbols; así, el símbolo :"What is the sound of one hand clapping?" se crea después de obtener su all_symbols y esto va a fracasar:

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

Si ejecuta test_constants_become_symbols de nuevo en la misma instancia intérprete (con la segunda assert_equal siendo comentada) y luego pasarán ambos sin comentar assert_equal llamadas como la primera ejecución a través de test_constants_become_symbols creará el :"What is the sound of one hand clapping?" y el segundo Symbol.all_symbols lo incluirá en la matriz devuelta.

Ejecutando su código en irb sin envolverlo en un def podría ayudarlo a ver qué está pasando.

+0

Que yo sepa, el objetivo de esto Ruby Koan debía demostrar que las constantes se convierten en símbolos (al menos, eso es lo que estoy deduciendo del nombre del método). Como se declara RubyConstant, ¿por qué no está '" ¿Cuál es el sonido de una mano que aplaude? ". ¿To_sym' está incluido en la lista de símbolos? La única explicación que se me ocurre es que, contrariamente al nombre del método, las constantes no se convierten en símbolos. ¿Alguna idea? – dskang

+13

No es el valor de la constante lo que se convierte en un símbolo. Es el nombre de la constante. Entonces 'Symbol.all_symbols.include? : RubyConstant' sería cierto. –

+2

El _name_ de la constante se convierte en un símbolo, pero no en el _valor_ de la constante. Intenta esto: 'Zoo =" Zee "; p Symbol.all_symbols.grep (/^Z /) # => [: ZeroDivisionError,: Zoo] ' – Phrogz

3

No soy un gurú de Ruby pero parece que el intérprete creó estos símbolos durante la evaluación de la expresión def. Es por eso que estos símbolos ya están allí cuando llamas al Symbol.all_symbols. El tercero assert falla y el segundo se comenta porque "string".to_sym crea un símbolo durante la ejecución de los métodos, es decir, después de obtener símbolos disponibles con all_symbols = Symbol.all_symbols.