OOP Perl pasando @_ al segundo método
Frecuentes
Visto 154 equipos
0
#! /usr/bin/perl
# this is the object tester
{package Hate;
sub status {
my $class = shift;
print "-- $_[0] $_[1] $_[2]\n";
print "$class exists and ", $class->stats($_[0]), "and ", $class->type($_[1]), "and ", $class->location($_[2]);
}
}
{package Grudge;
@ISA = "Hate";
sub stats{"$_[0]\n"}
sub type{"$_[0]\n"}
sub location{"$_[0]\n"}
}
Hate::status("Grudge", @ARGV);
corrí ./programa uno dos tres
esta salida es lo que esperaba Grudge existe y uno y dos y tres
esto es lo que tengo El rencor existe y el rencor y el rencor y el rencor
Sin embargo, cuando uso este script
#! /usr/bin/perl
# this is the object tester
{package Hate;
sub status {
my $class = shift;
print "-- $_[0] $_[1] $_[2]\n";
print "$class exists and ", $class->stats($_[0]), "and ", $class->type($_[1]), "and ", $class->location($_[2]);
}
}
{package Grudge;
@ISA = "Hate";
sub stats{"$_[1]\n"}
sub type{"$_[1]\n"}
sub location{"$_[1]\n"}
}
Hate::status("Grudge", @ARGV);
Esto funcionó.
1 Respuestas
4
En tu primer ejemplo, $class->stats($_[0])
se llama como Método y se pasa un objeto como primer argumento, que debe ser desplazado como lo hizo en Hate::status
. Es por eso $_[1]
funciona: porque el primer argumento del método es en realidad el segundo elemento en @_
(después $self
).
Las cosas se vuelven mucho más claras y manejables si desentraña los argumentos de @_
al comienzo de la función, por ejemplo
{
package Hate;
sub status {
my ($class, $stats, $type, $location) = @_;
print "-- $stats $type $location\n";
print "$class exists and ", $class->stats($stats), ...;
}
}
{
package Grudge;
our @ISA = qw(Hate);
sub stats { my ($self, $stats) = @_; $stats; }
sub type { my ($self, $type) = @_; $type; }
sub location { my ($self, $location) = @_; $location; }
}
Hate::status('Grudge', @ARGV);
Como nota al margen, su uso de objetos no es típico: si proporcionó más código, es posible que podamos proporcionar una solución Perl más idiomática. Por ejemplo, ninguno de sus objetos tiene constructores, y en este momento los tres métodos Grudge parecen hacer lo mismo. Tampoco está claro por qué Grudge
es una subclase de Hate
(como lo indica el @ISA
).
si realmente no quieres Grudge
para pasar su propio nombre como argumento, puede llamar a sus métodos como funciones a través de &{$class . '::stats'}()
pero tendrás que deshabilitar strict subs
. Por lo general, es mejor llamar a los métodos como lo está haciendo ahora.
Respondido 01 Jul 12, 18:07
Por lo general, eludo la invocación del método haciendo my $method = $class->can('stats')
entonces cuando llamas $method->(@args)
no pasa la autorreferencia. Limpiador y strict
-seguro. ;-)- joel berger
@JoelBerger: Sí, pero aun así, ¿por qué querrías hacerlo? - ilmari karonen
Ok, la verdad sea dicha, no evito la invocación de métodos, necesito referencias a métodos, y los llamo con $method->($instance, @args)
, pero el uso no es diferente. Por qué @rjh hace esto, no lo sé. - joel berger
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas perl oop inheritance object or haz tu propia pregunta.
¿Odia o le guarda rencor el código de sangría y las mayúsculas en las oraciones? - pilcrow
Realmente no estoy tratando de sonar sarcástico, pero ¿por qué esperas
one two three
? Quizás si explica por qué esta es su expectativa, podríamos entender cuál es la desconexión. También lo que está en@ARGV
? - Joel Berger