Форум программистов, компьютерный форум, киберфорум
Perl
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
174 / 170 / 19
Регистрация: 31.08.2010
Сообщений: 573
1

Задачки на понимание Perl (Скользкие места Perl)

11.11.2014, 21:10. Показов 3133. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Задача на понимание списочных литералов

что выведет каждая из строк

Perl
1
2
3
$num = ('один', 'два', 'три'); say $num;
$i=0; $n=(++$i, ++$i, ++$i); say $n;
$i=0; $n=($i=1, $i=2, $i=3); say $n;
Подсказка: если вы знаете C/C++, то эту задачу вы быстро решите

P.S. Можно выделить данную статью в раздел "Важно"
2
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.11.2014, 21:10
Ответы с готовыми решениями:

Графика в Perl, как создать GIF в Perl.
Помогите создать GIF при помощи перла. И где взять модули?

Как обстоят дела с Perl 6 и Perl 5
Сразу скажу не являюсь Perl-программистом(ибо Python), но решил поинтерисоваться языком, и вот...

Запустить perl-скрипт из perl-скрипта
Доброго времени суток! Есть главный скрипт и ещё один. Последний нужно запустить из главного,...

Переводчик кода Си в Perl(Convert C to perl)
Нужна такая вещь, а в идеале код такой программы.

18
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,238
11.11.2014, 21:18 2
Цитата Сообщение от TheAthlete Посмотреть сообщение
что выведет каждая из строк
Я ответил правильно, в том числе из-за знания C/C++. Правда они однотипные.

Цитата Сообщение от TheAthlete Посмотреть сообщение
Можно выделить данную статью в раздел "Важно"
Собирать задачи для начинающих?Будет интересно порешать,а может и составить.
Хотелось бы также увидеть в важных тему - коллекцию полезных примеров( работа с файлами,XML,что-там еще есть ).
0
174 / 170 / 19
Регистрация: 31.08.2010
Сообщений: 573
11.11.2014, 22:16  [ТС] 3
Хотя думаю переименовать тему в "Скользкие места в Perl" или еще лучше "Perl. Священные знания" (по аналогии с книгой "Стивен Дьюхерст - C++. Священные знания"), т.к. планирую описывать вещи, на которые стоит обратить внимание.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
12.11.2014, 10:53 4
Что здесь важного? И чего здесь священного?
0
174 / 170 / 19
Регистрация: 31.08.2010
Сообщений: 573
12.11.2014, 12:29  [ТС] 5
Суть данной темы (как и аналогичной книги по C++) - указать на некоторые неочевидные моменты, подробно их описать и систематезировать. В той же книге по C++ ("С++. Свщенные знания"), описано в других книгах, того же Страуструпа или Мейерса, но сделано это в кратком виде, т.е. глянул на оглавление - выбрал тему, которая нужна и разобрался более глубоко с этой темой.

Если говорить в контексте Perl, то для большинства начинающих, а иногда и не только. не очевидно, что список (списочный литерал) и массив это разные вещи и, например, по-разному работают в скалярном контексте. И много других неочевидных моментов, которые в большинстве своем не влияют на работу с языком, но при наличии такой книги или темы, в которых данные вещи рассказываются и разбираются, позволяют еще на уровень подняться в знании языка и начать пользоваться языком более эффективно. Или будут стимулом, чтобы еще перечитать "Программирование на Perl" или почитать встроенную документацию.

Тоже самое можно сказать и про приоритет операторов (в том числе использовние низкоприоритетных операторов and, or), использование операторов ||, //, использование срезов хэшей и массивов вместо циклов (где это нужно) и т.д.
1
2304 / 1063 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
13.11.2014, 20:05 6
Пффф. Это разве не очевидные моменты.
Вот это вот не очевидно и скользко:
Perl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env perl
 
%foo = (foo   => "bar",
        baz   => "xyz",
        hello => "world",
        yoba  => "boba"
    );
 
while (my ($key, $value) = each %foo) {
    print "$key: $value\n";
    last if ($key eq "hello");
}
 
# ...
# тут много кода
# и мы давно забыли что выпрыгнули last-ом из цикла
# ...
 
while (my ($key, $value) = each %foo) {
    print "$key: $value\n";
}
2
174 / 170 / 19
Регистрация: 31.08.2010
Сообщений: 573
13.11.2014, 20:08  [ТС] 7
Тут я вижу проблему в архитектуре программы, а не в языке. Аналогичный код можно написать на любом другом языке.
0
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,238
13.11.2014, 20:11 8
Цитата Сообщение от nullxdth Посмотреть сообщение
Вот это вот не очевидно и скользко:
Признаю результат меня удивил.Надо правда в спойлере написать почему так происходит.Или сказать,где об этом хорошо написано.

Добавлено через 1 минуту
Цитата Сообщение от TheAthlete Посмотреть сообщение
Тут я вижу проблему в архитектуре программы, а не в языке. Аналогичный код можно написать на любом другом языке.
Не думаю,что внешне аналогичный код на другом языке выдаст тот-же результат.
0
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
13.11.2014, 21:25 9
Ух ты, интересно. Спойлер, наверно, ни к чему...
http://perldoc.perl.org/functions/each.html
After each has returned all entries from the hash or array, the next call to each returns the empty list in list context and undef in scalar context; the next call following that one restarts iteration. Each hash or array has its own internal iterator, accessed by each, keys, and values. The iterator is implicitly reset when each has reached the end as just described; it can be explicitly reset by calling keys or values on the hash or array.
http://perldoc.perl.org/functions/keys.html
As a side effect, calling keys() resets the internal iterator of the HASH or ARRAY (see each). In particular, calling keys() in void context resets the iterator with no other overhead.

Выделение моё.
3
174 / 170 / 19
Регистрация: 31.08.2010
Сообщений: 573
13.11.2014, 22:13  [ТС] 10
Цитата Сообщение от S_el Посмотреть сообщение
Не думаю,что внешне аналогичный код на другом языке выдаст тот-же результат.
Согласен, был не прав.

Суть в том, что каждый массив и хэш имеет внутренний итератор, доступный через each, key или value оператор (текст доки выше постом от helter).

Еще нашел интересный модуль: Hash::StoredIterator

Добавлено через 34 минуты
Еще пару ссылок:
How Hashes Really Work
PerlGuts Illustrated - смотреть тип HV, поле RITER (это тот самый итератор (internal iterator))

Perl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/env perl -w
use strict;
use warnings;
use feature 'say';
 
use Devel::Peek;
 
my %foo = (foo   => "bar",
        baz   => "xyz",
        hello => "world",
        yoba  => "boba"
    );
 
while (my ($key, $value) = each %foo) {
    say "$key: $value";
    Dump \%foo;
    last if $key eq "hello";
    #keys %foo && last if $key eq "hello";
    #$key eq "hello" && keys %foo && last;
}
 
say '---';
 
# ...
# тут много кода
# и мы давно забыли что выпрыгнули last-ом из цикла
# ...
 
while (my ($key, $value) = each %foo) {
    say "$key: $value";
    Dump \%foo;
}
Вывод следующий: ищем RITER
Кликните здесь для просмотра всего текста
hello: world
SV = IV(0x1502040) at 0x1502050
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x150c8e8
SV = PVHV(0x14eaff0) at 0x150c8e8
REFCNT = 2
FLAGS = (PADMY,OOK,SHAREKEYS)
ARRAY = 0x15059b0 (0:4, 1:4)
hash quality = 137.5%
KEYS = 4
FILL = 4
MAX = 7
RITER = 1
EITER = 0x14f8580
RAND = 0xfd0de954
Elt "foo" HASH = 0xe434ff8
SV = PV(0x14e4a50) at 0x14e3cb8
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x14fc000 "bar"\0
CUR = 3
LEN = 16
Elt "baz" HASH = 0xcab9a9e3
SV = PV(0x14e4b60) at 0x14e3f28
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x150e440 "xyz"\0
CUR = 3
LEN = 16
Elt "hello" [CURRENT] HASH = 0xd9f3a09d
SV = PV(0x14e4be0) at 0x1502020
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x1521dc0 "world"\0
CUR = 5
LEN = 16
---
yoba: boba
SV = IV(0x1502040) at 0x1502050
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x150c8e8
SV = PVHV(0x14eaff0) at 0x150c8e8
REFCNT = 2
FLAGS = (PADMY,OOK,SHAREKEYS)
ARRAY = 0x15059b0 (0:4, 1:4)
hash quality = 137.5%
KEYS = 4
FILL = 4
MAX = 7
RITER = 3
EITER = 0x14f8658
RAND = 0xfd0de954
Elt "foo" HASH = 0xe434ff8
SV = PV(0x14e4a50) at 0x14e3cb8
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x14fc000 "bar"\0
CUR = 3
LEN = 16
Elt "baz" HASH = 0xcab9a9e3
SV = PV(0x14e4b60) at 0x14e3f28
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x150e440 "xyz"\0
CUR = 3
LEN = 16
Elt "hello" HASH = 0xd9f3a09d
SV = PV(0x14e4be0) at 0x1502020
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x1521dc0 "world"\0
CUR = 5
LEN = 16
foo: bar
SV = IV(0x1502040) at 0x1502050
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x150c8e8
SV = PVHV(0x14eaff0) at 0x150c8e8
REFCNT = 2
FLAGS = (PADMY,OOK,SHAREKEYS)
ARRAY = 0x15059b0 (0:4, 1:4)
hash quality = 137.5%
KEYS = 4
FILL = 4
MAX = 7
RITER = 4
EITER = 0x14f85b0
RAND = 0xfd0de954
Elt "foo" [CURRENT] HASH = 0xe434ff8
SV = PV(0x14e4a50) at 0x14e3cb8
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x14fc000 "bar"\0
CUR = 3
LEN = 16
Elt "baz" HASH = 0xcab9a9e3
SV = PV(0x14e4b60) at 0x14e3f28
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x150e440 "xyz"\0
CUR = 3
LEN = 16
Elt "hello" HASH = 0xd9f3a09d
SV = PV(0x14e4be0) at 0x1502020
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x1521dc0 "world"\0
CUR = 5
LEN = 16
baz: xyz
SV = IV(0x1502040) at 0x1502050
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x150c8e8
SV = PVHV(0x14eaff0) at 0x150c8e8
REFCNT = 2
FLAGS = (PADMY,OOK,SHAREKEYS)
ARRAY = 0x15059b0 (0:4, 1:4)
hash quality = 137.5%
KEYS = 4
FILL = 4
MAX = 7
RITER = 7
EITER = 0x14f8598
RAND = 0xfd0de954
Elt "foo" HASH = 0xe434ff8
SV = PV(0x14e4a50) at 0x14e3cb8
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x14fc000 "bar"\0
CUR = 3
LEN = 16
Elt "baz" [CURRENT] HASH = 0xcab9a9e3
SV = PV(0x14e4b60) at 0x14e3f28
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x150e440 "xyz"\0
CUR = 3
LEN = 16
Elt "hello" HASH = 0xd9f3a09d
SV = PV(0x14e4be0) at 0x1502020
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x1521dc0 "world"\0
CUR = 5
LEN = 16


Добавлено через 1 минуту
Хотя в PHP each так же работает, т.е. создает итератор. Про другие языки не знаю

Добавлено через 1 минуту
PHP each doc
1
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,238
13.11.2014, 22:15 11
Итераторы в perl,для меня сложноваты,но на заметку возьму.
0
5989 / 1998 / 323
Регистрация: 10.12.2013
Сообщений: 6,882
14.11.2014, 01:22 12
Цитата Сообщение от S_el Посмотреть сообщение
Признаю результат меня удивил.Надо правда в спойлере написать почему так происходит.Или сказать,где об этом хорошо написано.
а вот и спойлер: Дело в том, что Ларри большой эстет в том смысле, что пытается притянуть языковые конструкции ЯП к живому английскому языку, стало быть и к естественным человеческим привычкам; если помнить об этом и возвратиться к разбираемому примеру, взяв за аналогию чтение книги, то никакой 'скользкости' нет в том, что читая книгу и отвлекшись на что-либо, вернувшись ты продолжаешь чтение с той же страницы, а не открываешь книгу заново.

Добавлено через 43 минуты
внутренним статусом обладает также и оператор интервала ( .. ), в скалярном контексте
называемый флип-флоп оператором.

ещё раз: оператор интервала в списочном контексте вернёт список,
а в скалярном контексте он называется flip-flop оператор и хранит свои состояния.
строго говоря, этих операторов два: ( .. ) и (...)

Хороши они тем, что позволяют в самом естественном виде реализовать например такую ситуацию:

"Сидоров, копать будешь от этого забора и до обеда".


на практике выглядит это так:

Задача - вывести содержимое файла, начиная от 5-ой строки и до слов "грузите апельсины в бочках".

Реализация:
Perl
1
perl -E 'print if 5 .. /грузите апельсины в бочках/ ' телеграмма.txt
то есть, реализация совпадает с точностью до слова с формулировкой выданного задания и даже выглядит короче !!

ни в каком другом ЯП этого нет.

Добавлено через 7 минут
правка: в примере должно быть конечно perl -nE
3
5989 / 1998 / 323
Регистрация: 10.12.2013
Сообщений: 6,882
18.04.2018, 04:32 13
Цитата Сообщение от TheAthlete Посмотреть сообщение
Задача на понимание списочных литералов
Perl
1
$num = ('один', 'два', 'три'); say $num;
Можно придраться к автору темы, отметив, что в приведённом коде в правой части нет списочных литералов,
а есть обычное перечисление, потому что в левой части находится железобетонный скаляр и
никакие круглые скобки справа это обстоятельство отменить не могут.

Придумал вопрос для тестового задания.

Что увидишь на экране после выполнения нижеследующих вариантов ?

Perl
1
2
3
4
5
6
7
8
9
10
11
use feature 'say';
 
$num   =    ('один', 'два', 'три');     say "1: $num";
 
($num) =    ('один', 'два', 'три');     say "2: $num";
 
$num   =    <'один', 'два', 'три'>;     say "3: $num";
 
$num   =    qw('один', 'два', 'три');   say "4: $num";
 
@$num  =    ('один', 'два', 'три');     say "5: @$num";
Хочу отметить, что вариант 3 - это для настоящих зубров Perl-программирования ))


отгадка:
Кликните здесь для просмотра всего текста
1: три
2: один
3: один,
4: 'три'
5: один два три
0
48 / 22 / 3
Регистрация: 21.06.2013
Сообщений: 92
30.04.2018, 08:33 14
Попытаюсь ответить цитатами из 4-й книги с Верблюдом (которое не русском).

Perl
1
$num   =    ('один', 'два', 'три');     say "1: $num";
скалярное присваивание:

Perl
1
$stuff = ("один", "два", "три");
присваивает только значение «три» переменной $stuff (с. 105).

Perl
1
($num) =    ('один', 'два', 'три');     say "2: $num";
Тут в $num попадёт "один", все остальные отбросятся.

Perl
1
$num   =    <'один', 'два', 'три'>;     say "3: $num";
Мастер! Тут-то почему 'один'? Ответь!

Perl
1
$num   =    qw('один', 'два', 'три');   say "4: $num";
Опять присваивание размера списка скаляру.

Perl
1
@$num  =    ('один', 'два', 'три');     say "5: @$num";
Тут некоей самооживлённоой разыменованной ссылке на массив...
0
5989 / 1998 / 323
Регистрация: 10.12.2013
Сообщений: 6,882
30.04.2018, 14:00 15
Цитата Сообщение от hobo-mts Посмотреть сообщение
Perl
1
$num   =    qw('один',  'два',  'три');   say "4: $num";
Опять присваивание размера списка скаляру.
Kстати, совсем не тривиальный тест. Я сам себе ответил на него неправильно.
Нет тут никакого присваивания списка скаляру, потому что список справа не самооживляется,
несмотря на оператор qw, явно возвращающий список.
Данный пример вместо явления чуда самооживления массива опять преобразовался к варианту #1 - простому перечислению.

Настоящая подножка мастеру манежа.

Таким образом товарищи сверху дают нам понять, что список - это таки не массив.


Теперь переходим к алмазам <>.

Perl
1
$num   =    <'один', 'два', 'три'>;     say "3: $num";
Здесь я сам себе ответил правильно. Почти.
Правильно - это потому что догадался, что возвратится 'один'.
Почти - это потому, что возвратился не 'один',, а один, без кавычек.
А это в свою очередь означает то, что при реализации функции glob, которую вызывают алмазы,
участвует и функция eval, которая сдёргивает одинарные кавычки.

Почему 'один', а не 'три' ? А потому что функция glob в скалярном контексте работает как флип-флоп
оператор, внутри неё живёт итератор, который обеспечивает возвращение следующего возможного значения
при каждом обращении.

Легко проверить:

for ( 1 .. 2 ) {
$num = glob(" 'один' 'два' 'три' ");
}
say $num;

output: два
0
1 / 1 / 0
Регистрация: 18.08.2021
Сообщений: 31
08.04.2023, 02:35 16
Подскажите новичку, как с
Perl
1
say $num;
работать?
Не совсем понимаю предназначения данной функции.
В терминале не выводит результат, если другой пример ввожу, то ошибка.
Я зеаю, что с языком Raku нет проблем с данной функцией, а что с Perl объясните пожалуйста.
0
5989 / 1998 / 323
Регистрация: 10.12.2013
Сообщений: 6,882
08.04.2023, 10:45 17
в perl функция say появилась не сразу, поэтому она подключаемая.
Bash
1
perldoc -f say
1
314 / 41 / 9
Регистрация: 08.04.2022
Сообщений: 160
08.04.2023, 11:06 18
О! Движуха в разделе.

Цитата Сообщение от MetH92 Посмотреть сообщение
Подскажите новичку
say это новая функция, появившаяся, кажется, в Perl 5.10 и по умолчанию не поддерживается.

Чтобы активировать надо

в командной строке:
Bash
1
2
perl -E 'say 42'
perl -Mv5.10 -e 'say 42'
в файле:
Perl
1
2
3
4
5
#!/usr/bin/env perl
 
use v5.10;
 
say 42;
Добавлено через 4 минуты
Цитата Сообщение от volodin661 Посмотреть сообщение
вариант 3
Цитата Сообщение от hobo-mts Посмотреть сообщение
Perl
1
$num = <'один', 'два', 'три'>; say "3: $num"
Зная, что <> может быть (сам использовал такое) синонимом функции glob, предполагал пустое значение в $num. Проверил и удивился. Ваше объяснение надо осмысливать.

Я не зубр )))
0
5989 / 1998 / 323
Регистрация: 10.12.2013
Сообщений: 6,882
08.04.2023, 14:41 19
Цитата Сообщение от siberian-man Посмотреть сообщение
Ваше объяснение надо осмысливать.
моё обьяснение нуждается в подтверждении путём просмотра исходных текстов perl

Добавлено через 2 часа 10 минут
очень полезно просматривать старые темы,
а ещё полезнее во время просмотра старых тем углубляться в RTFM ( read the fucking manual ).

в частности, просматривая эту тему, прочитал внимательно про функцию each(а также keys и values),
где обнаружились её забытые особенности, а именно:

при циклическом обращении к each она итеративно отдаёт пары ключ/значение для HASH ( или индекс/значение для ARRAY ), затем она иссякает и возвращает пустой список () в списковом контексте или undef в скалярном контексте,
а затем возрождается( reset ), как феникс из пекла, и начинает всё с начала.
0
08.04.2023, 14:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.04.2023, 14:41
Помогаю со студенческими работами здесь

Авторизация на Perl (сессии на perl)
Привет. Учусь значит, сказали сделать небольшой сайт на perl, нужно сделать так, чтобы страницы...

Запуск perl script linux, linux+java+perl
Добрый день. Работаю на Линуксе. Есть perl script, который переносит данные из дбф в postgresql....

Запуск скрипта Perl из скрипта Perl
Доброго времени суток! Подскажите/направьте, как собственно запустить скрипт из скрипта и получить...

Perl Tk
Здраствуйте.Подскажыте как в Тk,передвигать кнопки и другое в разном направления.Зарание спасибо.

Perl TK
Ребята нужен совет , хочу сделать приложение с gui остановился на perl Tk но есть одна проблема...

Perl
Здравствуйте. Как настроить Apache для работы с perl? Прописал в httpd.conf # If the perl module...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru