De perldoc perlobj (citado en este excelente answer ):

my $fred = Critter->find("Fred");
$fred->display("Height", "Weight");

... el código anterior es en su mayoría equivalente a:

my $fred = Critter::find("Critter", "Fred");
Critter::display($fred, "Height", "Weight");

¿Cuál es exactamente la diferencia, dejando de lado la verificación de errores para asegurarse de que el primer parámetro sea un objeto bendecido o un nombre de clase válido? P.ej. ¿Por qué es principalmente pero no exactamente lo mismo?

7
DVK 28 may. 2012 a las 16:58
2
"Dejando de lado la comprobación de errores para asegurarse de que el primer parámetro sea un objeto bendecido o un nombre de clase válido", esa es una propiedad bastante grande para dejar de lado, ¿no es así?
 – 
Mat
28 may. 2012 a las 17:06
- Correcto. Lo dejé fuera por su obviedad, no por falta de importancia.
 – 
DVK
28 may. 2012 a las 17:08

1 respuesta

La mejor respuesta

Digamos que Critter es una subclase que no define find o display, ¡o ambos! La correspondencia no es uno a uno porque las sub llamadas cableadas no realizan búsquedas de métodos, como explica la documentación de perlobj.

¿Cómo sabe Perl en qué paquete está la subrutina? Mirando el lado izquierdo de la flecha, que debe ser un nombre de paquete o una referencia a un objeto, es decir , algo que ha sido bendecido para un paquete. De cualquier manera, ese es el paquete donde Perl comienza a buscar. Si ese paquete no tiene subrutina con ese nombre, Perl comienza a buscarlo en cualquier clase base de ese paquete, y así sucesivamente.

Con un sub, tienes que saber exactamente dónde está estáticamente, o tu programa lo hará die. Para llamar a un método, solo necesita especificar dónde comenzar a buscarlo.

Por ejemplo:

#! /usr/bin/env perl

package Critter;
sub new { bless {}, shift }
sub display { ref($_[0]) . " display" }

package SuperCritter;
@SuperCritter::ISA = qw/ Critter /;

package main;
my $super = SuperCritter->new;

# one of these things is not like the other
warn $super->display;
warn Critter::display($super);
warn SuperCritter::display($super);

Salida:

SuperCritter display at ./call-demo line 14.
SuperCritter display at ./call-demo line 15.
Undefined subroutine &SuperCritter::display called at ./call-demo line 16.
15
Greg Bacon 9 jun. 2012 a las 02:43
Entonces, llamar a Critter_subclass::display resultará en un error de tiempo de ejecución? (mostrando que probablemente mejoraría esta ya buena respuesta al proporcionar un ejemplo concreto para una explicación teórica).
 – 
DVK
28 may. 2012 a las 17:13
¡Buena sugerencia! Actualizado.
 – 
Greg Bacon
28 may. 2012 a las 17:23
2
Una excelente respuesta, que voté a favor, y sin embargo, logra demostrar que la respuesta a la pregunta es principalmente herencia, sin usar la palabra herencia. :)
 – 
DavidO
29 may. 2012 a las 04:08