Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Мини-тест ("опечатка" + стилистика кода + "известный механизм" языка) (https://javascript.ru/forum/misc/7041-mini-test-opechatka-stilistika-koda-izvestnyjj-mekhanizm-yazyka.html)

Dmitry A. Soshnikov 12.01.2010 13:58

Мини-тест ("опечатка" + стилистика кода + "известный механизм" языка)
 
Опять небольшой тест на знание (механизмов) языка. Понравился пример из одной темы в news-группе.

Допустим, есть такая проверка (пример абстрактный):

if (!x)
{
  x = 1;
}


Какого типа ошибка будет при следующей опечатке в ключевом слове?

iff (!x)
{
  x = 1;
}


Важно ответить самому без запуска кода, проверок; пояснить, почему именно так.

B@rmaley.e><e 12.01.2010 14:04

Переменная iff не инициализованна. А происходит так, потому что iff (/*smthng*/) трактуется JS'ом как вызов ф-ии.

/* Все честно: сначала написал, потом проверил. */

Dmitry A. Soshnikov 12.01.2010 14:16

B@rmaley.e><e, угу, спасибо. Ответ ясен, подождём ещё.

Также, интересуют причины (приведённое Вами - это следствие) и методика недопущения ошибок подобного рода.

Kolyaj 12.01.2010 14:46

Цитата:

Сообщение от Dmitry A. Soshnikov
интересуют причины

Грамматика :)

Цитата:

Сообщение от Dmitry A. Soshnikov
методика недопущения ошибок подобного рода

Смотреть, что пишешь.

Dmitry A. Soshnikov 12.01.2010 15:03

Kolyaj, угу, спасибо, ещё подождём. Ответы пока неполные.

Цитата:

Сообщение от Kolyaj
Смотреть, что пишешь.

Возможно ли получить подобную ошибку и "смотря, что пишешь"? Возможно ли избежать подобную ошибку, "не смотря, что пишешь"?

P.S.: всем: пишите, не стесняйтесь. Не бойтесь ошибиться в предположениях, так можно наиболее точно понять, что и почему происходит.

x-yuri 12.01.2010 15:26

Цитата:

Сообщение от Dmitry A. Soshnikov
методика недопущения ошибок подобного рода

пользоваться редактором с подсветкой синтаксиса :)

Kolyaj 12.01.2010 15:40

Цитата:

Сообщение от Dmitry A. Soshnikov
Ответы пока неполные.

Можно, конечо, развернуть тут десяток правил грамматики. Этого ждешь? :)

Цитата:

Сообщение от Dmitry A. Soshnikov
Возможно ли получить подобную ошибку и "смотря, что пишешь"? Возможно ли избежать подобную ошибку, "не смотря, что пишешь"?

Какие-то странные у тебя вопросы сегодня.

Dmitry A. Soshnikov 12.01.2010 15:46

Цитата:

Сообщение от Kolyaj
Можно, конечо, развернуть тут десяток правил грамматики. Этого ждешь?

Не-а, не этого ;) Хотя, правило там одно.

Цитата:

Сообщение от Kolyaj
Какие-то странные у тебя вопросы сегодня.

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

Dmitry A. Soshnikov 12.01.2010 15:48

Цитата:

Сообщение от x-yuri
пользоваться редактором с подсветкой синтаксиса

Да, однозначно поможет :)

Можно ли недопустить ошибку подобного плана без редактора с подстветкой?

Будет ли вообще ошибка? Если да, при каких условиях?

subzey 12.01.2010 15:55

iff (!x) /* заканчивается \r\n — запускаем функцию iff — ошибка, если такой нет */
{ /* начинаем объявление объекта */
  x = 1; /* ошибка синтаксиса, что-то типа «недопустимое имя свойства»? */
}

Как-то так?

Dmitry A. Soshnikov 12.01.2010 15:59

Цитата:

Сообщение от subzey
iff (!x) /* заканчивается \r\n — запускаем функцию iff — ошибка, если такой нет */

Верно. Механизм автоматической вставки точки с запятой завершит эту инструкцию.

Это самый главный момент - это именно RuntimeError, не ParseError (SyntaxError). Соответственно, если ещё и функция iff существует, то в этом месте ошибки вообще не будет (а вот такие ошибки уже являются ошибками логики программы - программа полностью рабочая и нерабочая одновременно).

Причина и следствие ясны.

Возможно ли как-то избавиться от RuntimeError (именно это я имел в виду, когда спрашивал про избавление от подобного типа ошибки), но не допустить ошибки в логике программы? Т.е. можно, конечно, объявить функцию iff, и RuntimeError-a не будет, но это ещё больше усугубит дело, т.к. ошибка не будет отловлена.

Цитата:

Сообщение от subzey
{ /* начинаем объявление объекта */ x = 1; /* ошибка синтаксиса, что-то типа «недопустимое имя свойства»? */ }

Угу, спасибо, возможно. Ещё подождём.

PeaceCoder 12.01.2010 23:30

Цитата:

Сообщение от subzey
{ /* начинаем объявление объекта */ x = 1; /* ошибка синтаксиса, что-то типа «недопустимое имя свойства»? */ }

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

Dmitry A. Soshnikov 12.01.2010 23:45

Цитата:

Сообщение от PeaceCoder
это уже parseErrorr и программа не запустится

Не обязательно ;) Я не сказал, что будет ошибка с фигурными скобками, я сказал "возможно", чтобы другие могли ответить.

Меня как раз интересует, можно ли сделать так, чтобы был SyntaxError на стадии парсинга? Чтобы мы отловили ошибку с iff ещё до запуска и не допустили случая логической ошибки, если будет существовать функция iff.

В сущности, все подсказки были даны в заголовке темы (две из них уже разобраны).

PeaceCoder 12.01.2010 23:49

ну остается только механизм. это обьявление функции при которой ключевое слово funcion отсутсвует.

Dmitry A. Soshnikov 13.01.2010 00:27

Цитата:

Сообщение от PeaceCoder
ну остается только механизм.

Нет, "механизм" из подсказок, уже задействовали - это механизм автоматической вставки точки с запятой.

Также, задействовали "опечатку".

Осталась "стилистика кода". Отмечу, что я обычно использую стилистику не ту, что была приведена в примере, хотя в текущем проекте у нас принята именно стилистика из примера.

Gvozd 13.01.2010 01:35

пока пришла в голову только использовать обязательно конечный else, таким образом вызывая именно ошибку парсинга
непонятно что делать с другими стандартными структырами типа циклов do,do-while, и условий switch-case(фигню сморозил.они дадут syntax error на первом case)

B~Vladi 13.01.2010 01:36

Если не будет точки с запятой внутри фигурных скобок - ошибки не будет:-? (будет, невнимательность:))

Цитата:

Сообщение от Dmitry A. Soshnikov
Меня как раз интересует, можно ли сделать так, чтобы был SyntaxError на стадии парсинга? Чтобы мы отловили ошибку с iff ещё до запуска

Писать нужно как принято и не будет никаких двойственных ситуаций (я про перенос скобки).
iff (!x) {
  x = 1;
}

Gvozd 13.01.2010 02:01

Цитата:

Сообщение от B~Vladi
Писать нужно как принято и не будет никаких двойственных ситуаций (я про перенос скобки).

видимо это и есть то к чему нас подводил Дмитрий
хотя не факт
ибо, такой подход все еще не решает проблему do-while
x=false;
doq=123;
i=0;
doq {
alert(i);//в опере данный код показывает один alert, после чего процессор начинает показывать 100% нагруженность, без каких-либо изменений на странице скрипта
//мозилла показывает ошибку missing ; before statement "doq {\n"
i++;
if(i==3)
  x = true;
}while(!x);
alert('end');

B~Vladi 13.01.2010 08:54

Цитата:

Сообщение от Gvozd
//в опере данный код показывает один alert, после чего процессор начинает показывать 100% нагруженность, без каких-либо изменений на странице скрипта //мозилла показывает ошибку missing ; before statement "doq {\n"

Видимо, опера добавляет ";" после doq (может, потому что находит значение doq?), т.к. если самому это вставить в мозилле - эффект будет тот же как и в опере. Непонятно только почему выскакивает алерт - открывающая скобка никого не смущает?! Получается, что можно указывать любые выражения в имени свойства?:-?

Gvozd 13.01.2010 10:10

Цитата:

Сообщение от B~Vladi
любые выражения в имени свойства?

вы забываете что фигурные скобочки используются не только для объектов, но и для блочности кода
то есть в зависимости от контекста, фигурные скобочки будут использоваться так или иначе
<script type="text/javascript">
var qwe={alert(1)};//missing : after property id, ибо объект
</script>
<script type="text/javascript">
{alert(1)};//выведет alert, ибо это блок кода
</script>

Цитата:

Сообщение от Gvozd
ибо, такой подход все еще не решает проблему do-while

Цитата:

Сообщение от Gvozd
//в опере данный код показывает один alert

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

B~Vladi 13.01.2010 10:19

Dmitry A. Soshnikov, ну ты мозг, конечно...
Цитата:

Сообщение от Dmitry A. Soshnikov
В сущности, все подсказки были даны в заголовке темы (две из них уже разобраны).

Это звучит как "подсказка про подсказки" :)
Цитата:

Сообщение от Dmitry A. Soshnikov
Отмечу, что я обычно использую стилистику не ту, что была приведена в примере, хотя в текущем проекте у нас принята именно стилистика из примера.

Если моя версия окажется верной, будешь выступать за смену стилистики в вашем проекте (внутри вашей компании)? В любом случае займу твою позицию касаемо стилистики.

B~Vladi 13.01.2010 10:21

Цитата:

Сообщение от Gvozd
{alert(1)};//выведет alert, ибо это блок кода

О! Теперь всё ясно:)

Dmitry A. Soshnikov 13.01.2010 12:57

Цитата:

Сообщение от B~Vladi
Писать нужно как принято и не будет никаких двойственных ситуаций (я про перенос скобки).

iff (!x) {
  x = 1;
}

Верно. Всё разобрали ;)

Только насчёт "как принято" тут утверждать категорично нельзя, поскольку официального style-guide (который я бы хотел видеть даже от ECMA, либо от B.Eich-a) - нет. Более-менее "полуофициальным" можно считать style-guide от Mozilla - https://developer.mozilla.org/en/JavaScript_style_guide (поскольку создатель JS хоть как-то связан с Mozilla, а именно - работает там ;)); данная стилистика похожа на стиль Java.

К примеру у Python-a заведён специальный документ на эту тему, на официальном сайте.

По поводу приоритетов, я уже писал: http://javascript.ru/forum/offtopic/...html#post33740

(1) - локальный в компании, (2) - официальный технологии, (3) - локальная привычка. В идеале, (1) должно быть === (2). В профессиональном коде на международном уровне, (3) вообще не должно рассматриваться.

Цитата:

Сообщение от Gvozd
видимо это и есть то к чему нас подводил Дмитрий
хотя не факт

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

Цитата:

Сообщение от Gvozd
ибо, такой подход все еще не решает проблему do-while

Да, Опера, почему-то, ставит автоматом точку с запятой после dof со скобкой в той же строке.

var dof = 10;
dof 
{
} while(false);


Вот этот код должен завершится так:

var dof = 10;
dof; // разрешение идентификатора
{ // пустой блок
}; while(false); // пустой while


Но не этот:

var dof = 10;
dof {
} while(false);


Так что, Опера, не права, получается.

Цитата:

Сообщение от B~Vladi
Если моя версия окажется верной, будешь выступать за смену стилистики в вашем проекте (внутри вашей компании)? В любом случае займу твою позицию касаемо стилистики.

В текущий проект я уже пришёл, когда он активно разрабатывался, и там уже была устоявшаяся стилистика.

Вообще, существенным является именно наличие определённой единой стилистики кода в команде - это на данный момент имеется.

Впрочем, если бы речь шла о выборе стилистики в самом начале проекта, я бы отдал предпочтение стилистике Mozilla. Хотя, стилистика текущего проекта также хорошо структурирована и оформлена (для меня вопрос "Где ставить скобку - в той же строке или с новой?" - давно уже перешёл в разряд несущественных, я могу подстраиваться под стилистику, главное, чтобы она была единой, логически структурированной и обоснованной).

Хотя, если "завтра" B.Eich или ECMA выпустят официальный style guide, в этом вопросе будет поставлена окончательная точка - и тогда да, возможно предложить смену стилистики, поскольку код на международном уровне должен быть оформлен по официальному стилю технологии (хотя, локальная стилистика компании всё ещё будет иметь приоритет выше; в своих локальных проектах - должна быть только официальная стилистика, не касаемо каких-то своих локальных привычек).

Kolyaj, возвращаясь по твоим вопросам (ответам),

Цитата:

Сообщение от Kolyaj
Можно, конечо, развернуть тут десяток правил грамматики. Этого ждешь?

Естественно не этого (это было бы занудно и скучно, даже для меня ;)). Правило там одно:

CallExpression :
    MemberExpression Arguments

Arguments:
    ( )
    ( ArgumentList )


Т.е. MemberExpression со скобками вызова - это выражение вызова (функции). А MemberExpression, в частности, распадается на Idenfier. Т.е. с ключевым словом бы это прокатило, а вот с идентификатором - уже нет, это по-любому трактуется, как вызов функции.

Ну и, плюс, механизм автоматической вставки точки с запятой делает своё дело.

Цитата:

Сообщение от Kolyaj
Какие-то странные у тебя вопросы сегодня.

Цитата:

Сообщение от Dmitry A. Soshnikov
Возможно ли получить подобную ошибку и "смотря, что пишешь"?

Имелось в виду, что не будет опечатки (т.е. тот, кто пишет, "смотрит, что он пишет"), но будет та же ошибка. Самый простой пример - возврат объекта через инициализатор:

return // undefined
{
  x: 10
};

return {
  x: 10
}; // object


Цитата:

Сообщение от Dmitry A. Soshnikov
Возможно ли избежать подобную ошибку, "не смотря, что пишешь"?

Имелось в виду, избежать RuntimeError, но всё же сделать опечатку (т.е. "не смотреть, что пишешь"), и получить SyntaxError:

iff (!x) { // SyntaxError
  x = 1;
}


subzey,

Цитата:

Сообщение от subzey
{ /* начинаем объявление объекта */ x = 1; /* ошибка синтаксиса, что-то типа «недопустимое имя свойства»? */ }

Уже отмечали (Gvozd) - синтаксической ошибки не будет, так как это блок кода, а не инициализатор объекта.

Ниже - синтаксически правильная ECMAScript-программа, состоящая из блока и пустой инструкции:

{
  ;
}


P.S.: ещё (классические) примеры:

a = b + c
({x: 10}).x


Здесь наоборот, точка с запятой не будет поставлена в конце первой строки, поскольку "c(... )" - это вызов функции с аргументом "{x: 10}".

Или:

var foo = function () {
  alert(arguments[0]);
}

(function () {return 'x';}())


Так же, точка с запятой не ставится; это вызов первой анонимной функции, в которую параметром передаётся результат вызова второй анонимной функции.

var foo = function () {
  alert(arguments[0]);
};

(function () {return 'x';})();


А так - верно: описание первой анонимной функции (которая сохраняется в foo); далее описание и вызов второй анонимной функции.

B~Vladi 13.01.2010 14:34

Вобщем, у меня вывод такой:
выбирать стиль кодирования (для себя, команды, стандарта) необходимо в первую очередь исходя из:
Цитата:

Сообщение от Dmitry A. Soshnikov
чтобы она была единой, логически структурированной и обоснованной

, а уж потом из личных предпочтений.
Это поможет избежать ошибок в логике программы и понимания кода другими людьми. Как показывает предыдущий пост, таких ситуаций может быть немало.
Цитата:

Сообщение от Dmitry A. Soshnikov
Только насчёт "как принято" тут утверждать категорично нельзя, поскольку официального style-guide (который я бы хотел видеть даже от ECMA, либо от B.Eich-a) - нет.

Да, я знаю. Для меня это само собой - стандартные настройки основных IDE форматируют именно так, да и не видел я людей, чтобы так писали...
PS: спасибо за примеры, отличный мануал;)


Часовой пояс GMT +3, время: 16:58.