2009-08-05 10 views

Odpowiedz

37

Oto kompletny, działający skrypt, który demonstruje to, o co prosisz.

sub a { print "Hello World!\n"; } 

sub b { 
    my $func = $_[0]; 
    $func->(); 
} 

b(\&a); 

Oto wyjaśnienie: wziąć odniesienie do funkcjonowania a mówiąc \&a. W tym momencie masz odniesienie do funkcji; podczas gdy normalnie funkcja byłaby wywoływana przez powiedzenie func() wywołujesz odwołanie do funkcji, mówiąc, że składnia $func->() ma również inne odwołania. Na przykład, oto przykład radzenia sobie z odniesieniami tablicy i hash:

sub f { 
    my ($aref, $href) = @_; 
    print "Here's an array reference: $aref->[0]\n"; # prints 5 
    print "Here's a hash ref: $href->{hello}\n";  # prints "world" 
} 

my @a = (5, 6, 7); 
my %h = (hello=>"world", goodbye=>"girl"); 
f(\@a, \%h); 
+1

Co, jeśli przekazywałbym funkcję jako część skrótu, to wyglądałby tak? $ args {function} ->(); – Kys

+0

Dodałem przykłady tablic i skrótów. –

+1

Ale co jeśli to było to: f (funkcja => \ &func); następnie w funkcji f, to byłoby to sub f { $ args {function} ->(); } – Kys

4

Można uzyskać dostęp do podprogramów referencje jako \&my_method w Perl, i nazywają te referencje z $myref->();. Wypróbuj to:

perl -e'sub a { print "foo in a"; }; sub b { shift->(); }; b(\&a);' 

Powodzenia!

+0

Co jeśli przechodzę przez functi w ramach skrótu, to może wyglądać tak? $ args {function} ->(); – Kys

2

Nawiązując do przykładu Eli Courtwright: jeśli używasz tylko pierwszą funkcję raz, można również zadzwonić b z anonimowej funkcji, takich jak to:

b(sub { print "Hello World\n"; }); 
5

Nie można przekazać funkcję do innej funkcji bezpośrednio. Zamiast tego podajesz funkcję reference. Aby wywołać funkcję, którą usuniesz (jako odwołanie do CODE), używając ->();

sub a { print @_ } 

sub b { 
    my $f = shift; # assuming that $f is a function reference... 
    $f->(@_);  # call it with the remaining arguments 
} 

b(\&a, "hello, world!"); # prints "hello, world!" 

Perl nie ma semantyki pass-by-name, ale można je emulować za pomocą skrótu. Metoda wywoływania funkcji jest taka sama. Usuwasz to.

sub a { print @_ } 

sub b { 
    my %arg = @_; 
    $arg{function}->(@{$arg{arguments}}); 
} 

b(function => \&a, arguments => ["hello, world!"]); 

ObPerl6: Perl 6 będzie miał semantykę pass-by-name.

Powiązane problemy