April 2032
|
|
|
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
|
4/17/09 05:04 pm
code wtf
Вот такой эпический код сегодня встретился:
assert '(( 1 <= level <= 5))' В комментах желающие могут рассказать, почему это не работает. Завтра расскриню. Да, это написано на bash, но на С будет примерно так же.
4/17/09, 03:15 pm
Предполагаю потому, что:
<= имеет левую ассоциативность, поэтому выражение 1 <= level будет вычислено первым; его результат (1 или 0 / true или false) всегда <= 5.
Это если я навскидку правильно помню последовательность вычислений на C. :-)
4/17/09, 03:20 pm
Это — на bash? А где жэ баксы (перед level)? Не, я вообще не понимаю, что имелось в виду, если это на bash.
Да, на C — очевидно, 1 <= level вернёт true либо false (не важно, что напрямую таких названий в C нет) — сравнивайте это с 5-ю наздоровье.
4/20/09, 10:17 am
у баша есть много всякой доп. функциональности, в частности,
4/20/09, 10:17 am
в частности, оператор (( ))
4/17/09, 03:41 pm
Всегда возвращает единицу. Должно быть assert '((level >= 1 && level <= 5))', если я правильно помню баш.
4/17/09, 04:19 pm
Я так понимаю, 5 будет сравниваться с булевым результатом предыдущего сравнения, а это, вероятно, не совсем то, что хотел сказать программист.
4/17/09, 04:47 pm
Не силен я в bash, но в С сначало бы проверилось одно неравенство и результат его станет операндом второго неравенства. В итоге результат будет не предсказуемым.
4/20/09, 10:18 am
всё верно, только результат будет предсказуем — первое сравнение возвращает 0 или 1, что всегда меньше 5
4/17/09, 05:14 pm
Чё тут думать-то, первое сравнение возвращает bool, а он уже меньше пяти Ж-)
Лучше б на http://lj.rossia.org/users/k001/660024.html отгадку повесил. Я по слайдам, конечно, догадываюсь (dcache - какой-то ядерный кэш содержимого каталогов?), а так тож сначала на иноды подумал.
4/17/09, 05:18 pm
Зависит, конечно, от того как реализован assert, но если он eval'ит строчку, то что 0, что 1 - все меньше 5-ти :)
4/20/09, 10:20 am
а как ассерт реализован — ниже в комментах
4/17/09, 05:20 pm
1<=level принимает значения true или false . Оба они меньше пяти. (false -- это 0, а true обычно 1, хотя я не помню, гарантировано ли, что это именно единица.)
P.S. Это я про C. В bash мне как-то assert не попадался.
4/20/09, 10:21 am
ну да.
самое удивительное — в питоне такая конструкция работает!
4/20/09, 10:33 am
У него это так и задумано было.
4/17/09, 05:26 pm
Поискал в баше среди built-in assert. Не нашел.
4/17/09, 05:33 pm
assert -- самописная функция, она запускает то, что ей передали, и проверяет код возврата, *примерно* так:
assert() { eval "$@" || exit 1 }
4/20/09, 10:33 am
Ага, как я и предполагал.
4/17/09, 07:21 pm
Ясен пень не будет :). <= -- левоассоциативная операция, поэтому условие переписывается так: ((1 <= level) <= 5). Выражение 1 <= level будет равно 0 или 1, в зависимости от значения level, но это, по сути, пофигу, так как и 0 и 1 меньше 5. Поэтому этого ассерта все равно что нет.
Правильно вот так: assert (1 <= level && level <= 5)
4/17/09, 07:38 pm
Эти операции в Баше, вроде, LTR. Тогда (1 <= level) даст либо 0, либо 1, т.е. всегда меньше 5.
4/17/09, 10:21 pm
Ну то есть, assert никогда не ругнется, поскольку и 0 <= 5, и 1 <= 5.
4/18/09, 12:10 am
Почти не знаю bash (и плохо знаю C), но попробую угадать.
Результат вычисления '1 <= level' это 0 либо 1 (в bash нет логического типа). И то, и другое меньше пяти. Тест всегда будет выполняться вне зависимости от значения level.
4/18/09, 02:49 am
Это, наверное, математик или студентег писал :) Мне такое студенты регулярно сдать пытаются.
В C будет либо сравниваться результат сравнения 1 <= level (это 0 или 1) с пятёркой (т.е. (1 <= level) <= 5) и будет получаться единица всегда, либо же, наоборот, будет 1 <= (level <= 5) и будет 0, если level > 5. Мне кажется, что порядок вычисления в данном случае стандартом не оговаривается. Сейчас проверил в gcc, получается всегда единица.
Интересно, что в перле такие выражения не позволяется писать: ошибка возникает.
4/20/09, 10:22 am
всё верно
> Интересно, что в перле такие выражения не позволяется > писать: ошибка возникает.
ещё интересней, что в питоне такие выражения работают так, как задумал программист, который это писал. ну то есть работают!
4/18/09, 04:43 pm
не понимаю bash programming. Есть standard-compliant sh. Есть язык программирования perl, который, при всех своих недостатках, вполне пригоден для написания небольших программ, которые слишком сложны по логике чтобы писать их на sh. А bash - и не то и не то. Он вообще зачем?
2 вопроса: - А что, там можно подставлять перенные без "$"? - А что, там есть оператор "x1 <= x2 <= x3"?
4/20/09, 10:23 am
переменные без $ можно подставлять, например, в let, а ещё в (( ))
4/20/09, 10:23 am
> А что, там есть оператор «x1 <= x2 <= x3»?
нет там такого оператора
4/19/09, 09:11 am
А на питоне без кавычек это валидный код и работать будет как надо. :)
4/19/09, 09:29 pm
(1 <= level) → {0,1} , что всегда меньше 5
|