Kiedy powinienem użyć & do wywołania podprogramu Perla?
Słyszałem, że ludzie nie powinni używać &
do wywoływania subów Perla, czyli:
function($a,$b,...);
# opposed to
&function($a,$b,...);
Wiem, że po pierwsze lista argumentów staje się opcjonalna, ale jakie są przypadki, w których właściwe jest użycie &
i przypadki, w których absolutnie nie powinieneś jej używać?
Również w jaki sposób performace increase wchodzi w grę, pomijając &
?
4 answers
IMO, jedynym powodem użycia &
jest uzyskanie lub wywołanie coderef, np.:
sub foo() {
print "hi\n";
}
my $x = \&foo;
&$x();
Główny czas, w którym Możesz użyć go, którego absolutnie nie powinieneś w większości przypadków, to wywołanie suba, które ma prototyp, który określa dowolne niestandardowe zachowanie wywołania. Chodzi mi o to, że niektóre prototypy umożliwiają reinterpretację listy argumentów, na przykład konwersję specyfikacji @array
i %hash
Na odwołania. Więc sub będzie oczekiwać tych reinterpretacji, które miały miejsce, i o ile nie przejdziesz do wszelkich niezbędnych długości, aby naśladować je ręcznie, sub otrzyma wejścia szalenie różne od tych, których oczekuje.
Myślę, że głównie ludzie próbują ci powiedzieć, że nadal piszesz w stylu Perl 4, a teraz mamy dużo czystszą, ładniejszą rzecz o nazwie Perl 5.
Jeśli chodzi o wydajność, istnieją różne sposoby, w jakie Perl optymalizuje wywołania podrzędne, które &
pokonuje, z których jednym z głównych jest inlining stałych.
Istnieje również jedna okoliczność, w której użycie &
zapewnia korzyści wydajnościowe: jeśli przekierowujesz wywołanie podrzędne za pomocą foo(@_)
. Użycie &foo
jest nieskończenie szybsze niż foo(@_)
. Nie polecałbym tego, chyba że definitywnie stwierdzisz, profilując, że potrzebujesz tej mikro-optymalizacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-13 16:27:13
Jestem częstym oprawcą &
, ale głównie dlatego, że robię dziwne rzeczy z interfejsem. Jeśli nie potrzebujesz żadnej z tych sytuacji, nie używaj &
. Większość z nich jest po prostu po to, aby uzyskać dostęp do definicji podprogramu, a nie wywołać podprogramu. Wszystko jest w perlsub.
-
Biorąc odniesienie do nazwanego podprogramu. Jest to prawdopodobnie jedyna wspólna sytuacja dla większości Perlerów: {]}
my $sub = \&foo;
-
Podobnie, przypisanie do typeglob, który pozwala na wywołanie podprogram o innej nazwie:
*bar = \&foo;
-
Sprawdzanie, czy podprogram jest zdefiniowany, jak można w zestawach testowych:
if( defined &foo ) { ... }
-
Usunięcie definicji podprogramu, która nie powinna być powszechna:
undef &foo;
-
Zapewnienie podprogramu dyspozytora, którego jedynym zadaniem jest wybranie odpowiedniego podprogramu do wywołania. Jest to jedyna sytuacja, w której używam
&
do wywołania podprogramu, a kiedy spodziewam się zadzwonić do dyspozytora wiele, wiele razy i muszę wycisnąć trochę wydajności z operacji:sub figure_it_out_for_me { # all of these re-use the current @_ if( ...some condition... ) { &foo } elsif( ...some other... ) { &bar } else { &default } }
-
Aby przeskoczyć do innego podprogramu używając bieżącego stosu argumentów (i zastępując bieżący podprogram w stosie wywołań), operacja unrare w dispatchingu, szczególnie w
AUTOLOAD
:goto ⊂
Wywołaj podprogram, który nazwałeś po wbudowanym perlu.
&
zawsze daje Ci zdefiniowaną przez użytkownika. To jest dlaczego uczymy go w Uczenie Się Perla. Nie chcesz tego robić. to normalnie, ale to jedna z cech&
.
Są miejsca, gdzie można je wykorzystać, ale są lepsze sposoby: {]}
Wywołanie podprogramu o tej samej nazwie, co Wbudowany Perl. Po prostu nie mają podprogramów o tej samej nazwie, co Wbudowany Perl. Sprawdź perlfunc , aby zobaczyć listę wbudowanych nazw, których nie powinieneś używać.
Aby wyłączyć prototypy. Jeśli nie wiesz, co to oznacza lub dlaczego chcesz, nie użyj
&
. Jakiś kod czarnej magii może go potrzebować, ale w takich przypadkach prawdopodobnie wiesz, co robisz.Do dereferencji i wykonania referencji podprogramu. Wystarczy użyć notacji
->
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-28 00:44:20
Forma &podprogram() wyłącza sprawdzanie prototypu. To może być to, czego chcesz.
Http://www.perl.com/doc/manual/html/pod/perlsub.html#Prototypes
Prototypy pozwalają określić liczby i typy argumentów podprogramu i sprawdzać je podczas kompilacji. Może to zapewnić użyteczną pomoc diagnostyczną.
Prototypy nie mają zastosowania do wywołań metod lub wywołań wykonanych w starym stylu przy użyciu prefiksu&.
The & is niezbędne do odniesienia się do podprogramu lub odniesienia do kodu
Np.
sub foo {
# a subroutine
}
my $subref = \&foo; # take a reference to the subroutine
&$subref(@args); # make a subroutine call using the reference.
my $anon_func = sub { ... }; # anonymous code reference
&$anon_func(); # called like this
Protypy również nie mają zastosowania do podprogramów.
Forma & podprogramu jest również używana w tak zwanej formie magic goto.
Wyrażenie goto &subroutine
zastępuje bieżący kontekst wywołania wywołaniem nazwanej podprogramu, używając bieżącej wartości @_.
Zasadniczo, można całkowicie przełączyć wywołanie na jeden podprogram z wywołaniem na wywołanie nazwane. Jest to powszechnie widoczne w blokach AUTOLOAD, gdzie można wykonać odroczone wywołanie podprogramu, być może z pewną modyfikacją@_, ale wygląda to całkowicie tak, jakby było to wywołanie do nazwanego sub.
Np.
sub AUTOLOAD {
...
push @_, @extra_args; # add more arguments onto the parameter list
goto &subroutine ; # change call another subroutine, as if we were never here
}
}
Potencjalnie może to być przydatne do eliminacji wywołania ogonowego , jak sądzę.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-05 14:36:12
Czytałem argumenty przeciwko używaniu '&', ale prawie zawsze go używam. Oszczędza mi to zbyt dużo czasu, żeby tego nie zrobić. Spędzam bardzo dużą część mojego czasu kodowania Perla, szukając części kodu, które wywołują określoną funkcję. Z wiodącym&, mogę wyszukiwać i znajdować je natychmiast. Bez wiodącego &, dostaję definicję funkcji, komentarze i instrukcje debugowania, Zwykle potrajając ilość kodu, który muszę sprawdzić, aby znaleźć to, czego szukam.
Najważniejsze, że nie używasz '&' you is pozwala na korzystanie z prototypów funkcji. Prototypy funkcji Perla mogą jednak tworzyć błędy tak często, jak im zapobiegają, ponieważ pobierają listę argumentów i reinterpretują ją w sposób, którego nie można się spodziewać, tak że wywołanie funkcji nie przekazuje argumentów, które dosłownie mówi.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-11 03:35:10