Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Объявление и инициализация в цикле, Объявление и инициализация в цикле 
V
    Опции темы
ginnie
Дата 20.3.2008, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Уважаемые коллеги!
Извините за "детский" вопрос, но хочу для себя прояснить как работает объявление и инициализация внутри цикла:

Код

for $count (1..10) {
    my $test = 13 + $count;
    print $test;
}
 

На каждой итерации происходит только присвоение переменной $test нового значения, или что-то большее? Очень приветствуется ссылка на документацию!


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
GoDleSS
Дата 20.3.2008, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 105
Регистрация: 11.2.2007
Где: Пироговский

Репутация: 2
Всего: 2



Для начала perldoc -f my

Функция my объявляет переменную локальной для текущего блока.
Таким образом переменная, описанная my внутри цикла будет каждый раз "создаваться" по новой, а старые участки памяти будут стираться, за исключением случаев, когда на них уже что-либо ссылается.

Таким образом код
Код

for $count (1..10) {
    my $test = 13 + $count;
    print $test;
}

выведет 14..23 

Это сообщение отредактировал(а) GoDleSS - 20.3.2008, 15:45
--------------------
It's a nice day to die my friend!
PM MAIL WWW ICQ   Вверх
amg
Дата 20.3.2008, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



А вот такой дурацкий код что напечатает? Можете сказать, не проверяя? (Я бы не угадал smile )
Код

for $count (1..10) {
    $test = 13 + $count + my $test;
    print $test;
}

PM MAIL   Вверх
BlackLFL
Дата 20.3.2008, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 8
Всего: 12



такой код в обще не должен дать результат, т.к. переменная $test не объявлена до инициализации.
PM WWW   Вверх
KSURi
Дата 20.3.2008, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



То, что написал GoDleSS - логично, я всегда так и считал. Но вот сейчас начал сомневаться:
Код

C:\>perl -MDevel::Peek -e"for(1..5){my$test=int rand time;Dump $test}"
SV = IV(0x18274dc) at 0x182428c
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,IOK,pIOK)
  IV = 681182229
SV = IV(0x18274dc) at 0x182428c
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,IOK,pIOK)
  IV = 172098990
SV = IV(0x18274dc) at 0x182428c
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,IOK,pIOK)
  IV = 933110713
SV = IV(0x18274dc) at 0x182428c
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,IOK,pIOK)
  IV = 884638863
SV = IV(0x18274dc) at 0x182428c
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,IOK,pIOK)
  IV = 1151988534
C:\>

Меня смущает, что у всех $test один адрес в памяти. Если переменная каждый раз создается снова, то почему адрес всегда одинаковый?

Это сообщение отредактировал(а) KSURi - 20.3.2008, 16:08


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
ginnie
Дата 20.3.2008, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Уважаемый GoDleSS, на чем основана уверенность, что будет создаваться новая переменная? Спасибо за то, что навели на верную мысль!

код

Код

for my $count (1..10) {
    my $test = 13 + $count;
    print $test, ' ', \$test,"\n";
}


выводит

Код

14 SCALAR(0x804eac4)
15 SCALAR(0x804eac4)
16 SCALAR(0x804eac4)
17 SCALAR(0x804eac4)
18 SCALAR(0x804eac4)
19 SCALAR(0x804eac4)
20 SCALAR(0x804eac4)
21 SCALAR(0x804eac4)
22 SCALAR(0x804eac4)
23 SCALAR(0x804eac4)



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
BlackLFL
Дата 20.3.2008, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 8
Всего: 12



2ginnie, не успел запостить, я тоже провел аналогичный тест
Код

for my $count (1..10) 
{
    my $test = 13 + $count;
    test( \$test );
}

print "\n";

for my $count (1..10) 
{
    my $test = 13 + $count;
    test( \$test );
}

sub test
{
    my $var = shift;
    
    print $var;
    print "\n";
}

Цитата

SCALAR(0x226f7c)
SCALAR(0x226f7c)
SCALAR(0x226f7c)
SCALAR(0x226f7c)
SCALAR(0x226f7c)
SCALAR(0x226f7c)
SCALAR(0x226f7c)
SCALAR(0x226f7c)
SCALAR(0x226f7c)
SCALAR(0x226f7c)

SCALAR(0x1aaf368)
SCALAR(0x1aaf368)
SCALAR(0x1aaf368)
SCALAR(0x1aaf368)
SCALAR(0x1aaf368)
SCALAR(0x1aaf368)
SCALAR(0x1aaf368)
SCALAR(0x1aaf368)
SCALAR(0x1aaf368)
SCALAR(0x1aaf368)


Это сообщение отредактировал(а) BlackLFL - 20.3.2008, 16:12
PM WWW   Вверх
ginnie
Дата 20.3.2008, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



BlackLFL, почему не объявлена? Какая часть присваивания выполняется сначала левая или правая?


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
BlackLFL
Дата 20.3.2008, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 8
Всего: 12



Цитата

BlackLFL, почему не объявлена? Какая часть присваивания выполняется сначала левая или правая? 


тут это не имеет значения, Perl все-равно выдаст ошибку 
Цитата

Global symbol "$test" requires explicit package name


Это сообщение отредактировал(а) BlackLFL - 20.3.2008, 16:15
PM WWW   Вверх
amg
Дата 20.3.2008, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(BlackLFL @  20.3.2008,  16:14 Найти цитируемый пост)
тут это не имеет значения, Perl все-равно выдаст ошибку 
С use strict - безусловно. А без него?

PM MAIL   Вверх
BlackLFL
Дата 20.3.2008, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 8
Всего: 12



Цитата(amg @ 20.3.2008,  17:19)
Цитата(BlackLFL @  20.3.2008,  16:14 Найти цитируемый пост)
тут это не имеет значения, Perl все-равно выдаст ошибку 
С use strict - безусловно. А без него?

правый конечно
PM WWW   Вверх
amg
Дата 20.3.2008, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Что-то я понимаю, нифига не понимаю. И по поводу переменной с my в цикле (вроде, каждый раз должна новая пременная создаваться, по крайней мере, работает, как будто так оно и есть, но так ли на самом деле ?). И с тем своим дурацким кодом тоже не вполне ясно, в какой последовательности операции выполняются.

Добавлено через 4 минуты и 20 секунд
BlackLFL, но если сначала выполняется правая часть (я тоже в этом был уверен), то почему переменная в левой части оказывается неопределенной? 
PM MAIL   Вверх
BlackLFL
Дата 20.3.2008, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 15.9.2005
Где: Москва

Репутация: 8
Всего: 12



amg, кстати да ... интересно получается ...

Добавлено @ 17:10
мне так кажется, что my имеет какое-то волшебное умение применять undef ... а сам интерпретатор, лишь "опирается" на my, для создания таблицы имен ...

Это сообщение отредактировал(а) BlackLFL - 20.3.2008, 17:10
PM WWW   Вверх
ginnie
Дата 20.3.2008, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



amg, похоже на то, что локальная переменная становится видна (кроме непосредственного присваивания) в коде только начиная со следующей команды (после ';') в коде программы.
Например, в коде
Код

if (my $test = rand() and $test++) {
    print $test, "\n";
}


получаем Global symbol "$test" requires explicit package name в строке с условием

По поводу цикла показателен следующий пример
Код

for my $count (1..10) {
    my $test;
    $test = $test // $count;
    print $test, ' ', \$test,"\n";
}


Переменная создается один раз в области видимости, но при каждой итерации ей присваивается значение undef.


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
ginnie
Дата 20.3.2008, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Дальнейшие исследования показали, что в коде 
Код

my $test = 0;
for my $count (1..10) {
    $test = 13 + $count + my $test;
    print $test // 'undef', "\n";
}
print $test, "\n";


получаем результат
Код

undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
23


т.е. присваивание в цикле проиводится переменной $test, определенной выше цикла.



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0713 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.