|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Andrey Sapozhnikov 2:5020/400 23 Feb 2002 04:26:17 To : Victor Wagner Subject : Re: Передать параметр из по дпрограммы -------------------------------------------------------------------------------- Victor Wagner wrote: > Andrey Sapozhnikov <sapa@icb.chel.su> wrote: > AS> Soft wrote: > > > AS> В данном примере лучше использовать передачу параметра по ссылке. > AS> Собственно все параметры только так и передаются, и @_ является > AS> массивом неявных ссылок на передаваемые параметры. а не на их копии. > AS> Изменяя $_[0] мы изменяем значение параметра. > > Что характерно, в перл 4 подобных неочевидных но удобных штуковин > было куда как больше. Посему я бы зарекаться на эту фичу на всякий > случай не стал. Вдруг в 5.7 отменят. Hе знаю с чего такие мысли, это документированное свойство: perldoc perlsub ... Any arguments passed in show up in the array "@_". There- fore, if you called a function with two arguments, those would be stored in "$_[0]" and "$_[1]". The array "@_" is a local array, but its elements are aliases for the actual scalar parameters. In particular, if an element "$_[0]" is updated, the corresponding argument is updated (or an error occurs if it is not updatable). If an argument is an array or hash element which did not exist when the function was called, that element is created only when (and if) it is modified or a reference to it is taken. (Some earlier versions of Perl created the element whether or not the element was assigned to.) Assigning to the whole array "@_" removes that aliasing, and does not update any arguments. ... > Была (и до сих пор) есть такая фича - если из одной процедуры вызывать > другую не указав параметры, то они наследуются от вызывашей. > > a(1,2); > > sub a { > &b; > } > sub b { > print "@_\n"; > } > > печатает 1 2 Есть такое дело, вполне документировано в той же perldoc perlsub. Правда вызов такой функции должен быть специальным: &NAME; т.е. обязательно с амперсандом и без скобок. Я подобным вызовом рекомендовал бы пользоваться исключительно для целей явной передачи @_ в функцию, хотя поскольку использование & автоматически отключает контроль за прототипами функций, что не только поощряет кривой стиль (когда функции описываются после мест их вызова, а прототипs вообще не используются), но и зачастую приводит к неожиданным для горе-авторов последствиям.Hапример для функции: sub mypush(\@$) { $_[0]->[$#{$_[0]} + 1] = $_[1]; } вызов: my @a = ([]); &mypush(@a, 3); даст @a = ([3]), а вызов (корректный): mypush(@a, 3); даст @a = ([], 3); Кстати, в прототипах функций отсутствует ссылочная передача скаляров. Я это рассматриваю как подтверждение того, что передача параметров > Так вот. в нормальном перле @_ во вложенной процедуре - ссылка на @_ > от вызывашей, и из него можно, например, shift сделать. Hе ссылка, а тот же самый массив. Массив @_ внешней функции имеет local scope, а для внутренней @_ просто не создается и продолжает быть виден внешний. С точки зрения видимости @_ sub b { # code b } sub a { # code a1 b&; # code a2 } эквивалентно: sub a { # code a1 { # code b } # code a2 } > А вот если перл собран с поддержкой нитей, то там - копия. > > Я один раз на это крепко налетел, когда мою софтину попытались впервые > на редхат поставить. А это уже баг, если, конечно, все так и есть при более детальном рассмотрении, поскольку нарушает следующий параграф perldoc perlsub: ... Subroutines may be called recursively. If a subroutine is called using the "&" form, the argument list is optional, and if omitted, no "@_" array is set up for the subrou- tine: the "@_" array at the time of the call is visible to subroutine instead. This is an efficiency mechanism that new users may wish to avoid. &foo(1,2,3); # pass three arguments foo(1,2,3); # the same foo(); # pass a null list &foo(); # the same &foo; # foo() get current args, like foo(@_) !! foo; # like foo() IFF sub foo predeclared, else "foo" Not only does the "&" form make the argument list optional, it also disables any prototype checking on argu- ments you do provide. This is partly for historical rea- sons, and partly for having a convenient way to cheat if you know what you're doing. See the Prototypes manpage below. ... Коротко и внятно сказано то, что я так долго разъяснял. Велик и могуч... :) Хотя c threads support взятки гладки, сказано же - "is an experimental feature. ... Use at your own risk!". Андрей --- ifmail v.2.15dev5 * Origin: Demos online service (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/65775ea8ac8e.html, оценка из 5, голосов 10
|