Громко конечно сказано - особые случаи. Просто иногда приходиться сталкиваться с определенными конструкциями, в которых можно допустить ошибку.
1 случай. Неоднозначность результата использования составных предикатов в условиях
Для наглядности - пример. Пусть даны первоначальные параметры:
$flag = false;
$n = 1;
А также дано такого рода условие:
if ( $flag && $n++ )
{
// some code
}
Что мы получим на выходе? Вроде бы $n за счет посткрементной формы должен увеличиться на 1, то есть должны получить число - 2, но этого не произойдет, даже если воспользуемся прекрементной формой (++$n).
Так как параметр $flag равен false, то интерпретатор далее условие не просматривает, он "знает", что если один из предикатов установлен в false, то конечный результат логического сравнения также даст false. Помните правило конъюнкции ( логическое умножение ) из булевой алгебры! :) Поэтому далее вычисление не происходит.
Похожая ситуация возникает и в следующем условии:
if ( $flag || $n++ )
{
// some code
}
Если $flag установлен в false, то все хорошо - далее проходит вычисление, но если $flag будет установлен в true, тогда вычисление не произойдет. Снова имеем дело с булевой алгебры - правило дизъюнкции ( логическое сложение ): в данном случае если один из предикатов установлен в true, то независимо от состояния ( true или false ), результатом логического сравнения будет true. В этом причина отсутствия вычисления.
Такого рода проявления вызваны оптимизацией работы интерпретатора с условными выражениями: быстро посмотрел, оценил и принял соответствующее решение. Логично, не так ли?!
Также стоит отметить, что интерпретатор просматривает условия слева направо, то есть если в приведенных примерах предикаты поменять местами, то такие исключения будут устранены.
Для заметки можно также подметить, что такого рода условные проверки встречаются во многих языках и даже в SQL.
2 случай. Неоднозначность результата в циклах
Рассмотрим простой цикл.
for ( $i = 0; $i < 5; $i++ )
{
if ( $i == 3 )
continue;
print( $i.'</br>' );
}
Данный цикл отрабатывая выдает последовательность чисел: 0 1 2 4, 3 из этой последовательности выпадает: на этом шаге условие становится истинным, срабатывает инструкция continue; которая вынуждает цикл перейти к следующей итерации. Ну тут все понятно. Но что будет, если в иструкции continue; мы случайно
не проставим завершающее любое выражение точку с запятой, то есть:
for ( $i = 0; $i < 5; $i++ )
{
if ( $i == 3 )
continue
print( $i.'</br>' );
}
По идее, интерпретатор в этом случае должен выбросить исключение, но что же происходит на самом деле.
Если запустить данный цикл, то на выходе получим следующее: 3. Неожиданно, покрайней мере для меня это было неожиданно. Такой же результат можно получить и в следующем цикле:
for ( $i = 0; $i < 5; $i++ )
{
if ( $i == 3 )
break
print( $i.'</br>' );
}
С чем это может быть связано? Происходят такие чудеса по двум причинам: 1 - у блока условия явно не определена область действия, а инструкции continue и break в свою очередь пытаются отыскать завершающие ; и в это же время на пути
встречается инструкция print( $i.'</br>' ), которая выводит соответствующее число, и далее выражение завершается на искомом завершающем символе. Что в итоге получается? Получается, что интерпретатор расширил область действия
данного условия, поэтому только число 3 и выводится. Таким образом интерпретатор был введен в замешательство, такого не произошло бы, если мы имели дело с компилятором, например в C++.
Как можно избежать таких неоднозначностей? Казалось бы, нужно явно определять области действия, не полагаясь на случай, особенно если дело касается программирования. Например вот так:
for ( $i = 0; $i < 5; $i++ )
{
if ( $i == 3 )
{
continue
}
print( $i.'</br>' );
}
Если же теперь попытаться повторить приведенные выше "чудеса" - ничего не выйдет, интерпретатор укажет вам на наличие
ошибки. Но если внутри этого блока также проставить команду с завершающим ; все снова отработает как ни в чем не бывало. М-да.
Вывод. Рецепт один, что бы исключить такого рода ошибки нужно проявлять внимательность, внимательность и еще раз внимательность. И только так. Всем успехов.
Oracle SQL Developer. ORA-12705: Cannot access NLS data files or invalid environment specified. Resolve
Столкнулся с проблемой подключения Oracle SQL Developer к СУБД Oracle 11g XE. При попытке создать соединение к стандартному для Oracle 11g XE экземпляру БД (SID) - XE получаю ошибку - ORA-12705: Cannot access NLS data files or invalid environment specified. И это не смотря на то, что подключение через SQL Plus проходит успешно. Проверил запись в tnsnames.ora. Вроде все хорошо.
Но все же проблема была найдена. Все дело в локали. Для устранения данной ошибки нужно в настройках SQL Developer - \sqldeveloper\ide\bin\ - в файлик - ide.conf - добавить следующие строчки:
AddVMOption -Duser.region=us
AddVMOption -Duser.language=en
Рестартуйте Ваш SQL Developer, если он был запущен, и вуаля - все готово. Ниже приведен скриншот успешного тест-коннекта. Всем успехов.
Но все же проблема была найдена. Все дело в локали. Для устранения данной ошибки нужно в настройках SQL Developer - \sqldeveloper\ide\bin\ - в файлик - ide.conf - добавить следующие строчки:
AddVMOption -Duser.region=us
AddVMOption -Duser.language=en
Рестартуйте Ваш SQL Developer, если он был запущен, и вуаля - все готово. Ниже приведен скриншот успешного тест-коннекта. Всем успехов.
Subscribe to:
Posts
(
Atom
)