2012-05-09 7 views
5

me escribió lo siguiente Perl Clase:En Perl, ¿cómo paso una función como argumento de otra función?

package Menu; 
use strict; 

my @MENU_ITEMS; 
my $HEADER = "Pick one of the options below\n"; 
my $INPUT_REQUEST = "Type your selection: "; 

sub new { 
    my $self = {}; 
    $self->{ITEM} = undef; 
    $self->{HEADER} = undef; 
    $self->{INPUT_REQUEST} = undef; 
    bless($self); 
    return $self; 
} 

sub setHeader { 
    my $self = shift; 
    if(@_) { $self->{HEADER} = shift } 
    $HEADER = $self->{HEADER}."\n"; 
} 

sub setInputRequest { 
    my $self = shift; 
    if(@_) { $self->{INPUT_REQUEST} = shift } 
    $INPUT_REQUEST = $self->{INPUT_REQUEST}." "; 
} 

sub addItem { 
    my $self = shift; 
    if(@_) { $self->{ITEM} = shift } 
    push(@MENU_ITEMS, $self->{ITEM}); 
    } 

sub getMenu { 
    my $formatted_menu .= $HEADER; 
    my $it=1; 
    foreach(@MENU_ITEMS) { 
     $formatted_menu.=$it.". ".$_."\n"; 
     $it++ 
     } 
    $formatted_menu.=$INPUT_REQUEST; 
    return $formatted_menu; 
} 
1; 

Si llamo el siguiente script Perl:

#!/usr/bin/perl 
use strict; 
use Menu; 

my $menu = Menu->new(); 
$menu->addItem("First Option"); 
$menu->addItem("Second Option"); 
print $menu->getMenu; 

que obtendrá el siguiente resultado:

Pick one of the options below 
1. First Option 
2. Second Option 
Type your selection: 

me gustaría para modificar una clase determinada de forma que pueda pasar un segundo argumento al método addItem()

algo como: $menu->addItem("First Option", &firstOptionFunction());

y si, y sólo si se seleccionaFirst Option, a continuación, se ejecuta $firstOptionFunction.

¿Hay alguna forma de lograr este comportamiento en Perl? Gracias!

Respuesta

6

Desea pass a reference a la subrutina.

$menu->addItem("First Option", \&firstOptionFunction); 

Y su método de addItem podría tener este aspecto:

sub addItem { ## your logic may vary 
    my ($self, $option, $code) = @_; 
    if ($option eq 'First Option') { 
     $code->(); 
    } 

    $self->{ITEM} = $option; 
    push @MENU_ITEMS, $option; 

    return; 
} 

Como se ha mencionado en los comentarios, es posible que desee dejar pasar la subrutina como referencia, sino más bien almacenarla en otro lugar. Algo como esto podría funcionar:

sub new { 
    my $class = shift; 
    my $self = bless {}, $class; 
    $self->{f_o_code} = \&firstOptionFunction; ## use a better name than f_o_code 
    return $self; 
} 

## add your other methods 

sub addItem { ## your logic may vary 
    my ($self, $option) = @_; 
    if ($option eq 'First Option') { 
     $self->{f_o_code}->(); 
    } 

    $self->{ITEM} = $option; 
    push @MENU_ITEMS, $option; 

    return; 
} ## call like $menu->addItem('First Option'); 
+0

y ¿cómo manejaría eso dentro del método addItem? Soy bastante nuevo en Perl, en pocas semanas. Estaba pensando en algo similar, tratando de encontrar una forma de obtener una referencia a la ubicación en la memoria de cada función, pero pensé que sería demasiado difícil de lograr. – ILikeTacos

+0

Siempre puede almacenar el code_ref en $ self como '$ self -> {first_op_code} = \ & firstOptionFunction;' y no pasar la referencia en absoluto. – gpojd

+0

¡Genial! Intentaré modificar el código que publicaste y ver si puedo hacerlo funcionar. Muchas gracias. – ILikeTacos

Cuestiones relacionadas