1. Друзья, в это тяжёлое и непонятное для всех нас время мы просим вас воздержаться от любых упоминаний политики на форуме, - этим ситуации не поможешь, а только возникнут ненужные ссоры и обиды. Это касается также шуток и юмора на тему конфликта. Пусть войны будут только виртуальными, а политики решают разногласия дипломатическим путём. С уважением, администрация Old-Games.RU.

    Скрыть объявление
  2. Если Вы видите это сообщение, значит, вы ещё не зарегистрировались на нашем форуме.

    Зарегистрируйтесь, если вы хотите принять участие в обсуждениях. Перед регистрацией примите к сведению:
    1. Не регистрируйтесь с никами типа asdfdadhgd, 354621 и тому подобными, не несущими смысловой нагрузки (ник должен быть читаемым!): такие пользователи будут сразу заблокированы!
    2. Не регистрируйте больше одной учётной записи. Если у вас возникли проблемы при регистрации, то вы можете воспользоваться формой обратной связи внизу страницы.
    3. Регистрируйтесь с реально существующими E-mail адресами, иначе вы не сможете завершить регистрацию.
    4. Обязательно ознакомьтесь с правилами поведения на нашем форуме, чтобы избежать дальнейших конфликтов и непонимания.
    С уважением, администрация форума Old-Games.RU
    Скрыть объявление

Perl vs. PHP

Автор: Helmut · 22 апр 2019 · ·
  1. Задолбали. Почти каждый заказчик, услышав, что работа будет выполнена на Perl, удивляется и задает одни и те же дурацкие вопросы. Ну ладно, Перл действительно несколько сложнее, потому что гибче и вариативнее. Но вот насчет трудночитаемости кода на Перл - байка. Поразительно устойчивая байка.

    Появилась она из-за того, что Перл позволяет писать практически любой исполняемый код в виде регулярного выражения. Такой код, действительно, выглядит крайне загадочно, и разобраться в нем - не самая простая задача даже для его автора. Но фокус в том, что практических задач, требующих решения именно таким методом - в жизни встречается крайне мало. Мне, например, не попадалось вообще ни разу. Если, конечно, задачей не является преднамеренная обфускация кода или обычный выпендреж. Тем более, что такой код будет выполняться в разы медленнее.

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

    Ну а выпендриваться тоже можно по разному. Например, поступила мне от бухов банальная задача - сделать функцию, парсящую число в пропись (с соблюдением правил написания чисел типа тысяча-тысячи-тысяч) . Почему я не взял одну из кучи давным-давно существующих библиотек? Во-первых, начальник у бухов сам был не чужд программированию, и мне не хотелось, чтобы для него все было слишком уж просто. Во-вторых, все готовые функции, попадавшиеся мне на глаза, состояли из двух-трех страниц кода. Мне захотелось прикола ради написать наиболее компактный код. В итоге уложился в 25 строчек.

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

    В результате код получился не самым читаемым, но он построен на тернарных операторах и с минимальными изменениями будет работать и на ПХП. И вообще, на ПХП тоже не проблема написать трудночитаемый код. А идиоту для этого даже труда прилагать не придется, причем на любом языке.

    Код:
    sub propis {
        my ($int,$s,@a) = (sprintf("%.2f",$_[0]),($_[1])?$_[1]:' ',());
        my ($smr,$smk) = ($int < 1e9) ? split(/\./,$int) : (0) x 2;
        my @r = split(//, sprintf("%09d",$smr));
        my @k = split(//, sprintf("%02d",$smk));
        my @t = qw (ноль одна две тысяча тысячи тысяч миллион миллиона миллионов);
        @a[1..20,30,40,50,60,70,80,90,100,200,300,400,500,600,700,800,900] = qw (
            один два три четыре пять шесть семь восемь девять десять одиннадцать двенадцать тринадцать четырнадцать пятнадцать шестнадцать семнадцать восемнадцать девятнадцать
            двадцать тридцать сорок пятьдесят шестьдесят семьдесят восемьдесят девяносто сто двести триста четыреста пятьсот шестьсот семьсот восемьсот девятьсот
        );
        my $rub = ($smr > 0) ? ($r[0] > 0) ? $a[$r[0]*100].$s : '' : $t[0];
        my $kop = ($smk > 0) ? ($k[0] > 1) ? ($k[1] > 0) ? $a[$k[0]*10].$s : $a[$k[0]*10] : '' : $t[0];
        $kop .= ($k[0] == 1) ? $a[$k[0]*10+$k[1]] : ($k[1] < 3) ? $t[$k[1]] : $a[$k[1]] if ($k[0] == 1 || $k[1] > 0);
        $rub .= ($r[1] == 1) ? $a[$r[1]*10+$r[2]].$s : $a[$r[1]*10].$s if ($r[1] > 0) ;
        $rub .= ($r[2] == 1) ? $a[$r[2]].$s.$t[6] : $a[$r[2]].$s if ($r[2] > 0 && $r[1] != 1);
        $rub .= ($r[2] > 0 && $r[2] < 5 && $r[1] != 1) ? $t[7] : $t[8] if ($smr >= 1e6 && ($r[1] == 1 || $r[2] != 1));
        $rub .= $s if ($smr >= 1e6 && $r[3]+$r[4]+$r[5] > 0);
        $rub .= $a[$r[3]*100].$s if ($r[3] > 0);
        $rub .= ($r[4] == 1) ? $a[$r[4]*10+$r[5]].$s : $a[$r[4]*10].$s if ($r[4] > 0);
        $rub .= ($r[5] == 1) ? $t[1].$s.$t[3] : ($r[5] == 2) ? $t[2].$s : $a[$r[5]].$s if ($r[5] > 0 && $r[4] != 1);
        $rub .= ($r[5] > 0 && $r[5] < 5 && $r[4] != 1) ? $t[4] : $t[5] if ($r[3]+$r[4]+$r[5] > 0 && ($r[4] == 1 || $r[5] != 1));
        $rub .= $s if ($smr >= 1e3 && $r[6]+$r[7]+$r[8] > 0);
        $rub .= ($r[7]+$r[8] > 0) ? $a[$r[6]*100].$s : $a[$r[6]*100] if ($r[6] > 0);
        $rub .= ($r[7] == 1) ? $a[$r[7]*10+$r[8]] : $a[$r[7]*10] if ($r[7] > 0);
        $rub .= ($r[7] > 1) ? $s.$a[$r[8]] : $a[$r[8]] if ($r[8] > 0 && $r[7] != 1);
        return($rub, $kop);
    }
    

Комментарии

  1. pause_break
    > Когда собеседуешься на работу, где приветствуется "умение разбираться в чужом коде".
  2. Helmut
    На ОГ, кстати, @SAS высказывал подобные предрассудки.
  3. daemolisher
    Я раньше не писал код на Perl.

    Интересно получается:
    Код:
    @outp = &propis (8.995);
    print "Долл.: $outp[0];\nЦент.: $outp[1].";
    Выводит:
    Но с другим числом:
    Код:
    @outp = &propis (2.995);
    Выводит:
    Э-э-э..
  4. daemolisher
    Покумекал.
    Оказывается функция sprintf так округляет.

    Интересно в Си так же работало или нет.
  5. Helmut
    @daemolisher, sprintf с шаблоном "%.2f" округляет до двух десятичных знаков. Соответственно, .99 останется как есть, .993 станет .99, а .995 должно округлиться до целого. Это должно быть на любом языке.
  6. hardcorenexus
    Пробовал когда-то перл учить, но потом засел за пайтон и забил. Хотя надо, для общего развития, таки подучить.
  7. daemolisher
  8. Helmut
    @daemolisher, видимо, от версии перла зависит. У меня стабильно получается 8.995 = 9. Прогнал в цикле на несколько сотен раз.
    Еще на sprintf могут кривые настройки locale влиять, но это уже экзотика.

    ЗЫ: Да и от бухов ни разу не поступало претензии. А если бы поступило - эта проблема решается очень просто. Вместо sprintf("%.2f",$_[0]) написать sprintf("%.0f",$_[0]*100)/100.
  9. SAS
    Жёсткий код.
    Тернарный оператор тернарным оператором погоняет.

    Я бы если такое писал, всё-таки старался бы делать названия переменных более говорящими (по мере возможности) и не стремился бы сделать код как можно более компактным. А то через полгода в такой код заглянешь и будешь долго и мучительно вспоминать почему чего и как делается:)
  10. Helmut
    @SAS, Я развлекался. Иначе взял бы одно из существующих решений.
Чтобы оставить комментарий просто зарегистрируйтесь и станьте участником!
  1. На этом сайте используются файлы cookie, чтобы персонализировать содержимое, хранить Ваши предпочтения и держать Вас авторизованным в системе, если Вы зарегистрировались.
    Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie.
    Скрыть объявление