Почему Perl — Отстой?

Возможно, «отстой» — слишком резкое слово, но по аналогии с «Почему C — отстой» И «Почему C++ — отстой» это, наверное, подходящее название.

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

Мне нравится его сила, мне нравится его элегантность и, Больше всего мне нравится его выразительность.

Однако Перл конечно не без недостатков.

Тон этой статьи не претендует на негативный.

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

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



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

    Наследование в Perl реализовано через массив.

    ЭТО (произносится как «is a» как «это проблема»), что позволяет вам позвонить методы из одного пакета через ссылку благословения на другой пакет. Например, если SomeClass содержит SomeOtherClass в своем глобальном множество ЭТО тогда вы можете напрямую вызвать любой метод SomeOtherClass через ссылку благословения в SomeClass. К сожалению, реального способа наследовать объекты из другого класса в Perl, вы можете наследовать только его методы.

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

    получить объект, добавить в хэш свои поля, а затем перенесите объект благословения в свой класс:

     
     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 на самом деле представляет собой не что иное, как благословение ссылок и немного синтаксический сахар.



    Счетчик ссылок.

    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().

    Что приводит меня к следующему раздражению.



    Не интуитивно понятный API.

    API Perl C весьма интересен.

    Во-первых, не видно соглашение об именовании.

    Имена некоторых процедур написаны смешанным шрифтом.

    регистр, например newSViv(), а другие содержат подчеркивание, например newRV_noinc().

    Множество имен переменных и члены структур имеют короткие, иногда вводящие в заблуждение имена, например «cur» — длина, «len» — размер.

    API также переполнен макросами, многие из которых не документированы.

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

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



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

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

    В Perl массивы возвращают свой размер при использовании в скалярном выражении.

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

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

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

     
     my $email_address = $input =~ /(\S+\@\S+)/; 
     
    и это сработает. Как же, спросите вы, тогда получить размер массива? Ну почему бы и не с используя функцию length()? Многие новички предполагают, что это Вот как это должно работать.



    Форматы.

    Форматы в Perl предположительно были частью «Отчета» «Практический язык извлечения и создания отчетов» — конечно, «Perl» уже не аббревиатура, и когда, честно говоря, ты сможешь вспомнить, что ты вы использовали форматы? В самом деле, можете ли вы вспомнить, как правильно ли их использовать? Эта большая, полностью игнорируемая часть Perl во многих отношениях отстой.

    причины.

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

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

    (Четыре выражения, если вы посчитаете и восстановите select().

    ) В-третьих, все, на что способны форматы, они обычно тоже умеют. printf() с помощью sprintf().

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

    Возможно, худшая часть всего этого заключается в том, что используется write().

    для вывода несуществующих форматов вместо выполнения ввода-вывода, такого как read(), его английская противоположность:

    «Обратите внимание, что запись *не* является противоположностью «чтению».

    К сожалению.

    "

    из (perldoc -f write).



    Никаких констант и макросов.

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

    по-другому, но на самом деле это просто хак; аккуратный, элегантный хак, но все же хак:

     
     use constant PORT => 80;
     
    PORT теперь можно использовать в качестве значения r в назначениях, как если бы это было бы что-то вроде константы, и любая попытка присвоить что-либо это приведет к фатальной ошибке.

    Но, видите ли, ПОРТ на самом деле это не константа, это просто функция с прототипом «без аргументов».

    Вы все равно можете переопределить его, переопределив функцию или через «использовать sub» или напрямую через таблицу символов.

    Что еще более важно, одной из целей констант является эффективность; делать жизнь упрощается для компилятора, поскольку устраняется необходимость присваивать что-то в переменную.

    Здесь вместо маленького выигрыша перл, переводчик терпит непристойный удар по производительности.



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

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

    К сожалению, Perl не предоставляет операторов, позволяющих узнать, какой тип «значение» содержит скаляр, оператор предназначен только для определения типа ссылки.

    Это позволяет, например, определить, является ли скалярное число, неожиданно подходящее для арифметических вычислений трудный.

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

     
     print "Not a number!" unless ($thing =~ /^\d+$/); 
     
    Конечно, это выражение работает не очень хорошо, поскольку числа могут содержат другие символы, такие как "+", "-" или ".

    " для обозначения знака, дробная часть или показатель степени.

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

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



    Автовивификация.

    Пары ключ/значение хешей 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 my $self = {
       name => undef,
       age  => undef
     
     .
    

    $self->{Name} = shift; # fatal error

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

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

    Реализация сложно изменить, а добавление новых функций не сломав старые становится крайне сложно.

    Perl 6 — это попытка сообщества Perl решить многие из этих проблем.

    Будет добавлена поддержка реальных объектов, уйдет счетчик ссылок, символы ($, @, %) станут более интуитивно понятными, а также появится множество новых функций.

    будет добавлено.

    Переписывание языка сверху вниз еще далеко от завершения, но я, как и многие другие, я с нетерпением жду этого.

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

Теги: #perl #perl
Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.