Представьтесь, пожалуйста

Имя пользователя:
Пароль:
(забыли пароль?)

 Why Perl sucks?

Возможно, "sucks" это слишком грубое слово, но по аналогии с "Why C sucks" и "Why C++ sucks" это, вероятно, подходящий заголовок.

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

Тон этой статьи не задуман как негативный. Я думаю нам будет полезно знать о слабых местах используемых языков программирования, особенно популярных, чтобы мы были уверены что эти слабости не попадут в другие языки.

Итак, вот мой список проблем в Perl:

  1. Нет наследования объектов.

    Наследование в Perl реализовано через массив @ISA (произносится как "is a", как в "this is a problem"), который разрешает вам вызывать методы из одного пакета через ссылку bless-нутую в другой пакет. Например, если SomeClass содержит SomeOtherClass в его глобальном массиве @ISA, то вы можете вызвать любой метод SomeOtherClass напрямую через ссылку bless-нутую в SomeClass.

    К несчастью, не существует настоящего способа унаследовать объекты из другого класса в Perl, можно наследовать только их методы. Обычно используемый workaround - из конструктора класса, который хочет наследовать, вызывается конструктор класса, который наследуется, чтобы получить объект, добавить свои собственные поля в хеш, и потом пере-bless-нуть объект в ваш класс:

    package SomeClass;
    use SomeOtherClass;
    
    @ISA = 'SomeOtherClass';
    
    sub new {
    	my $class = shift;
    
    	# create a new SomeOtherClass object:
    	my $self = $class->SUPER::new;
    
    	# mess with it:
    	$self->{'_something'} = 1;
    	$self->{'_something_else'} = 2;
    
    	# now bless it into SomeClass:
    	bless($self, $class);
    	return $self;
    }
    
    1;
    

    Проблема заключается в том, что это нарушает законы инкапсуляции и абстрагирования: вам требуется знать детали реализации объекта, который вы наследуете, и потом вы влезаете прямо внутрь и работаете с его полями напрямую. Вы можете объявлять глобальные переменные в одном пакете, писать процедуры для манипулирования этими переменными, потом наследовать эти процедуры... но это всё не то.

    С учётом бесчисленного количества объектно-ориентированных модулей на CPAN легко забыть, что Perl был изначально спроектирован как чисто структурный язык программирования. Такие моменты делают абсолютно ясным: ОО в Perl это на самом деле не более чем bless-нутые ссылки и немного синтаксического сахара.

  2. Счётчик ссылок.

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

    Проблема возникает, когда у вас есть две переменные ссылающиеся друг на друга, вроде родительского хеша и хеша ребёнка, которые обе содержат ссылки друг на друга. Поскольку ничей счётчик не может быть уменьшен до нуля пока последняя ссылка не уничтожена, один не может быть освобождён пока не освобождён второй, и в результате они оба остаются висеть в памяти. Это то, что известно как "циклические ссылки" (смотрите дополнительную информацию: http://www.perl.com/pub/a/2002/08/07/proxyobject.html ).

    Это означает что устроить утечки памяти на Perl неожиданно просто. Многие подающие надежды Perl хакеры делали это случайно. Они думали: "Ха, было бы полезно чтобы этот объект содержал ссылку на родителя, и наоборот", и, вуаля, утечка памяти.

    Perl, безусловно, не одинок в использовании счётчика ссылок: VB его использует, Python всё ещё его использует, как и PHP.

    Вероятно величайшая проблема со счётчиками ссылок это дополнительная нагрузка на авторов XS-расширений. Счётчики заставляют их плодить вызовы SvREFCNT_inc() и SvREFCNT_dec() по всему коду, контролируя что каждый SvREFCNT_inc() имеет соответствующий SvREFCNT_dec(). Что приводит меня к следующему раздражению...

  3. Не интуитивное API.

    C API Perl довольно любопытное. Во-первых, отсутствует видимое соглашение об именах. Некоторые имена процедур записаны в смешанном регистре, например newSViv(), в то время как другие содержат подчёркивание, например newRV_noinc(). Многие имена переменных и членов структур имеют краткие, иногда дезориентирующие имена, например "cur" для длины и "len" для размера.

    API также наводнено макросами, многие из которых не документированы в perlapi или любых других man страницах, например HvKEYS().

    И, чтобы сделать жизнь ещё более интересной, для функций, которые документированы, зачастую не сказано, будут ли они изменять счётчики ссылок своих аргументов.

  4. Не интуитивное поведение массивов/списков в скалярном контексте.

    Мне на самом деле не нравится писать код с дополнительными скобками типа:

    my ($first_field) = split(/\t/, $tab_delimited_fields); 
    
    чтобы помешать списку или массиву, возвращаемому из некоторой функции, повести себя неправильно.

    В Perl массивы возвращают свой размер, когда используются в скалярном контексте, а списки (напр. "(70, 80, 90)" в тексте программы) возвращают свой последний элемент. Во-первых, чего ради вообще введена разница между списками и массивами? Во-вторых, когда и зачем мне может потребоваться использовать список в скалярном контексте чтобы получить его последний элемент?

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

    my $email_address = $input =~ /(\S+\@\S+)/; 
    
    и он бы работал.

    Как же, вы спросите, тогда получить размер массива? Ну, почему бы не с помощью функции length()? Множество новичков предполагают что это должно работать именно так.

  5. Форматы.

    Форматы в Perl были предположительно "Report" частью из "Practical Extraction and Report Language" - конечно же "Perl" это уже не акроним, и когда, если честно, вы можете вспомнить что вы использовали форматы? На самом деле, можете ли вы вообще вспомнить как ими правильно пользоваться?

    Эта большая, полностью игнорируемая часть Perl - отстой по разным причинам.

    Во-первых, синтаксис определения форматов неуклюжий (как насчёт 20-ти или около того символов "<" один-за-другим?), глобальный (вам потребуется большой, заканчивающийся точкой блок где-то - вероятнее всего под вашим кодом) и абсолютно отличающийся от обычного синтаксиса Perl (увеличивая вероятность что вы его забудете, особенно поскольку вы никогда им не пользовались).

    Во-вторых, попытка сделать что-нибудь полноценное с помощью форматов приводит к многословию, часто требует использования функции select() и возни с $^ перед вызовом write(), заставляя вас использовать три выражения для достижения того, для чего хватило бы и одного. (Четыре выражения, если считать и восстановление select().)

    В-третьих, всё что умеют делать форматы, обычно умеют делать и printf() со sprintf()-ом. Даже когда синтаксис форматов действительно более гибок чем printf(), использование нескольких printf()-ов обычно позволяет решить проблему, и это более краткий и чистый способ.

    Возможно худшая часть всего этого это то, что write() используется для вывода несуществующих форматов вместо выполнения I/O как read(), его английская противоположность:

    "Note that write is *not* the opposite of 'read'. Unfortunately."
    из (perldoc -f write).
  6. Нет констант или макросов.

    На самом деле это должны быть два отдельных пункта, в Perl нет простого способа объявить переменные константами или определить макросы как альтернативу рассеивания магических чисел по всему коду.

    Да, в Perl есть прагма "constant", которая должна делать и то, и другое, но это на самом деле просто хак; ловкий, элегантный хак, но тем не менее хак:

    use constant PORT => 80;
    

    PORT теперь может быть использован как rvalue в присвоениях, как если бы он был чем-то типа константы, и любая попытка присвоить что-то в него вызовет фатальную ошибку. Но, видите-ли, PORT на самом деле это не константа, это просто функция с прототипом "без аргументов". Вы всё ещё можете перекрыть её, переопределив функцию, или через "use sub", или напрямую через таблицу символов (symbol table). Что более важно, одна из целей констант это эффективность; сделать жизнь проще для компилятора избавляя его от необходимости присваивать что-то в переменную. Здесь же, вместо мелкого выигрыша, perl, интерпретатор, получает непотребный удар по производительности.

  7. Нет информации о типе.

    В Perl скаляры могут содержать либо значение, либо ссылку на значение. К сожалению, Perl не предоставляет операторов чтобы узнать какого типа "значение" содержит скаляр, оператор есть только для определения типа ссылок. Это приводит к тому, что, например, определить, содержит ли скаляр число подходящее для арифметических вычислений неожиданно сложно. Да, я понимаю что мы, Perl хакеры, привыкли думать, что числа и строки взаимозаменяемы, но проблема всё равно возникает, и нелепо обращаться за помощью к регулярным выражениям чтобы определить:

    print "Not a number!" unless ($thing =~ /^\d+$/); 
    

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

    Даже функции из ctype.h были бы более полезны, чем ничего.

    Это ещё сильнее раздражает, потому что Perl, судя по всему, имеет довольно хорошее предположение, какого типа значение в SV (С-шный typedef описывающий значение скаляра) на основании значения поля "flags", и может легко конвертировать одно в другое при необходимости.

  8. Autovivification.

    Пары ключ/значение хешей autovivify (прим. переводчика: не знаю, как одним словом перевести autovivify, по смыслу - "создаются автоматически, на лету") в Perl. Это означает что вы можете указать новый ключ типа "autovived" и он возникнет:

    my %hash = (key1 => 'value1', key2 => 'value2');
    
    $hash{autovived} = 1;
    

    Это так же означает что вы можете опечататься в имени ключа и он тоже возникнет, без какого либо предупреждения. Это не является большой проблемой, когда вы используете хеши как словари, потому что ваши ключи часто приходят откуда-то ещё, но когда вы используете хеш как структуру или объект, это приводит к проблемам:

    $self = {
    	name => undef,
            age  => undef
    
    ...
    
    sub name {
     	my $self = shift;
    
     	$self->{Name} = shift if @_;
    
     	return $self->{name};
    }
    

    Когда я использую хеши как объекты, я всегда определяю и инициализирую каждый элемент хеша внутри конструктора чем-то, как минимум "undef". Что только я бы не дал за ключевое слово "static", которое мешало бы новым элементам добавляться в хеш после инициализации:

    static my $self = {
     	name => undef,
     	age  => undef
    
    ...
    
    $self->{Name} = shift; # fatal error
    

Другие, более слабые раздражители, которые приходят на ум, включают отсутствие эквивалента для chop() перед строкой, невозможность применять файловые тесты -x по цепочке (вам требуется писать "-e $filename && -T $filename && -w $filename" вместо "-e -T -w $filename" или "-eTw $filename"), странное соглашение для вызова binmode(), нестабильные сигналы, дезориентирующие имена типа local(), и отсутствие функции sizeof().

Этот 16-летний язык неуклонно разбухает уже некоторое время. Многие его аспекты становятся не интуитивными, не эффективными, или просто уродливыми. Реализация сложно поддаётся изменениям, и добавление новых возможностей без поломки старых становится чрезвычайно сложной.

Perl 6 это попытка Perl коммьюнити исправить многие из этих проблем. Будет добавлена настоящая поддержка объектов, счётчик ссылок уйдёт, сигилы ($, @, %) будут более интуитивные, и множество новых возможностей будет добавлено.

Это переписывание языка сверху-вниз всё ещё далеко от завершения, но я, вместе со многими другими, жадно жду его. До этого момента, я думаю, я продолжу использовать Perl 5 для выполнения большей части моей работы.



комментарии:  RSS-поток комментариев
powerman счастливый хабрачеловек 5 июня 2007 01:49 #
+11  
Честно говоря, в планах было после перевода выдать своё мнение... учитывая, что статья 3-х летней давности некоторые вещи могли измениться, о чём-то автор просто мог не знать.

Например, для определения типа скаляра есть функция looks_like_number() в модуле Scalar::Util. Ну и так далее, разных workaround-ов для описанных проблем существует некоторое кол-во.

Но сил на это уже нет. Два часа переводил, пол часа форматировал, а выдохся так, будто вагон разгружал. Вероятно, это связано с тем, что это мой первый перевод - до этого момента я предпочитал писать сам, а не переводить. Но эта статья очень понравилась, давно сам такое хотел написать. И, в общем и целом, в ней всё верно... хотя попридираться можно, если бы силы остались. :)
glader 5 июня 2007 09:04 #
0  
Это от желания поскорее выложить :) Можно же перевести, на следующий день на свежую голову вычитать и поправить.
ihrd 5 июня 2007 10:58 #
0  
огромное спасибо за перевод, инетресная статья. Как раз разбираюсь с Perl 6 и приятно видить, что сохраняя всю мощь, как раз описанные sucks старательно исправляют.
super 5 июня 2007 07:29 #
0  
Интересно было-бы почитать о сравнении PERL с PHP.
powerman счастливый хабрачеловек 5 июня 2007 08:14 #
+3  
Ага. На хабре только этого flamewar нехватало для полного счастья. Лучше сделаем так - выше статья по недостаткам Perl, а вот статья по недостаткам PHP: К вопросу об ублюдочности PHP. На всякий случай, как и автор этой статьи уточню - речь не идёт о том, что "Perl rulez, PHP suxx", это просто описание недостатков PHP, а Perl иногда упоминается просто для сравнения, не более того. Все языки важны, все языки нужны. Ом!
blockdog 5 июня 2007 09:46 #
0  
Прочитал по диагонали. Скажем так: не совсем правда. Но это обсуждение для отдельной статьи.
HeadWithoutBrains 5 июня 2007 10:36 #
+1  
Прочитал полностью. По пунктам которые там указаны
1. Такой разброс в названии функций, как ме кажется связан с тем что php разрабатывают/дорабатывают много людей, и если бы сейчас хотели бы упорядочить названия функций, было бы довольно сложно это сделать
2. Количество функций. Мне кажется, что именно поэтому php и популярен. Из за огромного количества функций которые могут выполнять рутинную работу. А то что они все сразу доступны. Опять же связано с архитектурой php
3. Насчет пространства имен, автор прав. Но к сожаленью например я, уже давно привык к этому =)
5. Бейте меня, но мне очень нравится работа с массивами в php. А для сравнения типов есть ===. Или при проверке, просто приводите переменную которую сравниваете к нужному типу.
6. Не хочу комментировать, так как сам начинаю задумывать насчет серьезности php

Хочу сказать что это всё, мое личное субьективное мнение. Я не гуру программинга на php и возможно что то говорю не правильно.
HeadWithoutBrains 5 июня 2007 10:39 #
0  
А насчет статьи про perl, то я бы лично не хотел говорить насчет его недостатках и говорить что он хуже php, так как такие языки как perl возникли сравнительно давно, и используются не только в вебе(в плане синтаксиса). Для меня лично, perl представляется эдаким пожилым мужчиной, а php молодым, постоянно куда то бегущим юнцом =)
А питон вообще змея :D
blockdog 5 июня 2007 10:14 #
0  
Мне тоже интересно.
oogl 5 июня 2007 08:42 #
0  
Было бы скорее интересно почитать о преимуществах Perl. Например: что в нём есть кроме регэкспов?
glader 5 июня 2007 09:07 #
0  
Регекспы много где есть. Просто в перле ими несколько более удобно пользоваться.
oogl 5 июня 2007 11:16 #
0  
почему удобней? чем?
bolk 5 июня 2007 15:58 #
0  
Смотря по сравнению с чем. По сравнению с PHP — явно удобнее. Например, regexp в Perl — отдельный типа, а в PHP он передаётся через строку. Из-за этого, иногда, возникает дикое количество слешей для экранирования.
glader 5 июня 2007 17:59 #
0  
Удобнее - тем, что есть синтаксический сахар. Строка
str =~ /\d+/;
нагляднее, чем
re.search('\d+', str)
хотя может это просто привычка
bendingunit22 5 июня 2007 19:04 #
+1  
В Perl регулярные выражения реализованы в самом языке на уровне операторов. Кроме того, в Perl лучший диалект, что признает тот же Фридл.
random 18 июня 2007 13:20 #
0  
В дополнение к уже сказанному (насчет удобного синтаксиса и диалекта) - в Перле регекспы проходят проверку синтаксиса на этапе компиляции. Это очень удобно.
jerom 5 июня 2007 09:19 #
0  
На нём красиво и компактно выглядят скрипты и очень удобно обрабатывать текстовые данные.

Но, если к C++ добавить boost, то всё становится примерно так же удобно, просто многословнее.

Вот тут из двух крупных функций на Паскале получаются такие строки:

sub ckinn($) { $_[0]!~/^(\d{9})(\d)(?:(\d)(\d))?$/ || (($3) ?
    $3!= c("0".$1.$2) || $4!= c($1.$2.$3): $2!= c("00".$1)) + 0 }
sub c($) { $a=shift; $c=0; map { $c+=chop($a)*$_ } (8,6,4,9,5,3,10,4,2,7,3); $c %11 %10 }

Это, конечно, просто зарядка для ума и развлечение, но возможности демонстрирует.
jartashi 5 июня 2007 11:04 #
0  
Пожалуй паскалевский код прочитать быстрее.
Хотя для тех кто пользует perl ежедневно пару лет и уже думает на нем, это наверное и не так.
jerom 5 июня 2007 11:37 #
0  
Ну, если рассматривать только вариант ckinn10, то он понятнее. Но я люблю такие развлечения
iDev 5 июня 2007 11:09 #
0  
Думаю, такая регекспина будет работать едва ли не дольше чем паскалевские функции, да и читаюстся они легче.
P.S. Я ни в коем случае не умоляю достоинств регулярных выражений, даже напротив время от времени ломаю об них мозг :)
oogl 5 июня 2007 11:23 #
0  
А если конкретно и не касаясь регэкспов.
schors 5 июня 2007 11:29 #
0  
Эка тему я в своё время подкинул... :)))
diamant 5 июня 2007 12:51 #
0  
вот из-за таких конструкций программисты и выбирают php, а не perl :)
когда delphi-с-программисту приходится быстро переходить на web-порграммирование, причём нет полгода на обучение, а проект нужно сдать через месяц
gribozavr 5 июня 2007 19:16 #
+2  
А потом мы спрашиваем откуда такое огромное количество ужасного кода в web-проектах...
glader 5 июня 2007 09:02 #
0  
Спасибо, интересно.

P.S. А аutovivification, по моему мнению, скорее плюс чем минус.
jerom 5 июня 2007 09:08 #
0  
Я бы сказал, что это был бы плюс, если бы в перле были честные классы.

Но сейчас классы это, по сути, хэши. Отсюда и растёт желание убрать аutovivification для некоторых конкретных хэшей.
glader 5 июня 2007 09:18 #
0  
В некоторых конкретных случаях можно включить варнинг использования несуществующих ключей. Хотя это нельзя назвать решением.
nonSmoker 5 июня 2007 09:30 #
+1  
Есть workaround для таких целей.
http://search.cpan.org/~kvail/Tie-Strict…
Meneldor 5 июня 2007 11:36 #
+1  
А ещё lock_keys of Hash::Util.
random 18 июня 2007 13:32 #
0  
use fields в помощь. Проблему с аutovivification решает, да еще и проверки будут не в рантайме (как с решениями на основе tie и пр.), а еще при компиляции.
Helg 5 июня 2007 10:06 #
0  
Кто-нибудь знает, когда ждать perl 6? Нигде внятной информации найти не могу :(
ihrd 5 июня 2007 11:11 #
0  
когда будет готов :) так говорят разработчики. мне самому дико интересно, потому, что то, что получается мне кажется отличным языком.
bendingunit22 5 июня 2007 11:17 #
0  
Не в этом году - это точно :(
Helg 5 июня 2007 11:45 #
0  
Где-то слышал, что Ларри обещал в мае... Уже июнь... Неужели правда не в этом году? Ссылка на источник есть?
bendingunit22 5 июня 2007 19:06 #
+1  
Он уже седьмой год только и делает, что обещает :)
cooper 5 июня 2007 11:26 #
0  
Ответ на этот вопрос мучает меня со времён первого апокалипсиса. Ларри говорит что язык выйдет в конце лета уже года три точно, но кроме parrot пока ничего толкового не вышло.

Ждём и верим что p6 всё-же будет.
Nenakhov 5 июня 2007 10:24 #
−1  
Не вижу ни одной причины использовать перл с тех пор как появился Python
cooper 5 июня 2007 11:16 #
0  
На питоне не так удобно писать скрипты автоматизации для работы в юникс-окружении.
Nenakhov 5 июня 2007 14:09 #
0  
Это ещё почему? Всё что нужно, там есть.
cooper 5 июня 2007 15:10 #
0  
Хорошо, напишите скрипт который пройдет по переданной в параметрах директории и сменит кодировки всех файлов с расширениями, переданными в виде regexp (.*\.?htm?|.*
.?pl), с cp1251 на utf8, используя для этого iconv.
cooper 5 июня 2007 15:15 #
0  
Хабр схавал половину поста.

На перле такие вот мелочи делаются в три строки и занимают 5 минут, ибо на CPAN всё есть, а «магия» многих операторов и встроенных функций позволяет оставлять пространства для маневров при вызове получившийся утилиты. Питон не даёт такой гибкости.
anortorn 6 июня 2007 13:36 #
0  
Это вы зря, у питона библиотека очень даже не маленькая. И скрипты автоматизации пишутся. Другое дело, что perl более привычен для многих в этой сфере.
Meneldor 5 июня 2007 11:36 #
0  
В Питоне есть аналог mod_perl?
Meneldor 5 июня 2007 11:42 #
0  
mod_python - это оно и есть?
bubuq 5 июня 2007 12:22 #
+1  
Я вижу одну: CPAN.
Chapaev 5 июня 2007 12:07 #
0  
Python & Ruby решают задачи Perl более лаконично IMHO.
bendingunit22 5 июня 2007 19:11 #
0  
Смотря какие задачи. Я на Ruby ради интереса и для более детального изучения синтаксиса пытался портировать готовое Perl приложение. Так вот местный Net::HTTP даже не умеет работать с плюшками, а во всех конференциях предлагают родить велосипед самому. Что уж говорить об LWP::Parallel и прочих радостях. CPAN - это то, благодаря чему Perl живет и довольно активно используется.
life4beer 5 июня 2007 13:16 #
+1  
Для меня большой минус перла - то, что там слишком много свободы. Можно использовать скобки, можно не использовать. Можно писать "if (blabla) { tratata}", а можно "tratata if (blabla)" и т.д. Поначалу это казалось плюсом, но как только довелось работать в команде, выяснилось, что очень трудно читать чужой код. Поэтому очень важно, если работаешь в команде, жестко придерживаться неких code rules, первым пунктом где ОБЯЗАТЕЛЬНОЕ использование use strict.
khibinite 5 июня 2007 13:45 #
0  
Ну так в любом языке можно словить множество неудобств из-за различий в форматировании, например. Меня, к примеру, крайне раздражают отступы в 1-2 пробела :), идентификаторы типа с1, x2 итп (в любом языке!). Так что, естественно, при работе в команде нужен стандарт.
life4beer 5 июня 2007 14:20 #
0  
форматирование в том числе, но я не только про него говорил. уж слишком много вольности, а без use strict так просто бардак.
DimaD 5 июня 2007 15:32 #
−1  
Ну если вы разрабатываете большой проект, то надо использовать соглашения о кодировании, а с ними обычно код на всех языках очень похож. В маленьких скриптиках "для себя" strict иногда мешает и я его там не использую вообще.
life4beer 5 июня 2007 16:06 #
+1  
можно пример, когда strict мешает?
bendingunit22 5 июня 2007 19:12 #
0  
Без use strict получается PHP ;)
123 5 июня 2007 14:05 #
−4  
1. Нет наследования объектов.

Не понимаю - зачем в скриптовом языке использовать ООП...
mshilov 5 июня 2007 16:07 #
0  
Perl это еще и объектно-ориентированный язык, просто "ориентация" там .. хм.. другая :)
DimaD 5 июня 2007 15:29 #
0  
Мне вот не нравится, что конструкция вида (1, 2, 3, (4, 5), 6) склеивается в один список и код вида. Ко всему остальному уже как-то привык
DimaD 5 июня 2007 15:31 #
0  
Первое предложе ние читать как "Мне вот не нравится, что конструкция вида (1, 2, 3, (4, 5), 6) склеивается в один список."
glader 5 июня 2007 18:05 #
0  
пиши (1, 2, 3, [4, 5], 6) :)
DimaD 6 июня 2007 12:42 #
0  
Это несколько другая вещь. По идее () - это список скаляров. Так вот когда я подставляю вместо одного из скаляров список, по идее должен срабатывать скалярный контекст на список, ан нет, списки склеиваются
glader 6 июня 2007 13:02 #
0  
А, вон ты про что. Видимо автор языка решил, что объединение списков понадобится чаще, чем преобразование списка в скаляр.
kentposalu 5 июня 2007 17:06 #
−2  
уродство этот perl по сравнению с ruby
MpaK 6 июня 2007 12:48 #
0  
то что не объектный это понятно уже давно, как и пхп... но писать коряво можно на любом языке, хоть тот же РУБИ или С++, еще как можно :)

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

*CONST = 'Hello World';

$CONST = 'Good buy World'; # вызовет ошибку! все нормально
MpaK 6 июня 2007 12:49 #
+1  
вот так правильнее *CONST = \'Hello World';
zag 6 июня 2007 15:05 #
−1  
Очень плохая статья. Человека, скорее относящегося равнодушно к perl!
Cancel 9 июня 2007 15:33 #
0  
Пользуюсь перлом довольно давно, в основном в качестве -pi-однострочников (ну, не люблю я sed/awk!) либо же для массовой обработки текстовых файлов.

Пробовал питон для второй задачи, но он у меня как-то не прижился. Стараюсь писать все перловые программы в C-стиле, иначе, действительно, потом хрен поймёшь, что же делает программа. Ну, а основное преимущество — это, конечно, CPAN.
random 18 июня 2007 14:21 #
0  
1. "ОО в Perl это на самом деле не более чем bless-нутые ссылки и немного синтаксического сахара" - интересно, что это "не более чем" дает возможность реализовать больше ОО-фичей, чем в любом другом мейнстримном языке: от множественного наследования до использования prototype-based обьектности вместо class-based.

2. Со счетчиком ссылок все просто: при необходимости используйте средства для создания weak references (ссылок, не инкрементящих счетчик). Стандартно - Scalar::Util::weaken().

5. "Здесь же, вместо мелкого выигрыша, perl, интерпретатор, получает непотребный удар по производительности." - это заблужение. Действительно, use constant создает функциии (сделано это, чтобы не вводить доп. сущностей в язык). Но: умный компилятор инлайнит функции, возвращающие константное значение (не важно, созданные ли через use constant или вручную), так что при операциях с ними работа идет непосредственно со значением, вызова функции не происходит. Кроме того, в качестве констант можно использовать readonly переменные.

6. Непонятно, зачем определять тип переменной вместо того, чтобы просто использовать ее в нужном контексте. Впрочем, если есть необходимость, можно напрямую обратиться к IV или строковому значению SV. Пример:

use B;
my $x = "string"; $x = 10;
my $xb = B::svref_2object(\$x);
printf "%s, %d",$xb->PVX,$xb->IV;
powerman счастливый хабрачеловек 18 июня 2007 15:59 #
0  
По поводу функций и их inline. К сожалению, это работает далеко не всегда, например смотрите мой пост на perlmonks: Slow constants. Кроме того, read-only скаляры (созданные, например, так: eval q{*O_NONBLOCK = \\}.O_NONBLOCK;) работают немного быстрее и обычных скаляров, и инлайнящихся функций! Об этом можно почитать в другом моём посте: Import constants as scalar instead of bareword sub.
random 18 июня 2007 17:45 #
0  
Естественно, компилятор не может оптимизировать то, чего нет на этапе компиляции - так что фолдинг не будет работать для динамически генерируемых функций (подозреваю, что и для XS тоже).

Вариант с readonly-переменными я тоже предлагал выше, ибо TMTOWTDI, но у него есть один очень серьезный недостаток: переменные, даже readonly, все-таки можно переопределить, причем случайно (что мешает мне обьявить my $O_NONBLOCK ?) - и компилятор/рантайм не выдаст при этом никаких сообщений! При переопределении же constant sub (не важно, через sub CONST {} или *CONST = sub) получим предупреждение: Constant subroutine main::CONST_NAME redefined (в случае sub CONST - еще на этапе компиляции).
powerman счастливый хабрачеловек 19 июня 2007 04:11 #
0  
Это уже софистика пошла. А на самом деле всё иначе.

Да, "компилятор не может оптимизировать то, чего нет на этапе компиляции". Но проблема в том, что когда я подгружаю через use разные модули, я не могу заранее знать, на каком этапе эти модули генерируют/экспортируют константы - на этапе компиляции или на этапе выполнения. В доке такие нюансы обычно не упоминают, да и задолбаешься по каждому отдельному модулю это уточнять. Так что проблема таки есть!

Что касается объявления "my $O_NONBLOCK", то тут два нюанса. Во-первых существует соглашение, что в верхнем регистре пишутся только константы, так что "my $O_NONBLOCK" в середине кода - это красный флаг на который среагируют все квалифицированные программисты, и никто из них такого не напишет (если не хочет действительно переопределить эту константу, как грязный но нужный хак). А во-вторых никто не мешает через no warnings 'redefine' отключить предупреждение о переопределении константной процедуры и переопределить её так же тихо, как и скаляр через "my".
cybermozg 3 августа 2007 01:52 #
0  
Весь перл - это один большой хак. В этом его сила и в этом его слабость.
Но перл - это всего лишь инструмент. Всё остальное - вопросы мастерства и дисциплины.

Можно сказать, что самурайски меч - это слишком неудобный дивайс, ибо его нельзя метнуть в голову врагу. И ещё он шибко острый, об него обрезаться можно.

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии. Авторизуйтесь, пожалуйста, или зарегистрируйтесь, если не зарегистрированы.