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;