Большинство других комментариев здесь завершены, и я не буду их повторять. Я сосредоточусь на своем личном предубеждении по поводу чрезмерного или недостаточного использования языковых идиом в языке, на котором вы пишете код. Как подсказка, можно написать C на любом языке. Также можно писать нечитаемый код на любом языке.
Я проходил обучение в C и C ++ в колледже и позже изучил Perl. Perl великолепен для быстрых решений и некоторых действительно долговечных решений. Я построил компанию на Perl и Oracle для решения логистических задач для DoD с около 100 активными программистами. У меня также есть некоторый опыт в управлении привычками других программистов Perl, новыми и старыми. (Я был основателем / генеральным директором, а не непосредственно занимался техническим менеджментом ...)
Я могу только прокомментировать мой переход на Perl-программист и то, что я видел в своей компании. Многие из наших инженеров поделились своим опытом в первую очередь быть программистами на C / C ++ по выбору и программистами на Perl.
Первая проблема, которую я видел (и имел сам), - это написание кода, который настолько идиоматичен, что он не читается, не поддерживается и не может использоваться через короткий промежуток времени. Perl и C ++ имеют возможность писать краткий код, который на данный момент интересен для понимания, но вы забудете, не будете рядом, а другие его не получат.
Мы наняли (и уволили) многих программистов за 5 лет, что у меня была компания. Распространенным вопросом интервью было следующее: Напишите короткую программу на Perl, которая будет печатать все нечетные числа от 1 до 50 включительно, разделенные пробелом между каждым числом и оканчивающиеся символом CR. Не используйте комментарии. Они могут сделать это в свое собственное время на несколько минут и могут сделать это на компьютере, чтобы проверить вывод.
После того, как они написали сценарий и объяснили его, мы попросили бы его изменить его, чтобы он печатал только четные данные (перед интервьюером), а затем получили шаблон результатов, основанный на каждой четной цифре, каждой нечетной, кроме каждого седьмого и 11-го в качестве примера. Другим потенциальным модом будет каждый четный в этом диапазоне, нечетный в этом диапазоне, без простых чисел и т. Д. Цель состояла в том, чтобы проверить, выдержал ли их первоначальный небольшой сценарий изменение, отладку и обсуждение другими пользователями, и думали ли они заранее, что спецификация может измениться.
Хотя в тесте не говорилось «в одну строку», многие взяли на себя задачу сделать его одной краткой строкой и с ценой читабельности. Другие сделали полный модуль, который просто занял слишком много времени, учитывая простую спецификацию. Нашей компании нужно было очень быстро обработать твердый код; вот почему мы использовали Perl. Нам нужны были программисты, которые думали так же.
Все представленные ниже фрагменты кода делают одно и то же:
1) Слишком похоже на C, но его очень легко изменить. Из-за цикла аргумента for
в стиле C 3 требуется больше подверженных ошибкам модификаций, чтобы получить альтернативные циклы. Простая отладка и обычное представление. Любой программист практически на любом языке поймет это. Ничего особенно плохого в этом нет, но не убийца:
for($i=1; $i<=50; $i+=2) {
printf("%d ", $i);
}
print "\n";
2) Очень похоже на Perl, легко получить четность, легко (с подпрограммой) получить другие циклы или шаблоны, легко понять:
print join(' ',(grep { $_ % 2 } (1..50))), "\n"; #original
print join(' ',(grep { !($_ % 2) } (1..50))), "\n"; #even
print join(' ',(grep { suba($_) } (1..50))), "\n"; #other pattern
3) Слишком идиоматичный, немного странный, почему он пробел между результатами? Собеседник допустил ошибку в получении четного Сложнее отлаживать или читать:
print "@{[grep{$_%2}(1..50)]}\n"; #original
print "@{[grep{$_%2+1}(1..50)]}\n"; #even - WRONG!!!
print "@{[grep{~$_%2}(1..50)]}\n"; #second try for even
4) Умно! Но тоже слишком идиоматичен. Нужно подумать о том, что происходит с хешем annon, созданным из списка операторов диапазона, и почему это создает шансы и четности. Невозможно изменить другой шаблон:
print "$_ " for (sort {$a<=>$b} keys %{{1..50}}), "\n"; #orig
print "$_ " for (sort {$a<=>$b} keys %{{2..50}}), "\n"; #even
print "$_ " for (sort {$a<=>$b} values %{{1..50}}), "\n"; #even alt
5) Kinda C, как снова, но прочная основа. Легко изменить за пределы четного / нечетного. Очень читабельно:
for (1..50) {
print "$_ " if ($_%2);
} #odd
print "\n";
for (1..50) {
print "$_ " unless ($_%2);
} #even
print "\n";
6) Возможно, мой любимый ответ.Очень Perl, как и все же читаемый (для меня в любом случае) и пошаговый в формировании и справа налево в потоке.Список находится справа и может быть изменен, обработка сразу же слева, повторное форматирование слева, последняя операция «печать» слева.
print map { "$_ " } grep { $_ & 1 } 1..50; #original
print "\n";
print map { "$_ " } grep { !($_ & 1) } 1..50; #even
print "\n";
print map { "$_ " } grep { suba($_) } 1..50; #other
print "\n";
7) Это мой наименее любимый заслуживающий доверия ответ.Ни C, ни Perl невозможно изменить без потрошения цикла, в основном показывая, что заявитель знал синтаксис массива Perl.Он очень хотел получить заявление по делу ...
for (1..50) {
if ($_ & 1) {
$odd[++$#odd]="$_ ";
next;
} else {
push @even, "$_ ";
}
}
print @odd, "\n";
print @even;
Опрошенные с ответами 5, 6, 2 и 1 получили работу и справились хорошо.Ответы 7,3,4 не получили наем.
Ваш вопрос касался использования динамических конструкций, таких как eval
или других, которые вы не можете сделать на чисто скомпилированном языке, таких как C. Этот последний пример является "динамическим" с eval в регулярном выражении, но действительно плохим стилем:
$t='D ' x 25;
$i=-1;
$t=~s/D/$i+=2/eg;
print "$t\n"; # don't let the door hit you on the way out...
Многие скажут вам "не пишите C на Perl".Я думаю, что это только частично правда.Ошибка и ошибка в том, что нужно жестко писать новый код Perl в стиле C, даже если в Perl так много выразительных форм.Используйте те.И да, не пишите НОВЫЙ код Perl в стиле C, потому что синтаксис C и идиома - это все, что вы знаете.(плохая собака - без печенья)
Не пишите динамический код на Perl только потому, что вы можете.Есть определенные алгоритмы, которые вы встретите, и вы скажете: «Я не совсем знаю, как написать TH на C», и многие из них используют eval.Вы можете написать регулярное выражение Perl для анализа многих вещей (XML, HTML и т. Д.), Используя рекурсию или eval в регулярном выражении, но вы не должны этого делать.Используйте синтаксический анализатор точно так же, как в C. Есть определенные алгоритмы, хотя eval
- это подарок.Исправление имени файла Ларри Уолла переименование потребовало бы намного больше кода C для репликации, не так ли?Есть много других примеров.
Также не избегайте строгого определения стиля C.Форма аргумента C 3 цикла for
может идеально подходить для определенных алгоритмов.Кроме того, помните, почему вы используете Perl: предположительно для высокой производительности программиста.Если у меня есть полностью отлаженный кусок кода C, который делает именно то, что я хочу, и мне это нужно в Perl, я просто переписываю глупый стиль C в Perl!Это одна из сильных сторон языка (но также и его слабость для более крупных или командных проектов, где отдельные стили кодирования могут различаться и затруднять соблюдение общего кода.)
Безоговорочно устная реакция на это интервьюВопрос (от заявителя, который написал ответ 6) был: Эта единственная строка кода соответствует спецификации и может быть легко изменена.Однако есть много других способов написать это.Правильный путь зависит от стиля окружающего кода, от того, как он будет вызываться, от соображений производительности и от того, может ли измениться формат вывода. Чувак!Когда ты можешь начать??(Он оказался в управлении BTW.)
Я думаю, что отношение также относится к вашему вопросу.