Комментарии 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
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
— Martin Fowler
Сразу видно, вам никогда не доводилось работать в компании, которая занимается сопровождением и/или кризисным менеджментом чужих проектов. Чтобы чужой код выбросить, необходимо его сначала понять. А чтобы уволить программиста, необходимо его сначала нанять. А чтобы избить программиста, необходимо хотя бы приблизительно знать, кто он такой.
Я выбираю компании, где мне комфортно работать.
Круто. Ну не всем же быть д'Артаньянами.
А что вас заставляет выбирать компании, где некомфортно работать?
Из чего вы сделали [неверный] вывод, что я выбираю компании, где мне некомфортно?
Я просто не забываю, что кроме меня в мире живет еще примерно 7 миллиардов чуваков и у всех — разные судьбы. Бывает, что нужно срочно поправить чей-то код. Это может быть сторонняя библиотека. А может быть и код уволившегося три года назад быдлокодера.
Если ко мне прибежит мой программист и скажет, что «автора этого нужно выпороть, а я перепишу все с нуля» — я уволю именно этого программиста.
Я просто не забываю, что кроме меня в мире живет еще примерно 7 миллиардов чуваков и у всех — разные судьбы. Бывает, что нужно срочно поправить чей-то код. Это может быть сторонняя библиотека. А может быть и код уволившегося три года назад быдлокодера.
Если ко мне прибежит мой программист и скажет, что «автора этого нужно выпороть, а я перепишу все с нуля» — я уволю именно этого программиста.
У нас с вами разные подходы к разработке.
Вам присуще странное стремление сделать выводы за окружающих.
Подход к разработке у всех (в идеале) один и тот же: сделать хорошо. Это косвенно подразумевает, что вы правы. Но.
У нас разный подход к сопровождению, да и опыта у меня поболее. Опыт мне подсказывает, что в любом мало-мальски значимом проекте наступает стадия, когда проект вдруг «выстреливает». Команда — отличная, проект — интересный. Но он был начат, например, восемь лет назад. Или двенадцать. Или семнадцать (личного опыта бо́льших сроков у меня нет, кроме совсем уж заскорузлых КОБОЛов, но они явно не относятся к категории интересных проектов). И вот ты переписываешь все «как надо», избавляешься от поддержки IE3 (я не шучу), тестируешь стресс-тестами и руками у себя, как можешь. Выкатываешь в продакшн — и триста тысяч пользователей отвалилось. Знаете, что нормальный человек в таком случае сделает? — Вернет, как было.
Я же не спорю с тем, что _при прочих равных_ вы абсолютно правы. Я говорю лишь, что уметь читать любой код — важная и нужная задача. Например, я не верю в то, что можно писать на js, не имея представления о LISP'е и перле. Возможно, я и ошибаюсь, но, опять-таки, наш с трудными ошибками общий сын подсказывает иное.
Подход к разработке у всех (в идеале) один и тот же: сделать хорошо. Это косвенно подразумевает, что вы правы. Но.
У нас разный подход к сопровождению, да и опыта у меня поболее. Опыт мне подсказывает, что в любом мало-мальски значимом проекте наступает стадия, когда проект вдруг «выстреливает». Команда — отличная, проект — интересный. Но он был начат, например, восемь лет назад. Или двенадцать. Или семнадцать (личного опыта бо́льших сроков у меня нет, кроме совсем уж заскорузлых КОБОЛов, но они явно не относятся к категории интересных проектов). И вот ты переписываешь все «как надо», избавляешься от поддержки IE3 (я не шучу), тестируешь стресс-тестами и руками у себя, как можешь. Выкатываешь в продакшн — и триста тысяч пользователей отвалилось. Знаете, что нормальный человек в таком случае сделает? — Вернет, как было.
Я же не спорю с тем, что _при прочих равных_ вы абсолютно правы. Я говорю лишь, что уметь читать любой код — важная и нужная задача. Например, я не верю в то, что можно писать на js, не имея представления о LISP'е и перле. Возможно, я и ошибаюсь, но, опять-таки, наш с трудными ошибками общий сын подсказывает иное.
да и опыта у меня поболее
А каким образом вы сравнивали? Мы с вами, вроде, не знакомы, чтобы вы могли знать: какой у меня опыт.
Я верю людям и умею заглядывать в профиль.
В 1986 году я написал первую программу на фортране. Доставайте свой :-)
В 1986 году я написал первую программу на фортране. Доставайте свой :-)
То есть опыт для вас — временной отрезок? Я встречаю людей за сорок, которые приходят ко мне на собеседования. Мои стажеры по уровню их превосходят. Для меня опыт, измеряемый во времени, ни о чем не говорит.
В принципе, ничего нового лично для меня нет. Однако, после прочтения статьи при виде этой строчки всё ещё впадаю в «кататонический ступор»
Я правильно понимаю, что в примере пользователь просто не сможет поставить линукс? При наличии apple и microsoft до || «linux» просто не дойдёт.
Вот более живой пример:
И адептам майкрософт нельзя ставить линукс.
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 интересен тем, что возвращает первое ненулевое значение»
— здесь необходимо уточнить, что такое «ненулевое значение», так как к нулём оно слабо связано.
«чему способствует низкий приоритет тернарного оператора: console.log( (a > b)? „a больше b“: „a меньше или равно b“ );»
— при чем здесь приоритет, если первые скобки это вывоз метода, а вторые явное указание этого самого приритета?
Подобный оператор, возвращает первое «ненулевое значение» не только в javascript, но и в других языках.
С точки зрения «алгебры логики», если у нас несколько условий, объединенных оператором «или», то «true» оно же «ненулевое значение», в цепочке, будет возвращено если хотя бы 1 условие будет истинно. Тот же эффект и с оператором «и», только в его случае будет возвращен «false», если хоть 1 false встретиться.
Просто при обработке, условия проверяются по порядку, и на этапе когда мы уже точно знаем значение всего оператора, не имеет смысла тратить время на проверку остальных условий. Об этом стоит помнить начинающим, при составлении условий.
С точки зрения «алгебры логики», если у нас несколько условий, объединенных оператором «или», то «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
Входной тип Результат
Undefined false
Null false
Boolean Результат совпадает с входным аргументом (преобразование не производится).
Number Результат равен false, если аргумент равен +0, -0 или NaN, иначе результат равен true.
String Результат равен false, если аргумент является пустой строкой (его длина равна нулю), иначе результат равен true.
Object true
Вы нам-то зачем это рассказываете? :)
Мы это и так знаем, просто в тексте статьи есть неточность.
Вместо «ненулевое значение» стоит написать что-то вроде «false-like» и попутно пояснить о чем речь.
Глубинный смысл тут в том, что в Javascript оператор "!" (not) — булевский, а "&&" (and) и "||" (or) — нет! Хотя их действие внешне очень похоже.
Я бы еще где-нибудь упомянул про врожденную болезнь джаваскрипта, оператор "==".
Мы это и так знаем, просто в тексте статьи есть неточность.
Вместо «ненулевое значение» стоит написать что-то вроде «false-like» и попутно пояснить о чем речь.
Глубинный смысл тут в том, что в Javascript оператор "!" (not) — булевский, а "&&" (and) и "||" (or) — нет! Хотя их действие внешне очень похоже.
Я бы еще где-нибудь упомянул про врожденную болезнь джаваскрипта, оператор "==".
Грешу последнее время использованием логического «И» следующим образом:
y === 5 && doSomething()
Это аналог
if(y === 5) doSomething()
Тернарный оператор не устраивал обязательным указанием действия else.
y === 5 && doSomething()
Это аналог
if(y === 5) doSomething()
Тернарный оператор не устраивал обязательным указанием действия else.
y === 5 && doSomething()
А что именно тут происходит?
Знаете, если человек в состоянии заменить
if (x % 2 > 0) doSomething();
на
if (x & 1) doSomething();
То я пойму, что он сделал, и почему это (возможно) лучше. А вот плюсов вашего стиля честно говоря не вижу. Кроме самовыражения.
if (x % 2 > 0) doSomething();
на
if (x & 1) doSomething();
То я пойму, что он сделал, и почему это (возможно) лучше. А вот плюсов вашего стиля честно говоря не вижу. Кроме самовыражения.
Во-первых, я привел не лучший пример.
Во-вторых я просто не люблю такие вот конструкции:
if(somthing) doSomething();
И использую всегда блоки:
if(something) {
doSomething();
}
Возможно, из-за того, что ифы без фигурных скобок меня немного запутывают. Это субъективно.
Во-вторых я просто не люблю такие вот конструкции:
if(somthing) doSomething();
И использую всегда блоки:
if(something) {
doSomething();
}
Возможно, из-за того, что ифы без фигурных скобок меня немного запутывают. Это субъективно.
Я тоже всегда ставлю фигурные скобки. Но я говорил вот о таких конструкциях.
y === 5 && doSomething()
y === 5 && doSomething()
Ифы без фигурных скобок могут сильно подгадить в случае, когда нужно дописать вторую строчку в тело оператора и человек впопыхах забывает дописать скобки. Стиль, который способствует возникновению ошибки — это худший вариант стиля.
P.S. Я бы на все кодерские сайты вешал бы в качестве правил использования полный текст Code Complete МакКоннела и кнопку под ним «я полностью прочел и усвоил прочитанное» :)
P.S. Я бы на все кодерские сайты вешал бы в качестве правил использования полный текст Code Complete МакКоннела и кнопку под ним «я полностью прочел и усвоил прочитанное» :)
Может быть, привычки из пхп/перловского «mysql_connect() or die()»
В чем же здесь грех? Вполне себе практика.
Как минимум не вредит читаемости.
Правда, в языках, где void не кастится по умолчанию к false в булевых операциях, подобный подход налагает требование возвращать каждой используемой функции подходящее значение.
Как минимум не вредит читаемости.
Правда, в языках, где void не кастится по умолчанию к false в булевых операциях, подобный подход налагает требование возвращать каждой используемой функции подходящее значение.
Попробуйте перейти на это: y === 5? doSomething(): 0
В интерпретируемых языках ваш вариант пойдёт, а в каком порядке компилятор решит выдать условия после оптимизации, это уже загадка.
В интерпретируемых языках ваш вариант пойдёт, а в каком порядке компилятор решит выдать условия после оптимизации, это уже загадка.
Вопрос ниразу не в тему: Разве дисклеймер это не «Отказ от ответственности»?
Во всех лицензиях есть такой пункт «15. Disclaimer of Warranty.» (GPL: www.gnu.org/copyleft/gpl.html) которое переводится как отсутствие обязательств.
В свою очередь лигва тоже утверждает: disclaimer [dɪs'kleɪmə] 2) письменный отказ от ответственности.
Однако это не первая статья, в которой это слово употребляется в роли «важный комментарий» или типа того. И мне не понятно — я это слово по английски не так пишу, или у него несколько смыслов? И как тогда правильно его писать и что оно точно значит?
Во всех лицензиях есть такой пункт «15. Disclaimer of Warranty.» (GPL: www.gnu.org/copyleft/gpl.html) которое переводится как отсутствие обязательств.
В свою очередь лигва тоже утверждает: disclaimer [dɪs'kleɪmə] 2) письменный отказ от ответственности.
Однако это не первая статья, в которой это слово употребляется в роли «важный комментарий» или типа того. И мне не понятно — я это слово по английски не так пишу, или у него несколько смыслов? И как тогда правильно его писать и что оно точно значит?
я про вот это место:
Цель топика (и сразу же дисклеймер) — помочь начинающим не впадать в кататонический ступор при виде чего-то вроде
в следующем абзаце вроде нормальное использование :)
Цель топика (и сразу же дисклеймер) — помочь начинающим не впадать в кататонический ступор при виде чего-то вроде
в следующем абзаце вроде нормальное использование :)
Так ведь тут и есть отказ от ответственности за растолковывание элементарных вещей, к которой автора могли бы призвать какие-нибудь горячие головы.
Напомнило: www.artlebedev.ru/tools/technogrette/js/likbez/
Статья называется «Нетривиальный синтаксис»
Я бы даже сказал, что подозрительно похожи
Статья называется «Нетривиальный синтаксис»
Я бы даже сказал, что подозрительно похожи
Нельзя писать такие статьи, ибо начинающие подумают что это хорошо.
прототипы почему-то не вспоминаются,
Указанные примеры непонимание могут вызвать, если с синтаксисом человек не знаком, а это уже ну оооочень начинающий, и не к объектам ему на данном этапе.
Указанные примеры непонимание могут вызвать, если с синтаксисом человек не знаком, а это уже ну оооочень начинающий, и не к объектам ему на данном этапе.
> console.log( (a > b)? «a больше b»: «a меньше или равно b» );
--зачем вводить начинающих в заблуждение и писать лишние скобки? У тернарного оператора в выражении — самый низкий приоритет. За ним идут только привоения и запятая.
--зачем вводить начинающих в заблуждение и писать лишние скобки? У тернарного оператора в выражении — самый низкий приоритет. За ним идут только привоения и запятая.
Про все эти особенности рассказывается на первых 100 страницах Флэнагана (про оператор ||, про доступ к полям объекта через квадратные скобки, даже про y === 5 && doSomething() ), начинающим JavaScript программистам нужно прочитать эту книгу обязательно :)
Писать так конечно можно, но читать будет сложновато, лучше в релизе выпустить сжатый вариант JS кода и не экономить на строчках при разработке.
Писать так конечно можно, но читать будет сложновато, лучше в релизе выпустить сжатый вариант JS кода и не экономить на строчках при разработке.
Один мой знакомый обожает вставлять тернарный оператор вместо if (используя тернарник как lvalue):
myBoolean? execute1(): execute2();
Мне повезло, что он не знает про y === 5 && doSomething()
На мой взгляд if должен быть if'ом. Все вот эти синтаксические хаки имхо хороши только если
1) укорачивают конструкцию и используются обфускаторами
или
2) не ухудшают читаемость кода
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);
это уже жопа, можно сидеть и мысленно парсить строчку, прикидывая что и в какой последовательности выполняется, но зачем, если разбить все на несколько выражений, то возможно получится и менее круто, но намного понятнее для чтения. Но уметь надо, чтобы читать, что написали товарищи не особо заботившиеся о будущем.Приоритеты знать надо безусловно, но в строке с десятком операций скобки все равно лучше расставить, так намного быстрее и читается и понимается позднее, бросил взгляд и все понятно.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Ненормальный Javascript