Pytanie "How can I monkey-patch an instance method in Perl?" zmusiło mnie do myślenia. Czy mogę dynamicznie przedefiniować metody Perla? Załóżmy, że mam taką klasę:Jak mogę przedefiniować metody klasy Perla?
package MyClass;
sub new {
my $class = shift;
my $val = shift;
my $self = { val=> $val};
bless($self, $class);
return $self;
};
sub get_val {
my $self = shift;
return $self->{val}+10;
}
1;
Załóżmy, że dodanie dwóch liczb jest naprawdę drogie.
Chciałbym zmodyfikować klasę tak, aby $ val + 10 było obliczane tylko przy pierwszym wywołaniu metody na tym obiekcie Kolejne wywołania metody zwrócą buforowaną wartość.
mogę łatwo zmodyfikować sposób obejmuje buforowanie, ale:
- mam kilka sposobów, takich jak to.
- Wolę nie brudzić tej metody.
Co naprawdę chcę zrobić, to podać listę metod, które znam zawsze zwracają tę samą wartość dla danej instancji. Następnie chcę wziąć tę listę i przekazać ją do funkcji dodawania buforowania do tych metod.
Czy istnieje skuteczny sposób, aby to osiągnąć?
Kontynuacja. Poniższy kod działa, ale ponieważ użycie strict nie zezwala na odwołania za pomocą ciągu znaków, nie jestem w 100% tam, gdzie chcę być.
sub myfn {
printf("computing\n");
return 10;
}
sub cache_fn {
my $fnref = shift;
my $orig = $fnref;
my $cacheval;
return sub {
if (defined($cacheval)) { return $cacheval; }
$cacheval = &$orig();
return $cacheval;
}
}
*{myfn} = cache_fn(\&myfn);
Jak zmodyfikować po prostu to zrobić ?:
cache_fn(&myfn);
{brak ostrzeżeń "przedefiniowanie"; * myfn = cache_fn (\ &myfn);} - To pozbywa się niejednoznacznych i redefiniowanych ostrzeżeń.Zobacz moją nową odpowiedź na temat cache_fn (&myfn); – draegtun
Możesz zajrzeć do notowania (jest kilka dobrych modułów CPAN) lub użyć wyzwalaczy Moose do buforowania drogich obliczenia w atrybutach i przeliczyć je w razie potrzeby za pomocą wyzwalaczy – Ether