logo - ¿Cuál es la diferencia entre-> y:: en Perl
perl vs python (3)
Cuando el lado derecho es una función ->
pasa su lado izquierdo como el primer argumento de la función. Entonces, los siguientes ejemplos son equivalentes si $foo
es un objeto bendecido para empaquetar Foo y Bar está en el paquete Foo. ->
resolverá los métodos heredados haciéndolo más limpio y más útil para los objetos.
$foo->Bar();
Foo::Bar($foo);
->
También puede tomar un nombre de paquete
Foo->Bar();
Foo::Bar(''Foo'');
Esto significa que ->
generalmente se usa en métodos de instancia para que el objeto se pase a sí mismo y a los constructores, de modo que los constructores sepan con qué paquete bendecir. Esto suele ser un parámetro por lo que puede ser heredado.
¿Cuál es la diferencia exacta entre ::
y ->
en Perl?
->
veces funciona donde ::
no lo hace.
Muchas explicaciones aquí, pero aquí está la respuesta muy simplista para los nuevos desarrolladores:
FOO::BAR(); # is calling the class''s (aka. package''s) default object
$FOO->BAR(); # is calling an initiated object
Normalmente, un objeto tiene propiedades que a menudo se establecen, donde un objeto no iniciado usa solo las propiedades predeterminadas del objeto.
Supongamos que FOO tiene una propiedad llamada ''Age'' que tiene un valor predeterminado de 1 que podemos cambiar mediante un comando set anteriormente en nuestro programa. Entonces decidimos llamar al paquete de nuevo de las dos maneras por diversión que pudimos ver:
use FOO;
$FOO = new FOO(); #new instance of foo
$FOO->SetAge(21);
# more code here
print $FOO->GetAge(); # prints 21
print FOO::GetAge(); # prints 1
¿Qué pasa con los paquetes sin ninguna variable almacenada? En muchos casos, puede que no haya ninguna diferencia, pero esto depende en última instancia de cómo se escribe la clase. Al final, es más complejo que eso ... y esta no es realmente la respuesta exacta, pero es lo que creo que está buscando según su pregunta.
Solo para evitar confusiones, generalmente no uso el nombre de las clases / paquetes al crear un objeto. Si por alguna razón no sé cómo llamarlo, lo prefijo con una ''o'' para que quede claro que es un objeto y no una clase, lo que es una buena práctica para cualquier lenguaje de programación.
es decir, usar
$oFOO = new FOO(); // new object instance of foo
Espero que ayude.
::
Tiene dos usos.
Es el separador de espacio de nombres en los nombres de paquetes.
use Foo::Bar; # Load Foo/Bar.pm $Foo::Bar::var # $var in namespace Foo::Bar
Agregado a una palabra, crea una cadena literal [1] .
Lo siguiente es lo mismo que
''hello''
excepto que advierte si el paquetehello
no existe:hello::
->
Tiene dos usos.
Se utiliza para desreferir.
$array_ref->[$i] $hash_ref->{$k} $code_ref->(@args)
Se utiliza en las llamadas de método para denotar el invocante.
CGI->new() # Static method call $cgi->param() # Object method call
Probablemente estás preguntando cuál es la diferencia entre
Foo::Bar::mysub()
y
Foo::Bar->mysub()
El primero es una llamada de función. Este último es un método llamado. Una llamada de método es como una llamada de función con dos diferencias:
Método de llamadas utiliza la herencia.
Las llamadas de método pasan el invocante (lo que queda de
->
) al sub como primer argumento.
{
package Foo::Baz;
sub new {
my ($class, $arg) = @_;
my $self = bless({}, $class);
$self->{arg} = $arg;
return $self;
}
sub mysub1 {
my ($self) = @_;
print($self->{arg}, "/n");
}
}
{
package Foo::Bar;
our @ISA = ''Foo::Baz'';
sub mysub2 {
my ($self) = @_;
print(uc($self->{arg}), "/n");
}
}
my $o = Foo::Bar->new(''hi''); # Same as: my $o = Foo::Baz::new(''Foo::Bar'', ''hi'');
$o->mysub1(); # Same as: Foo::Baz::mysub1($o);
$o->mysub2(); # Same as: Foo::Bar::mysub2($o);
Notas
-
Foo->method
llama engañosamente al sub nombreFoo
si existe (usando su valor que devuelve como invocante).Foo::->method
, que significa''Foo''->method
, no lo hace.