2010-03-19 19 views
6

En Perl, cuando tiene una estructura de datos anidada, se permite omitir las flechas de desreferenciación en 2d y más nivel de anidamiento. En otras palabras, los siguientes dos sintaxis son idénticos:Flechas anuladas de desreferenciación en Perl: ¿omitir o no omitir?

my $hash_ref = { 1 => [ 11, 12, 13 ], 3 => [31, 32] }; 

my $elem1 = $hash_ref->{1}->[1]; 
my $elem2 = $hash_ref->{1}[1]; # exactly the same as above 

Ahora, mi pregunta es, hay una buena razón para elegir un estilo sobre el otro?

Parece ser un hueso popular de contención estilística (Justo en SO, Accidentalmente tropecé con this y this en el espacio de 5 minutos).

Hasta ahora, casi ninguno de los sospechosos habituales dice nada definitivo:

  • perldoc se limita a decir "usted es libre de omitir el puntero de flecha eliminación de referencias".
  • Conway "Perl Best Practices" dice "siempre que sea posible, desreferencia con flechas", pero parece aplicarse únicamente al contexto de desreferenciación de la referencia principal, flechas no opcionales en el nivel 2d de estructuras de datos anidados.
  • "Mastering Perl para Bioinfirmatics" el autor James Tisdall no da preferencia muy sólido, ya sea:

    "El lector perspicaz puede tener cuenta de que parece que estamos omitiendo operadores de flecha entre matriz subíndices. (Después de todo, estos son matrices anónimas de matrices anónimas de matrices anónimas, etc., por lo que no deberían escribirse [$ array -> [$ i] -> [$ j] -> [$ k]?) Perl permite esto, solo el operador de flecha entre el nombre de la variable y se requiere el primer subíndice de matriz . Es hacer las cosas más fáciles en los ojos y ayuda a evitar el síndrome del túnel carpiano. En por otro lado, puede preferir mantener las flechas de desreferenciación en su lugar, al dejar en claro que se trata de referencias . Su elección."

  • ACTUALIZADO "Intermedio Perl", según su co-autor Brian D Foy, recomienda omitiendo las flechas. Véase la respuesta completa de Brian continuación.

Personalmente, 'm en el lado de 'poner siempre flechas en, ya que es más fácil de leer y obvio que están tratando con una referencia'

ACTUALIZACIÓN que volver más específico:. legibilidad, en el caso de una expresión de múltiples anidado wher Los propios subíndices son expresiones, las flechas ayudan a "visualizar visualmente" las expresiones al separar los subíndices entre sí.

+0

Brian - el sistema no me dijeron que actualizó su respuesta, lo siento por notar tarde. – DVK

Respuesta

13

A menos que realmente le guste teclear o líneas excesivamente largas, no use las flechas cuando no las necesite. Los subíndices junto a los subíndices implican referencias, por lo que el programador competente no necesita pistas adicionales para descubrirlo.

No estoy de acuerdo con que sea más legible tener flechas adicionales.Definitivamente no es convencional hacer que muevan las partes interesantes del término más alejadas entre sí.

En Intermediate Perl, donde enseñamos referencias, le advertimos que omita las flechas innecesarias.

Además, recuerde que no existe la "legibilidad". Solo hay lo que (y otros) han entrenado sus ojos para reconocer como patrones. No lees las cosas carácter por personaje y entiendes lo que significan. Ves grupos de cosas que has visto antes y las reconoces. En el nivel de sintaxis base del que está hablando, su "legibilidad" es solo su capacidad para reconocer patrones. Es más fácil reconocer los patrones cuanto más lo use, por lo que no es sorprendente que lo que hace ahora sea más "legible" para usted. Los nuevos estilos parecen extraños al principio, pero finalmente se vuelven más reconocibles y, por lo tanto, más "legibles".

El ejemplo que da en sus comentarios no es difícil de leer porque carece de flechas. Es todavía difícil de leer con flechas:

$expr1->[$sub1{$x}]{$sub2[$y]-33*$x3}{24456+myFunct($abc)} 
$expr1->[$sub1{$x}]->{$sub2[$y]-33*$x3}->{24456+myFunct($abc)} 

escribo ese tipo de código como este, el uso de estos tipos de nombres de variables para recordar al siguiente codificador sobre el tipo de contenedor cada nivel es:

my $index = $sub1{$x}; 
my $key1 = $sub2[$y]-33*$x3; 
my $key2 = 24456+myFunct($abc); 

$expr1->[ $index ]{ $key1 }{ $key2 }; 

Para hacerlo aún mejor, oculte los detalles en una subrutina (para eso están :), para que nunca tenga que jugar directamente con ese lío de estructura de datos. Esto es más legible que cualquiera de ellos:

my $value = get_value($index, $key1, $key2); 

    my $value = get_value(
    $sub1{$x}, 
    $sub2[$y]-33*$x3, 
    24456+myFunct($abc) 
    ); 
+0

Aunque brian no necesita mi voto, me gusta mucho el punto "partes interesantes del término". – Axeman

+0

brian - ¿Alguna información sobre mi punto hecha a Jefromi? P.ej. espaciamiento adicional entre subíndices ayuda a "tokenizarlos visualmente" - importa poco al escribir $ a -> [2] {c} pero mucho más con expresiones más complicadas como "$ expr1 -> [$ sub1 {$ x}] {$ sub2 [$ y] -33 * $ x3} {24456 + myFunct ($ abc)} "(¡NO es mi código real!) – DVK

+0

PD Totalmente no relacionado, pero ¿tienes alguna respuesta para esta pregunta de Meta? http://meta.stackexchange.com/questions/42797/randal-schwartz-on-so-but-not-in-perl – DVK

1

Siempre escribí todas las flechas. Estoy de acuerdo contigo, separan mejor los diferentes subíndices. Además uso llaves para expresiones regulares, por lo que para mí {foo}{bar} es una sustitución: s{foo}{bar} se destaca más de $s->{foo}->{bar} que de $s->{foo}{bar}.

no creo que es una gran cosa, sin embargo, el código que omite las flechas adicionales lectura no es un problema (a diferencia de cualquier sangrado que no es el que yo uso; -)

2

Desde la flecha -> no se usa de manera opcional para las llamadas a métodos, prefiero usarlo solo para llamar al código. Así que me gustaría utilizar el siguiente:

$object->method; 
$coderef->(); 
$$dispatch{name}->(); 

$$arrayref[1]; 
$$arrayref[1][5]; 
@$arrayref[1 .. 5]; 
@$arrayref; 
$$hashref{foo}; 
$$hashref{foo}{bar}; 
@$hashref{qw/foo bar/}; 
%$hashref; 

Dos sellos espalda con espalda siempre significa una falta de referencia, y la estructura sigue siendo consistente a través de todas las formas de eliminación de referencias (escalares, rebanada, todos).

También mantiene todas las partes de la variable "juntos" que me parece más fácil de leer, y es más corto :)

+0

Pero no todas las referencias tienen dos sigilos seguidos :) –

+1

Exactamente, y dado que hay opciones para la desreferenciación, y no para las llamadas a métodos ... "Creo que las metáforas visuales son muy importantes. Cómo se ve. Las cosas diferentes deberían verse diferentes. Cosas similares deberían parece similar." ~ Larry Wall. El código de llamada es muy diferente de otras formas de desreferenciación. –

+2

Considera $ {$ hash {a}} {b} y $$ hash {a} {b}, y consigue que Perler sin experiencia te explique por qué son diferentes. Es mucho más fácil hacer que esas cosas se vean diferentes con la flecha principal. Como dijo Larry, las cosas deberían ser diferentes. –