Pull to refresh
40
0
Павлов Николай Александрович @ZyXI

Инженер

Send message
Здесь не научная статья. Никому низачем не нужно чёткого определения термина «язык общего назначения». Совсем. Умные люди отлично понимают нечёткие определения, тем более, что в обычном толковом словаре большинство именно такие.
Когда говорят «универсальный язык программирования» обычно имеют ввиду язык, который
  1. Изначально предназначался для решения широкого спектра задач.
  2. Является Тьюринг‐полным.
  3. На котором при этом люди реально могут решить практически всё — от написания текстового редактора до 3D‐рендеринга. Разумеется, это «всё» они могли бы решить лучше (быстрее и/или с меньшими затратами ресурсов компьютера) на других языках… если бы умели на них писать, причём быстро.
При этом из «всего» на самом деле исключены узкоспециализированные задачи: написание прошивок, скриптование ПО, не поддерживающего язык, …

В общем, данный термин не следует воспринимать совсем уж буквально. Текст или речь, произведённые людьми вообще не стоит воспринимать буквально практически никогда — математические доказательства есть практически единственные тексты, автор которых предполагал или должен был предполагать их буквальную интерпретацию.
Это для Python (и для большинства остальных языков, где есть нечто подобное). В некоторых языках такое поведение будет неожиданным. Правда я из таких знаю только VimL¹, а это никак не образец хорошего внутреннего устройства. Про PHP не знаю.

¹ Ошибки, использующиеся вместо SyntaxError, можно отловить прямо на месте, т.к. в VimL команда всегда заканчивается в конце строки, если только используемый метод получения строк не предоставляет их в виде одной \n‐разделённой C’шной строки (особенность реализации, которую мне придётся поддерживать).
По этой же причине нельзя забывать про LOAD_GLOBAL (у вас его нету). Если значение n изменится после LOAD_GLOBAL, но перед STORE_GLOBAL, то результат будет некорректным. А это три промежутка, куда можно вклинится.
Ну, то есть, не здесь, а у Ostrovski. Целое у него.
Здесь INPLACE_ADD будет делать ровно то же самое, что и BINARY_ADD. Опкодов два: INPLACE_ADD и STORE_FAST. Уберите STORE_FAST и получите, что ничего не изменилось.

Это не список, у которого определён __iadd__. Это неизменяемое целое.
Если это не GVim, то могут быть проблемы с кодировкой терминала. А GVim в Windows тоже на GTK? А то я вижу подозрительный файл src/gui_w32.c. Может ему нужна соответствующая &termencoding.

Впрочем, я не слишком хорошо знаю эту кухню с кодировками, особенно на Windows. У меня просто везде UTF-8. Хотя в тестах моих дополнений в Wine вроде set encoding=utf-8 и scriptencoding utf-8 во всех скриптах было достаточно.
Установка UTF-8 когда и к нечитабельному тексту где? Делать set encoding=utf-8 где‐либо, кроме vimrc, совершенно не рекомендуется, т.к. приводит к тому, что строки, уже хранящиеся в памяти, становятся неправильными.

И, кстати, Vim всегда брал и сейчас берёт кодировку из окружения. Я не помню, чтобы что‐то здесь менялось (что точно менялось — работа с именами файлов и, возможно, переменными окружения).
Скрытый текст
Насколько мне помнится, этот генератор изначально отсутствовал, находясь под запретом из‐за >21 века создания. Потом был переизобретён Великим Драконом, который, прокачав теорию, понял, что использовать его нельзя. Так что в книгах он упоминался, но не использовался. И в любом случае, вы говорили про материю. Генератор запретили раньше появления станции на Кванторе, и намного. А до латинян с дубликатором на Кванторе были хронофизики, они звезду не на материю перерабатывали.
Где? Дубликатор косвенно* работал на веществе звезды, генераторы замедляли соседние континуумы. Больше ничего похожего на «из неоктуда» не помню.

* посредством предварительного преобразования оного в какой‐то особый вид энергии.
На вершине стека вы в лучем случае получаете DivisionByZero. Полностью бесполезный, у вас там снизу 50 функций.
Там есть возможность с помощью макросов file! и line! получить номер строки в файле. Просто напишите свой try!, который будет не просто возвращать ошибку, а ещё и добавлять к ней информацию о том, где она пробрасывалась. Это вариант 3, но «кучу кода» пишет компилятор. Эти же макросы могут быть использованы и в месте генерации ошибки.

Локальные переменные вы, конечно, не получите (а, может, я просто плохо знаю макросы Rust). Но это всё же лучше, чем стандартный вариант.
Каким метатегам? Если вы про Content-Type заголовок в письмах или про определение типа содержимого по примитивным сигнатурам вида «если в начале файла %PDF-, то это application/pdf» (примерно так делает утилита file и все остальные, если он используют библиотеку libmagic), то злоумышленникам так даже легче будет (пользователи привыкли смотреть расширение, а тут javascript с .doc, причём расширение даже прятать не надо).
Гм. Откуда в this возьмётся age?

Кроме того, у вас здесь три строчки «мусора»: кода, который не нужен для восприятия алгоритма (если такие конструкции раскиданы по всему коду, то к ним быстро привыкаешь), а также кода, который это восприятие затрудняет (если вы такую конструкцию видите в первый раз, то понять, что она делает, гораздо сложнее, чем в варианте с this.age = age || 10;).

Даже более того, вы используете ||. Супер! Будучи применённой к значениям внутри по‐первости (если о новичках: людях, плохо знакомых с вашим кодом) непонятного объекта defs (definitions? defaults? ещё что‐то?) она, разумеется, становится понятнее, чем в this.age = age || 10;.

Переменная defs понадобится только, если переменных уж слишком много: в этом случае для установки значений будет использоваться функция вида mergeObjects(this, args, defaults), а все переменные будут в объекте args.
В neovim одно время использовался moonscript. Если забыть про прочие проблемы (малое число разработчиков, синтаксис, который многим не нравится, отсутствие в ряде дистрибутивов), то мы напоролись на довольно странную проблему: тесты с moonscript уходят в бесконечный цикл, со сгенерированным lua — нет. В связи с тем, что проблема была не единственная и фактически не приводимая к простому примеру, то особо разбираться никто не стал: просто сказали, что все тесты теперь на lua (раньше сначала говорили, что все тесты на moonscript, но из-за сопротивления разработчиков разрешили lua и moonscript; теперь только lua).
Здесь есть кнопка «ответить» под комментарием. Используйте её всегда, когда отвечаете на чей‐то комментарий; уже открытая форма существует только для ответа на саму статью. Иначе вы получаете минусы, вот как сейчас: люди ставят минус, не смотря в профиль на количество комментариев (тот на который я отвечаю — второй) или полагают, что после первого до вас должно было уже дойти, что здесь что‐то не так.
Мозг — не компьютер. Оба варианта воспринимаются как «если не возраст, то возраст равен 10», если вы знакомы с этим хаком.

А если вы достаточно длительное время писали на Perl’е (почему‐то там я использовал эту конструкцию чаще всего), то age = age || 10 будет восприниматься именно так: «если возраст не определён, то он равен 10». Вам нужно обновить свою версию «встроенного в мозг интерпретатора»: он вполне способен по ходу дела повышать уровень абстрагирования. Не думаю, что тут имеет смысл сравнивать энергетические затраты на повышение уровня с затратами на чтение вчетверо большего числа строчек.

Ктати, если переменных со значением по‐умолчанию больше одной, то || всегда лучше:

this.age = age || 10;
this.sex = sex || "Male";

if (!age) {
    age = 10;
}
if (!sex) {
    sex = 10;
}
this.age = age;
this.sex = sex;
В tutorial’ах по значительной части динамических языков этот трюк описан и иногда даже рекомендован: из тех языков, что я знаю так делают Perl, Python, Ruby, Shell¹, Lua. В последнем так вообще вместо тернарного оператора (которого нет) часто используется a and b or c (в отличие от того же Python b здесь не должно быть всего лишь nil и false, что сильно расширяет область применимости).

Так что понимание такого кода достаточно вероятно.

¹ Речь идёт о только кодах возврата (т.е. о “присвоении” $?), что практически бесполезно. Конструкция $(( a || b )) может вернуть только 1 или 0.
И? Предложено было собирать свой пакет для дистрибутивного менеджера пакетов. Ни один такой менеджер не запрещает вам быть maintainer’ом своего же пакета. И даже собирать его в той же системе, в которой он будет использоваться.
Вообще‐то он говорит собрать свой пакет, а не полагаться на какого‐то maintainer’а. Это не так уж и сложно, тем более что для gem’ов наверняка тоже есть что‐то готовое. Я же говорю, что sudo python setup.py install не так уж и страшен, и рассказывать про сборку пакетов в статье про fail2ban совершенно не нужно.
уважаемый, я очень ценю ваш труд, но почему, почему вы, чёрт возьми, make install? Сколько раз твердили миру…
Почему бы не научить, как собрать пакет и поставить его — ну реально на две команды больше, а жизнь облегчится…
Вы не работали с Python. Если автор Python’овского пакета адекватен и использовал стандартные distutils, то pip install … и cd … && python setup.py install не отличаются по своему результату.

Так что не надо. python setup.py install — это далеко не make install. Но только если вы считаете, что управление системными пакетами двумя менеджерами пакетов (pip и apt или что у вас там) — хорошая идея. Учитывая, что целью данной статьи не было обучение аудитории сборке пакетов на всех 100500 дистрибутивах и пакеты с distutils собираются элементарно, то всё в порядке.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity