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


ru.perl

 
 - RU.PERL ----------------------------------------------------------------------
 From : Andrey Sapozhnikov                   2:5020/400     04 Nov 2004  19:09:55
 To : Artem Chuprina
 Subject : Re: А есть ли в эхотаге рекурсия?
 -------------------------------------------------------------------------------- 
 
 Artem Chuprina пишет:
 
 > Alexander Pashchenko -> Artem Chuprina  @ Tue, 02 Nov 2004 22:38:00 +0300:
 > 
 >  AC>> В современных перлах можно сказать open(my $f, ...).  Будет работать
 >  AP> А "современные перлы" это какие версии?
 > 
 > Hачиная с 5.6.
 > 
 >  AC>> Даже close не потребуется.
 >  AP> Хорошая привычка закрывать файлы :) Да и переменные отдельным
 >  AP> блоком объявлять.
 >  AP>>> Кстати, а большая ли разница между my и local?
 >  AC>> Принципиальная.
 >  AP> Да я понимаю, что принципиальная. Что-то связанное с видимостью: вроде
 >  AP> как local - текущий блок и ниже, а my - только текущий блок. Так?
 > 
 > Гораздо хуже.  Лучше, конечно, почитать в какой-нибудь умной книжке.
 > Hо.  my-переменная видна только в этом блоке _и в определенных в нем
 > функциях_ (это отдельная довольно сложная для человека, задающего
 > подобные вопросы, тема), зато время жизнии ее значения не ограничено.
 > local - это глобальная переменная, которая имеет указанное значение на
 > время выполнения данного блока.  Т.е. она видна всегда, а ее данное
 > значение живет до выхода из этого блока, потом замещается внешним (для
 > случая рекурсии - там стек значений).
 
 Hу не совсем все так. Значение локальной переменной, как и любой другой,
 живет до тех пор пока не пропадет последняя ссылка на него. С выходом из
 блока исчезает локальная таблица имен для данного блока, и разыменование
 производится по локальным таблицам более "вышестоящего" уровня (для
 вложенных блоков) и глобальной таблице имен.
 
 ================= пример =======================
 #!/usr/bin/perl -w
 use strict;
 our $v = 'global';
 our $vref;
 
 sub so { print "test $_[0]: $v\n"; }
 sub sr { print "test $_[0]: $$vref\n"; }
 
 print "test 1: $v\n";
 
 {
      local $v = 'local';
      print "test 2: $v\n";
 
      sub si { print "test $_[0]: $v\n"; }
      $vref = \$v;
 
      so(3);
      si(4);
      sr(5);
 }
 
 so(6);
 si(7);
 sr(8);
 ================== вывод =====================
 test 1: global
 test 2: local
 test 3: local
 test 4: local
 test 5: local
 test 6: global
 test 7: global
 test 8: local
 
 Заметим, что test 8 выводит 'local'. При том, что
 вспомогательная переменная $vref никакой строки не
 содержит, а содержит лишь ссылку на значение. Выходит,
 что значение "живо" и после блока.
 
 Теперь посмотрим на модифицированный пример.
 
 ================= пример =======================
 #!/usr/bin/perl -w
 use strict;
 our $v = 'global';
 our $vref;
 
 sub so { print "test $_[0]: $v\n"; }
 sub sr { print "test $_[0]: $$vref\n"; }
 
 print "test 1: $v\n";
 
 {
      my $v = 'local scope';
      print "test 2: $v\n";
 
      sub si { print "test $_[0]: $v\n"; }
      $vref = \$v;
 
      so(3);
      si(4);
      sr(5);
 }
 
 so(6);
 si(7);
 sr(8);
 ================== вывод =====================
 test 1: global
 test 2: local scope
 test 3: global
 test 4: local scope
 test 5: local scope
 test 6: global
 test 7: local scope
 test 8: local scope
 
 Мы видим, что test 3 теперь выводит глобальную переменную.
 Почему? Потому, что переменная типа my не попадает в
 локальное пространство имен времени исполнения. Для нее
 существует свое пространство имен, разименование по которому
 происходит на этапе компиляции (оговорюсь, есть исключения,
 но сейчас о них упоминать ни к чему). test 7 теперь выводит
 local scope. Почему? Потому, что разименование этой переменной
 произошло на этапе компиляции тела функции si. И произошло это
 в зоне действия переменной типа my. Ссылка на значение это
 переменной была "запомнена" в скомпилированном коде функции
 si и функция si теперь печатает ее и только ее. Hесмотря на
 то, что "зону видимости" мы давно покинули. test 8 показывает,
 как и в прошлом примере, то, что и явные ссылки (а в примере 7
 была неявная) указывают на то значение, которое было "видно"
 в момент создания этой ссылки. Механизм ссылок таков, что они
 указывают не на имя, и не на запись в таблице имен, а на безымянное
 по своей природе значение. В данном случае под словом "значение"
 понимается не некоторое число/строка/и т.п., а безымянная структура -
 область памяти в которой хранится это число/строка/и т.п.. Т.е. если
 сразу после строки $vref = \$v; мы впишем $v = 'new value',
 то $vref, разумеется, будет указывать на то же "значение", но уже
 с новым "содержимым". Эта некоторая путаница с терминологией
 исторически сложилась, как результат внутренней организации
 переменных в интерпретаторе. Она не такова:
 
 Таблица имен (
     Запись в таблице имен 1 = [ИМЯ1, СОДЕРЖИМОЕ1],
     Запись в таблице имен 2 = [ИМЯ2, СОДЕРЖИМОЕ2],
     Запись в таблице имен 3 = [ИМЯ3, СОДЕРЖИМОЕ3],
     ...
 )
 
 а такова:
 
 Таблица имен (
     Запись в таблице имен 1 = [ИМЯ1, ССЫЛКА-HА-ЗHАЧЕHИЕ1],
     Запись в таблице имен 2 = [ИМЯ2, ССЫЛКА-HА-ЗHАЧЕHИЕ2],
     Запись в таблице имен 3 = [ИМЯ3, ССЫЛКА-HА-ЗHАЧЕHИЕ3],
     ...
 )
 
 Таблица значений (
      Значение1 = [счетчик ссылок, СОДЕРЖИМОЕ1],
      Значение2 = [счетчик ссылок, СОДЕРЖИМОЕ2],
      Значение3 = [счетчик ссылок, СОДЕРЖИМОЕ3],
      ...
 )
 
 конечно все это показано в сильно упрощенном виде. :) Данная
 конструкция гораздо более гибка, она например допускает
 существование "синонимов" - т.е. когда несколько записей
 указывают на одно значение. Допускает существование
 безымянных значений (как тех, которые стали безымянными
 по причине исчезновения записи в таблице имен при ненулевом
 счетчике ссылок, так и изначально безымянных)...
 
 Пока хватит для осмысления? Hа всякий случай перечитайте раза на
 три, после чего (если только я достаточно внятно пишу), все окажется
 предельно ясным, логичным, простым и единственно разумным настолько,
 что будет непонятно как до сих пор можно было во всем этом путаться :-)
 
 To: Artem Chuprina. Хотя этот постинг формально является ответом на
 твой (с целью цитирования), адресуется он, раземеется, в первую
 очередь новичкам :-)
 
 -- 
 Андрей
 --- ifmail v.2.15dev5.3
  * Origin: Demos online service (2:5020/400)
 
 

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

 Тема:    Автор:    Дата:  
 А есть ли в эхотаге рекурсия?   Alexander Pashchenko   01 Nov 2004 19:40:12 
 Re: А есть ли в эхотаге рекурсия?   Konstantin Tokar   01 Nov 2004 21:31:36 
 А есть ли в эхотаге рекурсия?   Alexander Pashchenko   02 Nov 2004 09:49:20 
 Re: А есть ли в эхотаге рекурсия?   Artem Chuprina   02 Nov 2004 13:45:17 
 А есть ли в эхотаге рекурсия?   Alexander Pashchenko   02 Nov 2004 23:38:00 
 Re: А есть ли в эхотаге рекурсия?   Artem Chuprina   03 Nov 2004 19:49:07 
 Re: А есть ли в эхотаге рекурсия?   Andrey Sapozhnikov   04 Nov 2004 19:09:55 
 Re: А есть ли в эхотаге рекурсия?   Artem Chuprina   02 Nov 2004 00:02:58 
 А есть ли в эхотаге рекурсия?   Alexander Pashchenko   02 Nov 2004 09:50:34 
Архивное /ru.perl/65770f68b45f.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional