Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Ваш стиль программирования на Perl


Автор: sir_nuf_nuf 27.8.2008, 10:26
Привет всем!

Какой стиль программирования на perl вам ближе:
1) со множеством перловых фишек и изворотов
2) строгий ООП стиль, а-ля java
3) что другое
?

Задаю этот вопрос, т.к. самому перл понравился за скороговорку, за возможность быстро делать сложные вещи.
Но по мере работы над проектом  замечаю, что такой код плохо поддерживается (особенно, если писал его другой человек),
потихоньку код приходит к виду a-la java, со множеством мелких классов, get/set, паттерны и все такое..
может я просто не постиг ДАО перла и на самом деле надо все писать процедурными скриптами ?

П.С. извиняюсь, если флейм.. 

Автор: ginnie 27.8.2008, 11:06
Уважаемый sir_nuf_nuf, стиль написания часто зависит от постановки задачи: если быстродействие кода не является определяющим фактором при разработке, то лучше писать понятный другим разработчикам код, т.е. без особых "изворотов" (использование уникальных для Perl конструкций только там, где они действительно уместны). Если же приоритетом является производительность кода, то тут бывает такое...  smile 

Автор: nitr 27.8.2008, 11:27
Perl-style был и будет, если придерживаться этих рамок, то всем любые извороты будут понятны. Сколько "читал" код программистов, всегда был рад, что пишут в этом стиле, иначе ни поддержка. ни поиск ошибок/недочетов, да вообще многое сводится к нулю.
Тут имхо всё равно ООП или только извороты, или извороты+ООП smile

perldoc perlstyle ;)

Добавлено через 1 минуту и 19 секунд
Цитата(sir_nuf_nuf @  27.8.2008,  10:26 Найти цитируемый пост)
потихоньку код приходит к виду a-la java, со множеством мелких классов, get/set, паттерны и все такое..

это просто ООП в его "понимании" и реализации на любом языке. Почему Perl должен отличаться, если задача реально того стоит и реализация её этого требует - то да.

Автор: ginnie 27.8.2008, 11:36
Уважаемый nitr, а вот такой код Вам понятен?

Код

print "some text and @{[time]}";

Автор: gcc 27.8.2008, 11:50
Цитата(ginnie @ 27.8.2008,  11:06)
быстродействие кода не является определяющим фактором при разработке, то лучше писать понятный другим разработчикам код, т.е. без особых "изворотов" (использование уникальных для Perl конструкций только там, где они действительно уместны). Если же приоритетом является производительность кода, то тут бывает такое...  smile

Уважаемый ginnie, а что именно под быстродействием имееться ввиду, использовать всегда хэш и не использовать процедуры в которыйх функции будут внутри другой функции?

компьтеры дешевеют, можно поставить 8Gb RAM  smile 
JAVA весь на ООП, но он требовательный к ресурсам...

Автор: nitr 27.8.2008, 12:01
ginnie, мне да. Но кто так писать будет? smile
И так 
Код
print "some text and ".time;

Автор: ginnie 27.8.2008, 12:01
Уважаемый gcc,

Цитата

а что именно под быстродействием имееться ввиду


думаю, для Вас не будет открытием, что в Perl один и тот-же результат можно получить несколькими способами. Время выполнения для разных способов отличается и если важна проиводительность кода, то приходится выбирать варианты, читаемость и понятность которых оставляет желать лучшего.

Например, задача преобразования IP-адреса из формата xxx.xxx.xxx.xxx в int (для сохранения в БД).  Самый быстрый вариант

Код

my $ip_int = unpack("N", pack("C4", split(/\./, $ip)));


Цитата

компьтеры дешевеют, можно поставить 8Gb RAM


У нас памяти в сервере больше 8 Гб, все равно не хватает  smile  Все зависит от решаемых задач.

Автор: nitr 27.8.2008, 12:03
лично такое "изворотом" не называю...

Добавлено через 2 минуты и 15 секунд
Цитата(ginnie @  27.8.2008,  12:01 Найти цитируемый пост)
Время выполнения для разных способов отличается и если важна проиводительность кода, то приходится выбирать варианты, читаемость и понятность которых оставляет желать лучшего.

 smile
Можно всё же это совмещать... Согласен не во всех случаях, но можно в "таких местах" оставлять комменты...

Добавлено через 3 минуты
За кодером не убудет...

Автор: Bulat 27.8.2008, 12:20
Побольше багов и косяков  smile 

ИМХО, если что-то небольшое и не очень функциональное(без огромного количества всяких фич), то проще писать по процедурному. Но если что-то многофункциональное, то лучше прибегать к ООП. Но мулька-то в этом, хошь так, хошь так. smile

Автор: ginnie 27.8.2008, 13:33
Уважаемый nitr, специально для Вас шедевр нетривиального мышления:

Код

sub next_power_of_two {
    my %s;
    @s{1..shift} = ();
    local $_ = %s;
    return m{/(.*)};
}

Автор: korob2001 27.8.2008, 16:08
Я лично по возможности использую только ООП. Правда далеко не все мудули на CPAN объектно ориентированы.

Автор: nitr 27.8.2008, 17:21
ginnie, спасибо smile Человек, который не знает Perl, не поймет "что тут творится"...

Автор: ginnie 27.8.2008, 17:41
nitr, я минут 15 разбирался  smile 

Автор: AlexPet 27.8.2008, 18:19
Люблю perl-style. Наверное, поэтому его (perl) и использую.
ООП примерно везде одинаково, и навевает скуку :(
Возможно, оффтоп, но в последнее время столкнулся с тем, что для высокопроизводительных математических вычислений перл все же слабоват. Даже XS модули не спасают. Приходится все же использовать либо Maple\MatLab для мат.экспериментов, либо C (по слухам, Python тоже в математике преуспел, но так до него руки и не дошли) для продакшн. Жаль :(


ginnie, возможно я не понял Ваш пример с next_power_of_two, но там всегда будет выводиться 1 в случае подачи на вход n >= 1.

Автор: ginnie 27.8.2008, 18:30
Уважаемый AlexPet, интересно, как это C-код работает нормально, а XS-модули не спасают?

Цитата

там всегда будет выводиться 1 в случае подачи на вход n >= 1


советую провести полевые испытания функции  smile 

Автор: AlexPet 27.8.2008, 19:08
ginnie, а вот так. Например, столкнулся на днях с тем, что Math::Prine::XS в некоторых случаях вылетает с ошибкой "Ошибка сегментации", а некоторых работает медленнее самописных функций. Просто тут меня затянуло в http://projecteuler.net (не сочтите за рекламу, я не имею никакого отношения к этому ресурсу), а там нужно считать оочень много и ооочень быстро.


Цитата(ginnie @  27.8.2008,  18:30 Найти цитируемый пост)
советую провести полевые испытания функции

Давайте по порядку, может я чего не понимаю?

Цитата(ginnie @  27.8.2008,  13:33 Найти цитируемый пост)

sub next_power_of_two {    
my %s;    
1: @s{1..shift} = ();    
2: local $_ = %s;    
3: return m{/(.*)};
}


Разбираем по строкам.
1) Создаем ключи в хеше от 1 до поданного в функцию значения (пусть это будет n), значения которых - undef
2) локализуем переменную $_ и заносим в нее значение хеша в скалярном контексте. Это будет "k/b", где k - количество ключей, b - точно не скажу, но вроде как количество отведенной памяти под хеш...
3) проверяем регулярным выражением {/(.*)} на совпадение (а оно будет, если n>=1, иначе выдаст ошибку (на нечисловых значениях еще при заполнении хеша); при n < 1 совпадения не будет )
После чего return (по крайне мере у меня) трактует m{/(.*)} в скалярном контексте (а не списочном, поэтому ему по барабану группирующие скобки в регулярном выражении), и возвращает 1 в случае совпадения (n>=1), 0 иначе

Поправьте, если что не так. Испытания провел, вроде все так.

Добавлено через 12 минут и 29 секунд
Кстати, на злобу дня: http://habrahabr.ru/blogs/perl/38014/

Автор: ginnie 27.8.2008, 19:29
Уважаемый AlexPet, Вы правы, я не обратил внимание на контекст для регулярного выражения. Он зависит от контекста вызова функции next_power_of_two(). Указанный выше вариант верно работает в списочном контексте (например print next_power_of_two(7);)

Про чужие XS-модули понятно, я имел ввиду свои XS-модули на основе корректно работающего C-кода.

Автор: AlexPet 27.8.2008, 19:58
Вот покопался в perldata и вот что вычитал:

Цитата

If you evaluate a hash in scalar context, it returns false if the hash is empty. If there are any key/value pairs, it returns true; more precisely, the value returned is a string consisting of the number of used buckets and the number of allocated buckets, separated by a slash. This is pretty much useful only to find out whether Perl's internal hashing algorithm is performing poorly on your data set. For example, you stick 10,000 things in a hash, but evaluating %HASH in scalar context reveals "1/16", which means only one out of sixteen buckets has been touched, and presumably contains all 10,000 of your items. This isn't supposed to happen.


Однако перл обычно выделяет число сегментов памяти под хэш как "min k, 2^k > n" (где n - количество элементов в хеше; установлено экспериментальным путем  smile )
Только в том-то и дело, что "обычно". Например:
n next_power_of_two
1..7 8
8 16
9 16
...
1023 1024
1024 1024

Так что я бы относился с осторожностью к значению, выдаваемому этой функцией  smile И кто знает, что она так себя регулярно ведет на всех платформах? Хотя все может быть.

Автор: nitr 27.8.2008, 21:47
AlexPetginnie
Код
#!/usr/bin/perl
use strict;
use warnings;

warn next_power_of_two(1023);
warn next_power_of_two(1024);
warn next_power_of_two(1025);

sub next_power_of_two {
    my %s;
    @s{1..shift} = ();
    local $_ = %s;
    return m{/(.*)};
}

Цитата
1024 at c:\1.pl line 5.
1024 at c:\1.pl line 6.
2048 at c:\1.pl line 7.


Вот размышления человека и его тесты smile http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html
А вот http://www.mathworks.com/access/helpdesk/help/techdoc/index.html?/access/helpdesk/help/techdoc/ref/nextpow2.html&http://www.mathworks.com/cgi-bin/texis/webinator/search/?db=MSS&prox=page&rorder=750&rprox=750&rdfreq=500&rwfreq=500&rlead=250&sufs=0&order=r&is_summary_on=1&ResultCount=10&query=nextpow2&submitButtonName=Search

У меня возник вопрос, что не так с функцией? smile
А какой контекст подразумевался ещё? Или как вы пытались использовать?

А вот насколько я в курсе "нормальная" реализация smile))
Код
sub next_power_of_two {
    my $x = shift;
    $x = $x - 1;
    $x = $x | ($x >> 1);
    $x = $x | ($x >> 2);
    $x = $x | ($x >> 4);
    $x = $x | ($x >> 8);
    $x = $x | ($x >> 16);
    return ($x + 1);
}


Добавлено через 6 минут и 59 секунд
 smile 

Автор: ginnie 27.8.2008, 22:40
Уважаемые коллеги, хочу обратить ваше внимание, что функцию я привел не как пример рабочего кода, а как пример кода, использующего нюансы Perl и трудного для понимания другими разработчиками.

Уважаемый nitr, результат поиска по шаблону (рег. выражения в конце функции) зависит от контекста, в котором он выполняется, а этот контекст в свою очередь зависит от контекста вызова функции. В скалярном контексте возвращает 1 (совпадение найдено) или 0 (не найдено), в списочном - захваченную скобками подстроку.

Код

my $test = next_power_of_two(7);                      
warn $test;


выведет 1

 smile
Хотел прояснить для себя правильное название контекста. Я всегда пишу списочный, некоторые коллеги, а также КэмелБук (в некоторых местах) используют слово списковый. Посмотрел на сайте gramota.ru: списочный - такое слово есть, а списковый - нет. Может кто-нибудь прояснить ситуацию (у меня в школе тройка была по русскому языку   smile ) 

Автор: nitr 28.8.2008, 01:00
Цитата(ginnie @  27.8.2008,  22:40 Найти цитируемый пост)
Уважаемые коллеги, хочу обратить ваше внимание, что функцию я привел не как пример рабочего кода, а как пример кода, использующего нюансы Perl и трудного для понимания другими разработчиками.

лично это я понял smile Я просто привел, более читабельный и думаю далеко "немедленный" код ;) Попрошу многоуважаемого amg сказать своё мнение по поводу производительности.

Цитата(ginnie @  27.8.2008,  22:40 Найти цитируемый пост)
Уважаемый nitr, результат поиска по шаблону (рег. выражения в конце функции) зависит от контекста, в котором он выполняется, а этот контекст в свою очередь зависит от контекста вызова функции. В скалярном контексте возвращает 1 (совпадение найдено) или 0 (не найдено), в списочном - захваченную скобками подстроку.

Спасибо. А то я не понял, что вы имели ввиду smile Это уже считаю "недоработкой" данного кода, но как уже говорилось выше - он всего лишь пример... Тем более недавно обсуждали такой подход return /regexp/.

Как выход:
Код
return $1 if m{/(.*)};

Автор: korob2001 28.8.2008, 11:12
Цитата(ginnie @  27.8.2008,  19:40 Найти цитируемый пост)
Хотел прояснить для себя правильное название контекста. Я всегда пишу списочный, некоторые коллеги, а также КэмелБук (в некоторых местах) используют слово списковый. Посмотрел на сайте gramota.ru: списочный - такое слово есть, а списковый - нет. Может кто-нибудь прояснить ситуацию (у меня в школе тройка была по русскому языку

Мне кажется, что всё же правильно будет - СПИСКОВОЙ контекст, по крайней мере в большинстве книг, употребляется именно это слово.

Автор: ginnie 28.8.2008, 11:22
Уважаемый korob2001, слово СПИСКОВОЙ в словорях на gramota.ru тоже отсутствует. Интересует правильный вариант именно с точки зрения правил русского языка (т.к. писать с ошибками в нашем возрасте уже неприлично  smile ).

Добавлено через 2 минуты и 42 секунды
Уважаемый nitr, приведенная мной функция next_power_of_two() никоим образом не является более производительным вариантом.

Автор: nitr 28.8.2008, 12:03
ginniesmile Тогда интересно чем руководствовался человек, который писал данный код, т.к. из лит-ры он должен был написать второй код smile Тут больше на "магию" Perl похоже...

Я тоже считаю "Списковый". Надо взять словообразовательный словарь, найти слово "список" и посмотреть, какое "прилагательное" из него образовывается smile

Мдя...
Цитата
СПИСОЧНЫЙ прил.
Соотносящийся по знач. с сущ.: список, связанный с ним.

Свойственный списку (1), характерный для него.

Названный в списке (1).


НО!!! в Гугле не нашёл "списочный элемент", в таком же контексте как "списковый элемент" smile
Скорее всего будет верно все предложения/словосочетания приводить к слову "список".
Например, списковый/списочный элемент - элемент списка smile

http://www.codenet.ru/webmast/perl/CGI-Perl.php
Цитата
Для того чтобы форсировать скалярный контекст, можно использовать оператор scalar. 

$x = localtime;                       # скалярный контекст
@time = localtime;                    # списочный контекст
($sec,$min,$hour) = localtime[0,1,2]; # списочный контекст
print scalar localtime;               # скалярный контекст

Значением списка в скалярном контексте является длина списка: 

В этой статье списочный. Но как-то не по-русски читается smile)) Я буду склоняться к словосочетаниям "элемент списка" smile

Автор: Bulat 28.8.2008, 13:01
Цитата(ginnie @  28.8.2008,  11:22 Найти цитируемый пост)
слово СПИСКОВОЙ в словорях на gramota.ru тоже отсутствует.


списковой - такого слова и в викисловаре нет, а вот списковый - в викисловаре присутствует, но статья незавершенная


Цитата(nitr @  28.8.2008,  12:03 Найти цитируемый пост)
Скорее всего будет верно все предложения/словосочитания приводить к слову "список".
Например, списковый/списочный элемент - элемент списка


Это все нуна копать в морфологию smile

Автор: korob2001 29.8.2008, 21:11
Цитата(ginnie @  28.8.2008,  08:22 Найти цитируемый пост)
Уважаемый korob2001, слово СПИСКОВОЙ в словорях на gramota.ru тоже отсутствует. Интересует правильный вариант именно с точки зрения правил русского языка (т.к. писать с ошибками в нашем возрасте уже неприлично

Только что посмотрел в книгах по Perl.

Perl - Специальный справочник (Стивен Холзнер).
Стр. 70
Цитата

Скалярный и списковый контексты - это два основных контекста данных в языке Perl.

И в той же книге, на следующей странице:
Стр. 71
Цитата

Например, можно вывести список (1, 2, 5) в списковом контексте.


Самоучитель Perl (Матросов, Чаунин)
Стр. 53
Цитата

В списковом контексте конструктор массива будет иметь значение, равное значению последнего элемента списка:


Программирование на Perl 3-издание (Уолл, Кристиансен, Орвант).
Стр. 105
Цитата

Есть два основных контекста: скалярный и списковый.
 
Если честно, раньше особого внимания не обращал на это, потому пологал, что везде написано именно так. Дальше смотреть не стал, ежу понятно, что как кому хочется так и тот и пишет. ;))))))

Автор: gcc 29.8.2008, 21:32
проще list smile 

Автор: nitr 29.8.2008, 22:15
korob2001, да, поэтому и возник у ginnie вопрос, как верно smile
Получается "переводам" можно не верить, а такие "бренды" их готовили, странно. Я проверил, ни в одном современном или советском словаре нет слова "списковый", от слова "список" образуется "списочный" и это будет верно так писать, как бы не казалось, что язык ломается от такого произношения, имхо, дело привычки smile .

Будем считать что слово "списковый" - perl'овый сленг smile. Кто "за"?

Автор: KSURi 30.8.2008, 02:40
Lingvo говорит, что "списковый" - list-oriented, а "списочный" - просто "list". В оригинальной документации везде используется словосочетание "list context". Да и просто "списковый" как-то не звучит)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)