2009-09-23 12 views
9

En Perl, ¿cuál de estos es el "mejor" estilo?

$hash{"string"} or $hash{string}? 

En cualquier caso, ¿son la funcionalidad idéntica?

+1

En Perl, romper las reglas de estilo es un buen estilo! – Artelius

+2

La primera versión funciona mejor con el código pegado en Stack Overflow. –

+4

¿Por qué te importa? De Verdad. Seguramente debe haber cosas mejores de las que preocuparse en su código. No me importa cuál gente use siempre y cuando sus cosas funcionen. –

Respuesta

13

De perldata perldoc:

De hecho, un identificador dentro de tales curlies se ve obligado a ser una cadena, como lo es cualquier identificador sencilla dentro de un subíndice hash. Tampoco es necesario citar. Nuestro ejemplo anterior, $days{'Feb'} se puede escribir como $days{Feb} y las cotizaciones se asumirán automáticamente. Pero cualquier cosa más complicada en el subíndice se interpretará como una expresión. Esto significa por ejemplo que $version{2.0}++ es equivalente a $version{2}++, no $version{'2.0'}++

Así que sí fundamentalmente idéntica. Sin embargo ten cuidado con los aspectos críticos:

sub is_sub { 'Yep!' } 

my %hash; 
$hash{ is_sub } = 'Nope'; 
$hash{ is_sub() } = 'it is_sub!!'; 

say Dumper \%hash; 

mostrará:

$VAR1 = { 'is_sub' => 'Nope', 'Yep!' => 'it is_sub!!' }; 

Mi preferencia es para el bareword ... pero recuerde los() o a + precedente (véase el comentario y la respuesta de jrockway) si' re llamar a un sub ;-)

+0

Su ejemplo con respecto a '$ version {2.0}' frente a '$ version {'2.0'}' me resulta confuso considerando esto: 'perl -e '$ foo { '2.0'} = 1; print $ foo {'2'} ++, $ foo {2} ++, $ foo {2.0} ++, $ foo {1 + 1} ++, "\ n"; ' ' El valor de las llaves se evalúa en un escalar y ese escalar se usa como clave. Por lo tanto, tengo que suponer que no has probado tu ejemplo o que me falta algo sutil en lo que intentas ing decir. (Para mí imprime * 1234 *) –

+0

Lamentablemente su ejemplo es incorrecto. En realidad, me sorprende que haya analizado bien. Estás usando comillas simples en -e y en el índice hash. De todos modos, si compruebas los valores hash de $ foo después de la configuración, obtienes {'2.0' => 1, '2' => 4} ... que es la respuesta que esperarías ver – draegtun

+0

También puedes escribir + función en lugar de función(). – jrockway

12

Funcionalmente idénticos, es decir hasta que la llave tenga un espacio o algún otro carácter no alfanumérico. Entonces tienes que usar el enfoque citado.

Prefiero no citar y usar nombres que contengan alpha_num y el guión bajo. Eso me permite salirse con la suya sin citar la mayor parte del tiempo.

+3

No son funcionalmente idénticos. En ciertos casos, obtienes el mismo resultado, pero no por la misma razón. –

+1

La pregunta era si $ hash {"string"} es idéntico a $ hash {string}, que es. –

4

El último formato, $hash{string}, es más conciso, pero solo funciona para caracteres alfanuméricos y guiones bajos.

7

Fuera de pedantería, siempre cito mis referencias de cadena en un hash. Sirve para garantizar que no voy a tener un gotcha [1].

[1] Soy bastante conservador en mi codificación Perl.

+1

+1 porque es un argumento legítimo aunque tiendo a estar en desacuerdo. –

+1

¿No está de acuerdo con que evite ciertos errores? ¿O no está de acuerdo con los motivos de estilo? Soy curioso. –

+0

¿Qué problemas exactamente evita siempre citar? – nohat

7

El formulario sin comillas es el preferido por la mayoría, porque es más conciso y ordenado, siempre que la tecla hash esté limitada a los caracteres alfanuméricos y al guión bajo. Además, la mayoría de los editores con soporte de sintaxis de Perl saben cómo resaltarlos como cadenas a pesar de que no están entre comillas.

Debe tenerse en cuenta que puede obtener este comportamiento no solo al usar las teclas hash, sino también al definir hashes, pasar argumentos o incluso al definir listas cuando usa =>. Puede ayudar a distinguir visualmente sus claves de sus valores en los dos casos anteriores. Ejemplos:

# Hash construction 
my %hash = ( 
    key1 => "val1", 
    key2 => "val2" 
); 

# Subroutine arguments 
some_function(arg1 => "val1", arg2 => $val2); 
sub some_function { my %args = @_; }; # arguments are pulled in as a hash 

# List construction (of course, not sure why you'd do this...) 
my @list = (Foo => "bar"); 
print @list; # prints Foobar 

Dicho todo esto, comencé a citar todo y ha sido un hábito difícil de romper. De alguna manera se siente "más seguro" citar tus claves hash, incluso después de todos estos años.

+0

¿Menos propenso a errores? He visto más errores de personas que no usan comillas que las usan. Vea la respuesta de Draegtun para algunos ejemplos. –

+0

@brian: Sí, los dos ejemplos dados son buenos, pero no son exactamente oscuros. Un período está fuera del conjunto alphanum + guión bajo, por lo que es fácil de atrapar. También hago que sea costumbre usar siempre parens con métodos definidos por el usuario, por lo que el segundo formulario tampoco me sirve. Sin embargo, me inclino ante tu experiencia superior y he eliminado esa oración de mi respuesta. –

8

Evitar las citas es más idiomático.

Editar para agregar:

Citando no es la solución a la legibilidad absoluta.Considere la inconsistencia aquí:

sub function() { 'OH HAI' } 
my @list = ('foo', 'bar', function); 
# ==> ('foo', 'bar', 'OH HAI') 

my %hash; 
$hash{'foo'} = 1; 
$hash{'bar'} = 2; 
$hash{function} = 3; 
# ==> { foo => 1, bar => 2, function => 3 } (oops) 

Cuando nunca se citan cadenas, las cosas "raras" son visualmente diferentes de las cadenas de civil ... y se analiza correctamente.

$hash{foo} = 1; 
$hash{bar} = 2; 
$hash{+function} = 3; # aha, this looks different... because it is 
# ==> { foo => 1, bar => 2, 'OH HAI' => 3 } 

(sintaxis de desbordamiento de pila destacando líos esto, a fin de tratar de ignorarlo.)

0

Debe siempre $hash{"string"} a menos que desee $hash{string}.