2010-01-09 11 views
12

Soy un principiante Ruby. Del libro, sé que un nombre de método Ruby debe comenzar con una letra minúscula o un guión bajo. Pero me encontré con diferentes escenarios:¿Cuáles son las reglas mayúsculas y minúsculas del nombre del método ruby?

  1. Si se define un método fuera de una clase, sólo puede comenzar con letra minúscula, Ruby se quejará con un error si se intenta definir un método que comienza con una letra mayúscula, por ejemplo:

    define sayHi 
        puts "Hello" 
    end 
    sayHi # => Hello 
    

    , pero el siguiente código no funciona:

    define SayHi 
        puts "Hello" 
    end 
    SayHi 
    

    se producirá un error: 0

    :in `<main>': uninitialized constant SayHi (NameError) 
    
  2. Si un método está definido dentro de una clase, entonces se puede comenzar con letra mayúscula:

    class Test 
        def SayHi 
        puts "hello" 
        end 
    end 
    t = Test.new 
    t.SayHi # => hello 
    

¿Alguien sabe por qué # 1 no funciona mientras que # 2 trabajo? ¿Cuáles son las reglas exactas del nombre del método Ruby?

Respuesta

23

Por convención, las cosas que comienzan con letras mayúsculas son constantes. Cuando invoca SayHi, le está diciendo a Ruby que busque una constante con este nombre. Por supuesto, no hay uno, entonces falla.

Si desea invocar el método, deberá agregar un par de paréntesis. Por ejemplo,

def S 
    puts "shazam!" 
end 

S #=> NameError: uninitialized constant S 
S() #=> "shazam!" 

Dentro de una clase, las reglas de resolución son un poco diferentes. Vamos a definir una clase simple con una constante y un método llamado para parecerse a una constante:

irb(main):001:0> class C 
irb(main):002:1> A = "x" 
irb(main):003:1> def B 
irb(main):004:2>  puts "B() invoked" 
irb(main):005:2> end 
irb(main):006:1> end 
=> nil 

Ahora, A es sin duda una constante. Pero ¿qué pasa con B?

irb(main):008:0> C.const_defined?("A") 
=> true # A is a constant! 
irb(main):009:0> C.const_defined?("B") 
=> false # B looks like a constant but isn't, because we 
      # used "def" to create it. "def" is for methods, 
      # not constants. 

Así que no es una constante, solo un método con ese nombre. Cuando tratamos de acceso B desde una instancia de C, Ruby ahora está buscando un método:

irb(main):011:0> C.new.B 
B() invoked 
=> nil 

Si quisiéramos acceder a una constante de C lugar, se utiliza el calificador de ámbito :::

irb(main):012:0> C::A 
=> "x" 
+0

Bastante nuevo para ruby, y esto también es útil para mí. Excelentemente explicado. +1 –

+0

Gracias John, aprendí mucho de tu respuesta. –

1

No hagas nada de lo que intentas hacer. Es un mal estilo de codificación.

buen estilo de programación Ruby:

def method_name 
end 

# or 

class CamelCase 
    def method_name(parameter_name) 
    end 
end 

Casi todo lo demás es simplemente errónea. El idioma puede dejarte hacer otras cosas, pero eso no significa que debas hacerlo.

Además, generalmente no desea definir métodos fuera de una clase o módulo; eso es aceptable en scripts cortos, pero no en proyectos de fondo.

+0

¿Tal vez emend "fuera de una clase" a "fuera de una clase o módulo"? No * todo * tiene sentido en una clase: a veces tiene un conjunto de métodos que encajan, pero no tiene ninguna razón para crear instancias para esos métodos. – Telemachus

+4

En realidad, los métodos que comienzan con letras mayúsculas son bastante comunes e incluso forman parte de las bibliotecas principales y bibliotecas estándar, por ejemplo, el método 'Array',' Hash', 'Integer',' Float', 'String' en la biblioteca principal y 'DelegateClass' en la biblioteca' delegate'. No es para nada un "mal estilo de codificación", sino todo lo contrario. En realidad, es la manera correcta de definir métodos que devuelven 'Class' es o' Module' s, que luego se pretende que sean 'include' d,' extended'ed o heredados. –

+0

Es verdad, pero seamos claros, esos no son casos de uso comunes. Este es un chico nuevo, y no va a escribir métodos que devuelvan clases o módulos pronto. Si bien he usado algunos de ellos, no creo que haya encontrado una buena razón para escribir uno. –

Cuestiones relacionadas