Главная страница


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)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 Передать параметр из подпрограммы   Soft   22 Feb 2002 00:15:14 
 Re: Передать параметр из по дпрограммы   Andrey Sapozhnikov   22 Feb 2002 17:17:40 
 Re: Передать параметр из по дпрограммы   Victor Wagner   22 Feb 2002 19:27:50 
 Re: Передать параметр из по дпрограммы   Andrey Sapozhnikov   23 Feb 2002 04:26:17 
 Re: Передать параметр из по дпрограммы   Victor Wagner   23 Feb 2002 12:16:04 
 Re: Передать параметр из по дпрограммы   Andrey Sapozhnikov   24 Feb 2002 03:04:47 
 Re: Передать параметр из по дпрограммы   Victor Wagner   24 Feb 2002 11:24:27 
 Re: Передать параметр из подпрограммы   Artem Chuprina   22 Feb 2002 17:24:49 
 Re: Передать параметр из подпрограммы   Soft   26 Feb 2002 20:02:49 
 Re: Передать параметр из подпрограммы   Andrey Sapozhnikov   27 Feb 2002 00:12:35 
 Re: Передать параметр из подпрограммы   Victor Wagner   22 Feb 2002 17:34:09 
 Re: Передать параметр из подпрограммы   Igor S Chencov   22 Feb 2002 17:41:28 
 Re: Передать параметр из подпрограммы   ‚« ¤Ё¬Ёp ѓpҐЎ­Ґў   22 Feb 2002 19:09:53 
Архивное /ru.perl/65775ea8ac8e.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional