Pull to refresh

Comments 49

Цель топика (и сразу же дисклеймер) — помочь начинающим не впадать в кататонический ступор при виде чего-то вроде

user[(os[((user.microsoft_adept ? microsoft : apple).system || "linux")].install_carma <= user.carma) ? "install" : "cant_install"](os[((user.microsoft_adept ? microsoft : apple).system || "linux")].name);


А где тут можно впасть в ступор, я что-то не понял?
Пожалуйста, прочитайте дисклеймер внимательнее. Статья рассчитана на начинающего. Мы с вами, надеюсь, не впадём.
Тут речь не о ступоре. Такой код просто выкидывается, человеку, который его написал, пишется выговор, и другой программист уже реализует задачу по-человечески.

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
— Martin Fowler
Сразу видно, вам никогда не доводилось работать в компании, которая занимается сопровождением и/или кризисным менеджментом чужих проектов. Чтобы чужой код выбросить, необходимо его сначала понять. А чтобы уволить программиста, необходимо его сначала нанять. А чтобы избить программиста, необходимо хотя бы приблизительно знать, кто он такой.
Я выбираю компании, где мне комфортно работать.
Круто. Ну не всем же быть д'Артаньянами.
А что вас заставляет выбирать компании, где некомфортно работать?
Из чего вы сделали [неверный] вывод, что я выбираю компании, где мне некомфортно?

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

Если ко мне прибежит мой программист и скажет, что «автора этого нужно выпороть, а я перепишу все с нуля» — я уволю именно этого программиста.
У нас с вами разные подходы к разработке.
Вам присуще странное стремление сделать выводы за окружающих.

Подход к разработке у всех (в идеале) один и тот же: сделать хорошо. Это косвенно подразумевает, что вы правы. Но.

У нас разный подход к сопровождению, да и опыта у меня поболее. Опыт мне подсказывает, что в любом мало-мальски значимом проекте наступает стадия, когда проект вдруг «выстреливает». Команда — отличная, проект — интересный. Но он был начат, например, восемь лет назад. Или двенадцать. Или семнадцать (личного опыта бо́льших сроков у меня нет, кроме совсем уж заскорузлых КОБОЛов, но они явно не относятся к категории интересных проектов). И вот ты переписываешь все «как надо», избавляешься от поддержки IE3 (я не шучу), тестируешь стресс-тестами и руками у себя, как можешь. Выкатываешь в продакшн — и триста тысяч пользователей отвалилось. Знаете, что нормальный человек в таком случае сделает? — Вернет, как было.

Я же не спорю с тем, что _при прочих равных_ вы абсолютно правы. Я говорю лишь, что уметь читать любой код — важная и нужная задача. Например, я не верю в то, что можно писать на js, не имея представления о LISP'е и перле. Возможно, я и ошибаюсь, но, опять-таки, наш с трудными ошибками общий сын подсказывает иное.
да и опыта у меня поболее


А каким образом вы сравнивали? Мы с вами, вроде, не знакомы, чтобы вы могли знать: какой у меня опыт.
Я верю людям и умею заглядывать в профиль.

В 1986 году я написал первую программу на фортране. Доставайте свой :-)
То есть опыт для вас — временной отрезок? Я встречаю людей за сорок, которые приходят ко мне на собеседования. Мои стажеры по уровню их превосходят. Для меня опыт, измеряемый во времени, ни о чем не говорит.
Уровень и опыт — это не синонимы.

И вообще, я уже вижу, какой вы крутой. Не нужно мне это лишний раз демонстрировать.
В принципе, ничего нового лично для меня нет. Однако, после прочтения статьи при виде этой строчки всё ещё впадаю в «кататонический ступор»
Я правильно понимаю, что в примере пользователь просто не сможет поставить линукс? При наличии apple и microsoft до || «linux» просто не дойдёт.
В приведённом исходнике не сможет. Сможет, если у производителя согласно предпочтениями системы по каким-то причинам не окажется
var apple = {
    //system: "macos"
}

или
var microsoft = {
    system: false
}
Вот более живой пример:
var checksystem='linux' //Систему которую надо проверить

user[(os[checksystem].install_carma <= user.carma &&
(checksystem=='windows' || !user.microsoft_adept)) ? "install" : "cant_install"](checksystem );


И адептам майкрософт нельзя ставить линукс.
Некоторые неточности, которые бросились в глаза:

«Условный оператор || в Javascript интересен тем, что возвращает первое ненулевое значение»
— здесь необходимо уточнить, что такое «ненулевое значение», так как к нулём оно слабо связано.

«чему способствует низкий приоритет тернарного оператора: console.log( (a > b)? „a больше b“: „a меньше или равно b“ );»
— при чем здесь приоритет, если первые скобки это вывоз метода, а вторые явное указание этого самого приритета?
Подобный оператор, возвращает первое «ненулевое значение» не только в javascript, но и в других языках.
С точки зрения «алгебры логики», если у нас несколько условий, объединенных оператором «или», то «true» оно же «ненулевое значение», в цепочке, будет возвращено если хотя бы 1 условие будет истинно. Тот же эффект и с оператором «и», только в его случае будет возвращен «false», если хоть 1 false встретиться.

Просто при обработке, условия проверяются по порядку, и на этапе когда мы уже точно знаем значение всего оператора, не имеет смысла тратить время на проверку остальных условий. Об этом стоит помнить начинающим, при составлении условий.
ненулевое — не совсем корректное определение, null или undefined тоже ведь не нуль
Оператор ToBoolean («к булевскому») преобразует свой аргумент в значение типа Boolean согласно следующей таблице:

Входной тип Результат
Undefined false

Null false

Boolean Результат совпадает с входным аргументом (преобразование не производится).

Number Результат равен false, если аргумент равен +0, -0 или NaN, иначе результат равен true.

String Результат равен false, если аргумент является пустой строкой (его длина равна нулю), иначе результат равен true.

Object true
Вы нам-то зачем это рассказываете? :)
Мы это и так знаем, просто в тексте статьи есть неточность.
Вместо «ненулевое значение» стоит написать что-то вроде «false-like» и попутно пояснить о чем речь.

Глубинный смысл тут в том, что в Javascript оператор "!" (not) — булевский, а "&&" (and) и "||" (or) — нет! Хотя их действие внешне очень похоже.

Я бы еще где-нибудь упомянул про врожденную болезнь джаваскрипта, оператор "==".
Грешу последнее время использованием логического «И» следующим образом:
y === 5 && doSomething()
Это аналог
if(y === 5) doSomething()
Тернарный оператор не устраивал обязательным указанием действия else.
y === 5 && doSomething()
А что именно тут происходит?
x && y && z — здесь возвращается либо первое вхождение false (0, '', null) либо последний аргумент в выражении.

1 && false && null //false
null && 231 && 4 //null
'valera' && 5 && 10 //10

В случае, описанном выше, если (y === 5) === false, то функция не выполнится, и наоборот.
Знаете, если человек в состоянии заменить
if (x % 2 > 0) doSomething();
на
if (x & 1) doSomething();

То я пойму, что он сделал, и почему это (возможно) лучше. А вот плюсов вашего стиля честно говоря не вижу. Кроме самовыражения.
Во-первых, я привел не лучший пример.

Во-вторых я просто не люблю такие вот конструкции:
if(somthing) doSomething();

И использую всегда блоки:
if(something) {
doSomething();
}

Возможно, из-за того, что ифы без фигурных скобок меня немного запутывают. Это субъективно.
Я тоже всегда ставлю фигурные скобки. Но я говорил вот о таких конструкциях.
y === 5 && doSomething()
Ифы без фигурных скобок могут сильно подгадить в случае, когда нужно дописать вторую строчку в тело оператора и человек впопыхах забывает дописать скобки. Стиль, который способствует возникновению ошибки — это худший вариант стиля.

P.S. Я бы на все кодерские сайты вешал бы в качестве правил использования полный текст Code Complete МакКоннела и кнопку под ним «я полностью прочел и усвоил прочитанное» :)
Может быть, привычки из пхп/перловского «mysql_connect() or die()»
В чем же здесь грех? Вполне себе практика.
Как минимум не вредит читаемости.
Правда, в языках, где void не кастится по умолчанию к false в булевых операциях, подобный подход налагает требование возвращать каждой используемой функции подходящее значение.
А вот товарищу выше мой стиль показался попыткой самовыражения.
Функцию после && я указал для наглядности, чаще я делаю так:
bool && (x=5)
Попробуйте перейти на это: y === 5? doSomething(): 0
В интерпретируемых языках ваш вариант пойдёт, а в каком порядке компилятор решит выдать условия после оптимизации, это уже загадка.
Вопрос ниразу не в тему: Разве дисклеймер это не «Отказ от ответственности»?

Во всех лицензиях есть такой пункт «15. Disclaimer of Warranty.» (GPL: www.gnu.org/copyleft/gpl.html) которое переводится как отсутствие обязательств.

В свою очередь лигва тоже утверждает: disclaimer [dɪs'kleɪmə] 2) письменный отказ от ответственности.

Однако это не первая статья, в которой это слово употребляется в роли «важный комментарий» или типа того. И мне не понятно — я это слово по английски не так пишу, или у него несколько смыслов? И как тогда правильно его писать и что оно точно значит?
я про вот это место:
Цель топика (и сразу же дисклеймер) — помочь начинающим не впадать в кататонический ступор при виде чего-то вроде

в следующем абзаце вроде нормальное использование :)
Вы правы, ITшники disclaim частенько как declare понимают в подобных случаях и не слишком правильно используют.
… и частенько не осознают, что «disclaimer» это не обязательно «disclaimer of responsibility».
Так ведь тут и есть отказ от ответственности за растолковывание элементарных вещей, к которой автора могли бы призвать какие-нибудь горячие головы.
Нельзя писать такие статьи, ибо начинающие подумают что это хорошо.
прототипы почему-то не вспоминаются,
Указанные примеры непонимание могут вызвать, если с синтаксисом человек не знаком, а это уже ну оооочень начинающий, и не к объектам ему на данном этапе.
> console.log( (a > b)? «a больше b»: «a меньше или равно b» );
--зачем вводить начинающих в заблуждение и писать лишние скобки? У тернарного оператора в выражении — самый низкий приоритет. За ним идут только привоения и запятая.
Про все эти особенности рассказывается на первых 100 страницах Флэнагана (про оператор ||, про доступ к полям объекта через квадратные скобки, даже про y === 5 && doSomething() ), начинающим JavaScript программистам нужно прочитать эту книгу обязательно :)

Писать так конечно можно, но читать будет сложновато, лучше в релизе выпустить сжатый вариант JS кода и не экономить на строчках при разработке.
Один мой знакомый обожает вставлять тернарный оператор вместо if (используя тернарник как lvalue):
myBoolean? execute1(): execute2();

Мне повезло, что он не знает про y === 5 && doSomething()

На мой взгляд if должен быть if'ом. Все вот эти синтаксические хаки имхо хороши только если
1) укорачивают конструкцию и используются обфускаторами
или
2) не ухудшают читаемость кода
а что, y === 5 && doSomething() ухудшает читаемость что ли?
При первом взгляде лично мне был неочевиден приоритет операций. Не думаю, что такая тривиальная по своей задумке инструкция заслуживает такого к себе внимания со стороны ревьюера.
Конечно не заслуживает. Потому что надо знать приоритет операций в языке.
Мне кажется, что писать нужно максимально очевидно, пример с y === 5 && doSomething() это ОК, проблем тут нет, одна операция, а вот user[(os[((user.microsoft_adept ? microsoft : apple).system || "linux")].install_carma <= user.carma) ? "install" : "cant_install"](os[((user.microsoft_adept ? microsoft : apple).system || "linux")].name); это уже жопа, можно сидеть и мысленно парсить строчку, прикидывая что и в какой последовательности выполняется, но зачем, если разбить все на несколько выражений, то возможно получится и менее круто, но намного понятнее для чтения. Но уметь надо, чтобы читать, что написали товарищи не особо заботившиеся о будущем.

Приоритеты знать надо безусловно, но в строке с десятком операций скобки все равно лучше расставить, так намного быстрее и читается и понимается позднее, бросил взгляд и все понятно.
Sign up to leave a comment.

Articles