2010-06-26 10 views
8

Por ejemplo, siempre he visto métodos conocidos como String#split, pero nunca String.split, lo que parece un poco más lógico. O tal vez incluso String::split, porque podría considerar #split en el espacio de nombre String. Incluso he visto el método solo, cuando se supone/implica la clase (#split).¿Cuál es la razón/historia de la # convención de identificar métodos en Ruby?

Entiendo que esta es la forma en que se identifican los métodos en ri. ¿Cuál vino primero?

¿Esto sirve para diferenciar, por ejemplo, los métodos de los campos? También he oído que esto ayuda a diferenciar los métodos de instancia de los métodos de clase. Pero, ¿dónde comenzó esto?

+0

Quiero saber por qué esta convención no se menciona/explica en libros/tutoriales cuando se discuten las convenciones de nomenclatura de ruby. Me pareció confuso ver los nombres de métodos con el prefijo '#' en varias discusiones y solo poder adivinar qué significado tenía el prefijo. El hecho de que '#' comience un comentario en la fuente .rb lo hace doblemente confuso. Como se puede imaginar, no es lo más fácil de buscar, así que gracias por haber preguntado esto en algún lugar pude tropezar con él. Me pregunto si podré encontrarlo de nuevo cuando olvide estos detalles en 6 meses de actividad sin rubí ... –

Respuesta

8

La diferencia indica cómo acceder a los métodos.

métodos de clase utilizan el separador :: para indicar que el mensaje puede ser enviado a la clase de objeto/módulo, mientras que métodos de instancia utilizan el separador de # para indicar que el mensaje puede ser enviado a un objeto de instancia.

Voy a elegir la clase Complex (en Ruby 1.9) para demostrar la diferencia. Tiene ambos Complex::rect y Complex#rect. Estos métodos tienen diferente arity y sirven propósitos completamente diferentes. Complex::rect toma un argumento real y otro imaginario, devolviendo una nueva instancia de Complex, mientras que Complex#rect devuelve una matriz de los componentes real e imaginario de la instancia.

ruby-1.9.1-p378 > x = Complex.rect(1,5) 
=> (1+5i) 
ruby-1.9.1-p378 > x.rect 
=> [1, 5] 
ruby-1.9.1-p378 > x.rect(2, 4) # what would this even do? 
ArgumentError: wrong number of arguments(2 for 0) 
    from (irb):4:in `rect' 
    from (irb):4 
    from /Users/mr/.rvm/rubies/ruby-1.9.1-p378/bin/irb:17:in `<main>' 

creo que la razón por la que no utilizan . como separador de todo es que sería ambigua si el método pertenece a una clase o una instancia. Ahora que estoy acostumbrado a que Ruby haga esto, en realidad lo veo como un inconveniente para las convenciones de otros idiomas, para ser honesto.

Además, esto es algo de un tema totalmente sin relación de campos porque todos los mensajes se pueden enviar mensajes son, propiamente hablando, incluso si se ve como un campo de acceso público. Lo más parecido que tiene a los campos son atributos o variables de instancia, por supuesto, que siempre llevan el prefijo @ y no son directamente accesibles desde fuera de la instancia, a menos que esté usando herencia o Object#instance_variable_get/_set.

En cuanto a por qué eligieron :: y #? :: tiene sentido para mí porque separa convencionalmente espacios de nombres, pero # fue probablemente solo un símbolo que no se usó en otra nomenclatura y podría reconocerse inequívocamente como un separador de método de instancia.

+0

Ahora, para obtener puntos de bonificación: ¿por qué no utilizar '::' para * invocar * métodos de clase mientras se usa ' # 'para invocar métodos de instancia? Entonces no hay ambigüedad tanto en leer los documentos como en el código real. –

+0

@JUST: * Puedes * hacer 'Complex :: rect (1,5)'. Pero como '#' comienza un comentario de línea, no creo que este último vaya a ser adoptado pronto. –

+1

Soy consciente de esto. El punto es que todavía es bastante extraño documentar con '#' en lugar de '.'. ** Especialmente ** ya que puedes invocar con '::'. Es uno de estos misterios inefables de Ruby para mí. Como ya tenemos las reglas de prefijo '@' y '@@', ¿por qué no hacer lo mismo para los métodos y forzar (no permitir, * forzar *) los métodos de clase que se invocan con '::' y forzar (no permitir, * force *) métodos de instancia que se invocarán con '.'? –

3

Entiendo que esta es la forma en que se identifican los métodos en ri. ¿Cuál vino primero?

Sí, aquí es de donde vino. Cuando utiliza #, hipervínculos automáticamente sus métodos, por lo que las referencias a otros métodos en la documentación comenzaron a estar precedidas por el signo #.Ver here:

nombres de las clases, archivos fuente, y cualquier nombre de los métodos que contienen un subrayado o precedidas por una almohadilla, se enlaza automáticamente de texto del comentario a su descripción.

No se puede invocar un método de esta manera, sin embargo. Pero eso no debería ser sorprendente; después de todo, <cref ...> es una declaración inválida en C# a pesar de ser una etiqueta de documentación válida.

+0

¿Así que este primer lugar los métodos fueron referidos por hashes? –

+0

@Justin L .: Es lo que creó la convención, sí. –

+0

¿Esto se debía a que los archivos rdoc usaban nombres de métodos como identificadores de anclaje, y html usa # para separar el hash de ubicación del identificador de documento? –

Cuestiones relacionadas