Para especificar como sobrecargar el operador convertir un objeto a cadena
hay que sobrecargar el operador de stringification
denotado como "\"\""
ó también q("")
o incluso '""'
.
La rutina asociada será llamada siempre que el objeto de la clase correspondiente
aparezca en un contexto que requiera una cadena.
package DaysOfTheWeek; ... my @_day_name = qw(Sun Mon Tue Wed Thu Fri Sat) use overload q("") => sub { $_day_name[$_[0]->val] };De este modo cuando se cree un objeto
DaysOfTheWeek
:
my $day = DaysOfTheWeek->new(3);
y se use en un contexto que requiere una cadena como es la función print
:
print $day,"\n";la función asociada con
q("")
será llamada, dando lugar a la salida:
TueOtros contextos en los que se requiere una cadena y, por tanto, se producirá la conversión son:
$menu{$day}
)
Análogamente se puede controlar el modo en que Perl realiza las conversiones
en aquellos contextos en los que requiere un número. El operador
encargado de ello es O+
:
package DaysOfTheWeek; ... my @_day_name = qw(Sun Mon Tue Wed Thu Fri Sat) use overload q("") => sub { $_day_name[$_[0]->val] }; "O+" => sub { $_[0]->{val} };Asi la subrutina asociada con
O+
será invocada dondequiera
que el objeto sea usado y Perl espere que aparezca un valor numérico:
print "*" x $dayimprimirá 3 asteriscos puesto que se supone que el segundo operador de
x
es un entero.
Otra cosa ocurriría si el operador x
estuviera ya sobrecargado, en cuyo caso
se usaría la correspondiente subrutina asociada. Otros contextos en los
que se espera un valor numérico son:
..
)
fallback
este definido a cierto,
los operandos de una operación aritmética no sobrecargada no implican un contexto
numérico. Así la expresión $day+1
no conlleva una conversión de $day
a numérico.
El operador de sobrecarga bool
se encarga de la conversión a valores lógicos.
La correspondiente subrutina será invocada en cualquier contexto en el que aparezca
el objeto de la clase y Perl espere un valor lógico.
Por ejemplo en el módulo Set::Scalar::Base
debido a
Jarkko Hietaniemi y que proporciona acceso al álgebra de conjuntos
vemos la siguiente declaración:
use overload '+' => \&_union_overload, '*' => \&_intersection_overload, '-' => \&_difference_overload, 'neg' => \&_complement_overload, '%' => \&_symmetric_difference_overload, '/' => \&_unique_overload, 'eq' => \&is_equal, '==' => \&is_equal, '!=' => \&is_disjoint, '<=>' => \&compare, '<' => \&is_proper_subset, '>' => \&is_proper_superset, '<=' => \&is_subset, '>=' => \&is_superset, 'bool' => \&size;Obsérvese como el manipulador para
bool
hace que
un conjunto en un contexto lógico devuelva su tamaño (\&size
).
El siguiente ejemplo ilustra este punto. Consideremos el
programa:
$ cat ./scalar_sets2.pl #!/usr/local/bin/perl5.8.0 -d use Set::Scalar; $A = Set::Scalar->new('a'..'z'); print "$A\n" if $A;Al ejecutarlo podemos contemplar como se llama a
&size
para evaluar la condición if $A
:
$ ./scalar_sets2.pl Loading DB routines from perl5db.pl version 1.19 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(./scalar_sets2.pl:4): $A = Set::Scalar->new('a'..'z'); DB<1> n main::(./scalar_sets2.pl:6): print "$A\n" if $A; DB<1> s Set::Scalar::Base::size(/usr/local/lib/perl5/site_perl/5.8.0/Set/Scalar/Base.pm:123): 123: my $self = shift; DB<1> TEl comando
T
nos permite ver la pila de llamadas:
$ = Set::Scalar::Base::size(ref(Set::Scalar), undef, '') called from file `./scalar_sets2.pl' line 6 DB<1> Set::Scalar::Base::size(/usr/local/lib/perl5/site_perl/5.8.0/Set/Scalar/Base.pm:125): 125: return scalar keys %{ $self->{'elements'} }; DB<1> c (a b c d e f g h i j k l m n o p q r s t u v w x y z)