mi $ auto=cambio en Perl; una explicación
attributes moose (3)
En el código de nivel superior, shift() es la abreviatura de shift(@ARGV) . @ARGV contiene los argumentos de línea de comandos.
En un sub, shift() es la abreviatura de shift(@_) . @_ contiene los argumentos del sub.
Entonces my $self = shift; está agarrando el primer argumento del submarino. Al llamar a un método, el invocante (lo que queda de -> ) se pasa como el primer parámetro. En otras palabras,
$o->method(@a)
es parecido a
my $sub = $o->can(''method'');
$sub->($o, @a);
En ese ejemplo, my $self = shift; asignará $o a $self .
Me está costando mucho entender la intersección de OO Perl y my $self = shift; La documentación sobre estos elementos individuales es excelente, pero ninguno de ellos que he encontrado trata sobre cómo funcionan juntos.
He estado usando Moose para hacer módulos con atributos, y por supuesto es útil hacer referencia al atributo de un módulo dentro de dicho módulo. Me han dicho una y otra vez que use my $self = shift; dentro de una subrutina para asignar los atributos del módulo a esa variable. Esto tiene sentido y funciona, pero cuando también paso argumentos a la subrutina, este proceso toma claramente el primer elemento de la matriz @ARGV y también lo asigna a $self .
¿Alguien puede ofrecer una explicación de cómo puedo usar shift para obtener acceso interno a los atributos de un módulo, al mismo tiempo que paso argumentos en la matriz @ARGV ?
En primer lugar, una subrutina no pasa la matriz @ARGV . Más bien, todos los parámetros pasados a una subrutina se aplanan en una sola lista representada por @_ dentro de la subrutina. La matriz @ARGV está disponible en el nivel superior de la secuencia de comandos, que contiene los argumentos de línea de comandos pasados a la secuencia de comandos.
Ahora, en Perl, cuando llamas a un método en un objeto, el objeto se pasa implícitamente como un parámetro al método.
Si ignoras la herencia,
$obj->doCoolStuff($a, $b);
es equivalente a
doCoolStuff($obj, $a, $b);
Lo que significa que el contenido de @_ en el método doCoolStuff sería: @_ = ($obj, $a, $b);
Ahora, la función integrada shift , sin ningún parámetro, desplaza un elemento de la variable de matriz predeterminada @_ . En este caso, eso sería $obj .
Entonces, cuando haces $self = shift , estás diciendo efectivamente $self = $obj .
También espero que esto explique cómo pasar otros parámetros a un método mediante la notación -> . Continuando con el ejemplo que he mencionado anteriormente, esto sería como:
sub doCoolStuff {
# Remember @_ = ($obj, $a, $b)
my $self = shift;
my ($a, $b) = @_;
Además, aunque Moose es una gran capa de objetos para Perl, no elimina el requisito de que deba inicializar el $self en cada método. Siempre recuerda esto. Mientras que el lenguaje como C ++ y Java inicializan la referencia del objeto implícitamente, en Perl necesitas hacerlo explícitamente para cada método que escribas.
Si llamas:
$myinstance->myMethod("my_parameter");
es lo mismo que hacer:
myMethod($myinstance, "my_parameter");
pero si lo haces:
myMethod("my_parameter");
solo se pasará "mi_parámetro".
ENTONCES si dentro de myMethod siempre lo haces:
$self = shift @_;
$ self será la referencia del objeto cuando myMethod id se llame desde un contexto de objeto
pero será "mi_parámetro" cuando se llame desde otro método dentro de una forma de procedimiento.
Sé consciente de esto;