2010-11-03 24 views
7

Perl automatically initializes variables a undef por defecto.¿Cómo puedo inicializar automáticamente todas las variables escalares en Perl?

¿Hay alguna manera de anular este comportamiento predeterminado y decirle al intérprete de Perl que inicialice las variables a zero (u otro valor fijo)?

+0

La inicialización de variables a 'undef' sigue siendo una inicialización. – zigdon

+7

¿Puedo preguntar por qué querría hacer esto? – Zaid

+0

@Zaid: la historia completa: estoy leyendo Code Complete (que menciona siempre inicializar variables mientras declaro, si es posible) y estaba mirando uno de mis archivos antiguos que usa muchos contadores que inicialmente había inicializado en 'cero' pero luego eliminó todas las inicializaciones innecesarias. Estoy pensando en reintroducir todas las inicializaciones y formulé esta pregunta para encontrar una mejor manera de hacerlo. – Lazer

Respuesta

12

La recomendación de código completo es importante para el lenguaje como C, porque cuando se tiene

int f(void) { 
    int counter; 
} 

el valor de counter es lo que pasa a ocupar la memoria.

En Perl, cuando se declara una variable usando

my $counter; 

no hay duda de que el valor de $counter es undef no un poco de basura al azar.

Por lo tanto, la motivación detrás de la recomendación, es decir, garantizar que todas las variables comiencen con valores conocidos, se satisface automáticamente en Perl y no es necesario hacer nada.

Lo que debes hacer con los contadores es incrementarlos o disminuirlos. El resultado de:

my $counter; 
# ... 
++ $counter; 

está bien definido en Perl. $counter tendrá el valor 1.

Finalmente, yo diría que, en la mayoría de los casos, los contadores no son necesarios en Perl y es posible que sea necesario volver a escribir el código que hace un uso extensivo de las variables del contador.

+2

+1 para preguntas con una explicación elegante – daxim

+2

¿Cuándo * reescrito * se convirtió en * refactorizado *, de todos modos? ☺ – tchrist

5

No. Hacer esto puede llevar a algunos errores muy aterradores y difíciles de descifrar, por lo que no es una buena idea cambiar este comportamiento de todos modos.

En Perl, puede declarar variables directamente cuando las necesita por primera vez, por lo que generalmente no es necesario declararlas primero (con o sin inicialización) y luego usarlas más adelante. Además, los operadores tales como ++ trabajarán con valores no definidos igualmente bien como cero, por lo que no es necesario para inicializar los contadores en absoluto:

# this is perfectly legal: 
my $counter; 
while ($some_loop) 
{ 
    $counter++; 
} 

Sin embargo, puedo insertar un enchufe para Moose mencionando que se puede lograr inicialización automática de los atributos en las clases de los alces:

package MyClass; 
use strict; 
use warnings; 
use Moose; 

has some_string => (
    is => 'rw', isa => 'Str', 
    default => 'initial value', 
); 

has some_number => (
    is => 'rw', isa => 'Int', 
    default => 0, 
); 
__PACKAGE__->meta->make_immutable; 
1; 

package main; 
my $object = MyClass->new; 
print "string has value: ", $object->some_string, "\n"; 
print "number has value: ", $object->some_number, "\n"; 

impresiones:

cadena tiene valor: valor inicial
número tiene valor: 0

11

Por lo que yo sé, esto no es posible (y no debe ser, es incluso más peligroso que $[).

Puede inicializar las variables de la siguiente manera para reducir el repetitivo:

my ($x, $y, $z) = (0) x 3; 

o mover la inicialización de una función:

sub zero {$_ = 0 for @_} 

zero my ($x, $y, $z); 

o incluso:

$_ = 0 for my ($x, $y, $z); 
+0

gracias. por cierto, ¿cómo es '$ [' peligroso? – Lazer

+1

es el índice desde el que comienzan las matrices. estaba allí para hacer que perl se comportara como awk estableciéndolo en 1. está en desuso y advierte y solo tiene alcance de archivo y debe establecerse en tiempo de compilación debido a todos los errores que podría causar en código no relacionado. perldoc perlvar para obtener más información –

+0

No veo por qué tendría que inicializar algo a cero en su punto de declaración. – tchrist

0

¿Te tiene una razón concreta para querer hacer esto, o es simplemente "porque Código Completo te dice que debería "?

Si es el primero, comparta la razón y podremos analizar las formas de Perly para lograr su objetivo real.

Si es el último, recuerde que Código completo es un conjunto de pautas para la programación en C, no en Perl. Perl no es C y tiene su propio conjunto de fortalezas y debilidades, lo que también significa que tiene un conjunto diferente de ... y odio usar esta frase ... mejores prácticas. Las pautas apropiadas para un idioma no necesariamente se aplican al otro. "Siempre inicializar variables (si es posible) cuando las declaras" es una práctica de sonido en C, pero generalmente innecesaria en Perl.

Cuestiones relacionadas