LINUX.ORG.RU

Perl 6 vs Python 3

 , ,


3

4

Дискач.

Чтобы писать утилиты и демоны например для десктопа. Допустим оставим в покое веб-девелопмент, там и так тесно. И забудем былое, Python 2, Perl 5 и связанные стереотипы.

P.S. Прошу не удалять за тупняк, я понимаю как это выглядит. Но тема то интересная

★★★★★

Последнее исправление: vertexua (всего исправлений: 2)
Ответ на: комментарий от perl5_guy

могу показать как красивше переделать ту или иную конструкцию

О! Мне покажи, пожалуйста.

Как-то раз я написал себе скриптик flacs2mpc.pl (для перекидывания музыки с домашнего хранилища на плеер). Но perl я знаю плохо, в его идиомах не ориентируюсь, modern perl не читал. Писал просто по докам.

(Там ещё осталась нереализованной идея асинхонности: поскольку файлы на microSD копируются небыстро, то это копирование должно происходить параллельно с кодированием, по мере готовности.)

Что бы ты там улучшил или сделал по-другому?

А чтобы хотя бы боком вписаться в тему треда, я попробую на досуге переписать этот скрипт на Perl 6. :)

aeralahthu
()
Ответ на: комментарий от aeralahthu

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

die $usage unless -d $path_from and -d $path_to;
Не нужно использовать сложные логические выражения вместе с unless, это очень трудно читать. Для этого ключевого слова, годится что-то вроде:
... unless $foo;

perl5_guy ★★★★★
()
Ответ на: комментарий от perl5_guy

Из серьёзных проблем только эта строчка:

die $usage unless -d $path_from and -d $path_to;

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

«Очень трудно»? «Серьёзная проблема»?

Но ведь unless something — это всего лишь if not (something).

Неужели

die $usage if not (-d $path_from and -d $path_to);

читается легче? По-моему, абсолютно так же, разве что лексем больше и нужно городить скобки.

А если применить въевшиеся в мозг (а у программиста они обязаны быть въевшимися в мозг) законы де Морагана

die $usage if not -d $path_from or not -d $path_to;

то получится ещё многословнее и, лично мне, чуть менее понятно.

Читать условие в unless становится немного неудобно в том случае, если в условии используется not. Тогда, конечно, имеет смысл подумать над использованием if вместо unless. Скорее всего и само условие от этого можно будет упростить.

Я понимаю (безотносительно перла и unless) рекомендацию «не использовать сложных условий»: если условие действительно сложное, то, конечно, его нужно попытаться упростить и/или разбить на более простые части. Но слепое следование правилу «никогда не писать в unless ничего, кроме ... unless $foo;» — это, по-моему, как-то чрезмерно. И, кстати, делает unless абсолютно бесполезным оператором, вместо которого без каких-либо потерь можно написать ... if not $foo;.

Ну и в целом, конечно, то, что большинство современных кодеров плохо ориентируются в булевой алгебре, совсем не радует. Приводит к тому, что они, не замечая ничего необычного, пишут вещи вроде if is_true(smth) then return True else return False, как было в этом треде.

Сейчас загружен дичайше, на выходных постараюсь посмотреть.

Да, пожалуйста. Я буду ждать. Но интересуют, всё-таки, более специфичные для перла места.

aeralahthu
()
Ответ на: комментарий от anonymous

PyQt

Который огромен и долго собирается

Говнина типа гтк

Которая не нужна в контексте ОП-поста.

Нет ли гуевого тулкита, использующего только Python? На ум приходит только Kivy, но он показался мне каким-то ограниченным.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от Deleted

Нет гуевого тулкита, использующего только Python? На ум приходит только Kiwi, но он показался мне каким-то ограниченным.

Во-первых, Kivy, во-вторых, нет, ты!

Virtuos86 ★★★★★
()
Ответ на: комментарий от aeralahthu

Хочешь ванговать? К питонистам иди. У них один и только один способ сделать что-то. С чего ты решил что я буду использовать именно такую конструкцию? Ещё и упрекнул меня в незнании булевой алгебры.

my $script = basename $0;
#
#die $usage if @ARGV < 2;
#my ($path_from, $path_to) = @ARGV;
#
#die $usage unless -d $path_from and -d $path_to;

my ($album_dir, $target_dir) = @ARGV;

foreach my $dir ( $album_dir, $target_dir ) {
	-d $dir or die "usage: $script <album dir> <target dir>";
}

perl5_guy ★★★★★
()
Ответ на: комментарий от perl5_guy

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

Просто из-за того, что кодеры не ориентируются в логике, для них потом придумывают нелепые бездумные рекомендации вроде «использовать unless только в виде ... unless $foo;». Но если ты посмотришь на мой вариант внимательно, я думаю (поскольку не считаю, что ты плохо знаешь булеву алгебру), ты увидишь, что он читается без проблем.

В твоём варианте мне не нравится: (1) использование foreach ради двух элементов и (2) при недостаточном количестве аргументов скрипт падает, не выдавая usage.

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

К питонистам иди. У них один и только один способ сделать что-то.

Именно потому, что «у нас везди Тим Тоуди», я против бездумного «мы никогда не используем unless, кроме случаев ... unless $foo;»

aeralahthu
()
Ответ на: комментарий от aeralahthu

`die $usage if @ARGV < 2;`

этот код избыточен при проверке далее переменных `$path_from` & `$path_to`. Они при присваивании списка `@ARGV` будут undefined.

Насчет тэгов. Тебе хэш не нужен. Говнокод-с. Обойдись готовым списком. Ах да, chomp избыточен.

``` my @tags = split /=|\n/, `metaflac --export-tags-to=- '$file'`; my @cmd = qw(mpcenc --standard);

# iterate through key/value for (my $i = 0; $i <= $#tags; $i += 2) { my ($k, $v) = @tags[ $i, $i+1 ]; push @cmd, '--'.lc($k), $v; } ``` Если нужно исключить какие то тэги, делай whitelist: ``` for (my $i = 0; $i <= $#tags; $i += 2) { my ($k, $v) = @tags[ $i, $i+1 ]; next if $k !~ /artist|etc|etc/i;

... } ``` Обрати внимание на `/i` (ignore case). Если он тебе нужен. Это избавит и от нестабильного when, и warningoв.

И еще, если тебе нужен `use warnings`, то зачем `/usr/bin/perl -w` в шебанге?

На большее не хватило, сорян.

В целом, код неплох даже таким какой есть. Для человека, который не читал modern perl и не знаком с идиомами языка — это круто.

anonymous
()
Ответ на: комментарий от anonymous

die $usage if @ARGV < 2;

этот код избыточен при проверке далее переменных $path_from & $path_to. Они при присваивании списка @ARGV будут undefined.

Насчет тэгов. Тебе хэш не нужен. Говнокод-с. Обойдись готовым списком. Ах да, chomp избыточен.

my @tags = split /=|\n/, `metaflac --export-tags-to=- '$file'`;
my @cmd  = qw(mpcenc --standard);

# iterate through key/value
for (my $i = 0; $i <= $#tags; $i += 2) {
	my ($k, $v) = @tags[ $i, $i+1 ];
	push @cmd, '--'.lc($k), $v;
}

Если нужно исключить какие то тэги, делай whitelist:

for (my $i = 0; $i <= $#tags; $i += 2) {
	my ($k, $v) = @tags[ $i, $i+1 ];
        next if $k !~ /artist|etc|etc/i;

        ...
}

Обрати внимание на /i (ignore case). Если он тебе нужен. Это избавит и от нестабильного when, и warningoв.

И еще, если тебе нужен use warnings, то зачем /usr/bin/perl -w в шебанге?

На большее не хватило, сорян.

В целом, код неплох даже таким какой есть. Для человека, который не читал modern perl и не знаком с идиомами языка – это круто.

anonymous
()

Питон лучше, потому что мейнстрим, без вариантов.

Einstok_Fair ★★☆
()
Ответ на: комментарий от anonymous

В целом, код неплох даже таким какой есть. Для человека, который не читал modern perl и не знаком с идиомами языка – это круто.

@chinarulezz, ты ли это?

anonymous
()
Ответ на: комментарий от aeralahthu

1. Нет такого слова «не нравится». Ты оптимизируешь до того как начало тормозить или считаешь конструкцию невыразительной?
2. Всё отработает без проблем, т.к. foreach не выполнится только если ему передать пустой список, а у нас, в случае отсутствия аргументов, будет список из двух неопределённых элементов.

perl5_guy ★★★★★
()
Ответ на: комментарий от anonymous

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

Доживаю очередную попытку бросить лор)

anonymous
()
Ответ на: комментарий от perl5_guy

Ты оптимизируешь до того как начало тормозить или считаешь конструкцию невыразительной?

В данном случае, считаю вариант die ... if ... более выразительным.

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

(2) при недостаточном количестве аргументов скрипт падает, не выдавая usage.

Всё отработает без проблем

Если оставить use warnings FATAL => 'all';, то нет:

$ cat test.pl
#! /usr/bin/perl

use v5.20;
use strict;
use warnings FATAL => 'all';
no warnings 'experimental';

my ($album_dir, $target_dir) = @ARGV;

foreach my $dir ( $album_dir, $target_dir ) {
	-d $dir or die "usage: q <album dir> <target dir>";
}
$ ./test.pl
Use of uninitialized value $dir in -d at ./test.pl line 11.
$ ./flacs2mpc.pl
usage: flacs2mpc.pl <album dir> <target dir> at ./flacs2mpc.pl line 16.
aeralahthu
()
Ответ на: комментарий от anonymous

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

Доживаю очередную попытку бросить лор)

Мой личный рейтинг ушедших (или выгнанных с лора) именно программистов (а не программистов-философов, любящих обсуждать одни сплетни из мира IT, и ничего более):

  1. @Царь
  2. @chinarulezz
  3. @Eddy_Em

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

Царь, вон продолжает из-под анонима перевоспитывать сектантов, что есть хорошо. Кстати, читая недавно его комментарии на Хабре почерпнул для себя кое-что новое из мира C++ (давно не следил за этим языком, но всё же).

anonymous
()
Ответ на: комментарий от aeralahthu

Ну понятно. Спецом однострочник написал чтоб проверить есть ли предупреждение если undef передаётся для -d, видать забыл ключ -w. Поправляется это просто:

-d( $dir || '' ) or die "usage: q <album dir> <target dir>";
Стандартный if наверное даже лучше будет:
if ( -d( $dir || '') ) {
    die "usage: q <album dir> <target dir>";
}

perl5_guy ★★★★★
()
Ответ на: комментарий от aeralahthu

Ладно, это всё в сторону от темы. Не настолько существенные вещи, чтобы мне хотелось о них спорить.

@perl5_guy, извини, если в моих ответах тебе я был слишком резок.

Если всё-таки увидишь в моём скрипте какие-то конструкции, которые, по-твоему, можно заменить на более эффективные и/или выразительные, буду благодарен. (Хотя при этом могу быть и не согласен. :) )

aeralahthu
()
Ответ на: комментарий от aeralahthu

Как ты его узнал? :)

Ну, он один из опытных перловиков на форуме, также он недавно писал о необходимости помощи адекватным новичкам, вот я и подумал, что это он (плюс стиль написания похож).

anonymous
()
Ответ на: комментарий от aeralahthu

Я и не думал оскорбляться.
Посмотрю как будет время.
Было бы неплохо, если конкретные примеры вывода metaflac предоставишь. Ещё есть Pod::Usage и Getopt::Long. Для небольших скриптов это оверкил, но знать о этих модулях полезно.

perl5_guy ★★★★★
()
Ответ на: комментарий от perl5_guy

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

die $usage if @ARGV < 2;
die $usage unless -d $album_dir and -d $target_dir;
foreach my $dir ( $album_dir, $target_dir ) {
    if ( -d( $dir || '') ) {
        die $usage;
    }
}

Ну или уж тогда (может это можно короче записать, не знаю):

die $usage unless defined $album_dir and -d $album_dir
              and defined $target_dir and -d $target_dir;
aeralahthu
()
Ответ на: комментарий от perl5_guy

Все спорите как правильно if записывать? Лол. Вот за эту кодерастию перл и нужно прикопать вместе с рубями. Вроде больше таким фимозом никто не страдает в мейнстриме.

bread
()
Ответ на: комментарий от aeralahthu

die $usage unless defined $album_dir and -d $album_dir and defined $target_dir and -d $target_dir;

За такое сразу в морг кладут в иных местах. Пиши лучше в стол.

bread
()
Ответ на: комментарий от perl5_guy

конкретные примеры вывода metaflac

Там просто набор пар TAG=какая-то строка без кавычек, разделённых переводом строки:

$ metaflac --export-tags-to=- 02\ -\ Frame\ By\ Frame.flac
TITLE=Frame By Frame
ALBUM=Discipline (40th AE)
TRACKNUMBER=2
TRACKTOTAL=11
ARTIST=King Crimson
PERFORMER=King Crimson

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

aeralahthu
()
Ответ на: комментарий от perl5_guy

Не удержался! За unless хочется убивать. Ну ладно еще die, а когда там выражение шириной в пару экранов, то вот это кайф, да. Сраные лингвисты мать вашу растак перетак.

bread
()
Ответ на: комментарий от bread

Это хитрый план по разжиганию растосрача случайное совпадение.

Слава богу, а то я уже слышал шаги вертухая vertexua за углом.

anonymous
()
Ответ на: комментарий от anonymous
push @cmd, '--'.lc($k), $v;

Э не, так не сработает. Обрати внимание, например, на эту строчку в моём скрипте:

when(/DATE/) { push @cmd, '--year', $tag{$_} }
aeralahthu
()
Ответ на: комментарий от anonymous

Ой, спасибо, но я дно, при всей моей нескромности.

Для меня первым ударом (личным) был Луговский. Физик, с научными трудами, функциональщик, эльф 80lvl. C++ хейтер, человек писавший микрокомпиляторы для лиспа, чтобы в отличие от цэпэцэ-инлайн-ассемблера, можно было в лиспо-стиле писать оптимизированный simd-код. Грустно было читать, как такое днище, вроде шомана, которому нечем гордиться, кроме как сертификатом админа красношапки, выпячивает уход луговского как своё достижение.

Еще ирси он провоцировал чтоб найти повод забанить, сам признавался. И срал из под анонимуса.

Потом, и можно заметить как деградируют скилы у сообщества, был не такой именитый, но очень классный чувак — мегабакс. Гентушник, при том, что айти не его специальность, и вёрсткой владеющий, и daily-use утилиты для генту писавший, и оверлеи c маст-хэв ебилдами державший. Самородок кароч. Выпилили.

Дальше следить было лень, зрение расфокусировалось... Сильви с знаниями всех флагов компилятора, щас Эдди. Царь (любопытнейший персонаж кстати).

Как любит повторять Тео, человек с токсичным (как сейчас говорят) характером, в сообществе хакеров всегда царила меритократия. Если ЛОР перестал к этому стремиться (а перестал очень давно, с тех пор как анскильные лалки стали модераторами), то ну и ладно. Найдём другое место где учиться и помогать друг другу.

anonymous
()
Ответ на: комментарий от aeralahthu

```perl die $usage unless defined $album_dir and -d $album_dir and defined $target_dir and -d $target_dir; ```

Зачем defined? Если `value == undef`, то оно уже `false` при проверке `-d`.

anonymous
()
Ответ на: комментарий от aeralahthu
die $usage unless -d $album_dir and -d $target_dir;
anonymous
()
Ответ на: комментарий от anonymous

Для меня первым ударом (личным) был Луговский. Физик, с научными трудами, функциональщик, эльф 80lvl.

Потом, и можно заметить как деградируют скилы у сообщества, был не такой именитый, но очень классный чувак — мегабакс.

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

Найдём другое место где учиться и помогать друг другу.

А вот это правильно. Удачи в начинаниях.

anonymous
()
Ответ на: комментарий от aeralahthu

ой, сорри.

for (my $i = 0; $i <= $#tags; $i += 2) {
    my ($k, $v) = @tags[$i, $i+1];

    if    ($k eq "DATE")        { $k = "year"  }
    elsif ($k eq "TRACKNUMBER") { $k = "track" }

    push @cmd, '--'.lc($k), $v;
}

:)

anonymous
()
Ответ на: комментарий от anonymous

Зачем defined? Если value == undef, то оно уже false при проверке -d.

Потому что при use warnings FATAL => 'all'; скрипт валится на проверке -d, если оно undef.

Рекомендуешь убрать use warnings FATAL => 'all';? Я бы не хотел.

aeralahthu
()
Ответ на: комментарий от anonymous

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

В несколько другом языке, например, я сделал так:

(define opts
    '((artist      . "--artist")
      (composer    . "--composer")
      (album       . "--album")
      (title       . "--title")
      (tracknumber . "--track")
      (date        . "--year")
      (genre       . "--genre")))

А потом уже применял их по необходимости.

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

aeralahthu
()
Ответ на: комментарий от aeralahthu

Рекомендуешь убрать use warnings FATAL => 'all';? Я бы не хотел

Перл это язык контекстуальный. Теперь ты знаешь контекст. Дальше вопрос вкуса, явное лучше неявного? Пожалуйста.

Лично для меня это излишняя «болтливость» скрипта. Неоправданное многословие в задаче которая не стоит того. Бойлерплейт.

Когда вижу маленький скрипт на 50 строк, в котором и strict, и warnings, и проверки на defined/undef/exists/ref/etc — мне это говорит, что человек использует perl не оптимально. Он либо не понимает в каком контексте обращается к перлу, и не знает как тот его поймёт, либо у него страсть к писанине, либо он старается покрыть множество неверных входных данных и исключить неопределенное поведение, которое, на мой скромный взгляд, скрипта не стОит.

Для меня ценность перла в том, что ты сам выбираешь язык обобщения. Как Ларри писал: иногда тебе нужно быстро сказать Перлу, сделай то-то и то-то, не уточняя и конкретизируя вероятности и пределы, которые имеешь в виду. И он должен сделать это без лишних вопросов.

А в сложных программах конечно. Warnings fatal.

anonymous
()
Ответ на: комментарий от aeralahthu

Я, всё-таки, склоняюсь к более универсально-абстрактным решениям.

Главное не забывать о принципах KISS, Worse is better, Unix.

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

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

anonymous
()
Ответ на: комментарий от anonymous

Это откуда инфа?)

Learning Perl:

Starting with Perl 5.12, you implicitly use this pragma when you declare a minimum Perl version:

use v5.12; # loads strict for you

Хотя https://metacpan.org/pod/distribution/perl/pod/perl5120delta.pod говорит (протестировал у себя), что получается даже с v5.11:

Using the use VERSION syntax with a version number greater or equal to 5.11.0 will lexically enable strictures just like use strict would do

goto-vlad
()
Ответ на: комментарий от goto-vlad

you implicitly use this pragma when you declare a minimum Perl version

Хух, попустило) Подумал что без прагмы `use strict` оно само активизируется. Про `use v*` упустил.

anonymous
()
Ответ на: комментарий от anonymous

Хух, попустило) Подумал что без прагмы use strict оно само активизируется. Про use v* упустил.

Каюсь, я первоначально неточно сформулировал.

goto-vlad
()
Ответ на: комментарий от bread

За unless хочется убивать.

а ты не тоже из тех кто нет да споткнётся об булеву алгебру?

Ну ладно еще die

У меня в реальном проекте есть код:

```perl %ORDER = do $order_script or die; # XXX Do we really want to die? ```

А ты так с питоном общаться не можешь) Вот и бесишься.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.