fenom/docs/ru/operators.md
bzick bc73e5b733 Merge branch 'master' into develop
Conflicts:
	docs/ru/syntax.md
	sandbox/fenom.php
2015-01-02 22:48:56 +03:00

17 KiB
Raw Blame History

Операторы

Арифметические операторы

Все же помнят арифметику?

  • -$a - отрицание знака, смена знака $a.
  • $a + $b - сложение, сумма $a и $b.
  • $a - $b - вычитание, разность $a и $b.
  • $a * $b - умножение, произведение $a и $b.
  • $a / $b - деление, частное от деления $a на $b.
  • $a % $b - деление по модулю, целочисленный остаток от деления $a на $b.
{$a + $b * $c/$d - $e*5 + 1e3}

Логические операторы

  • $a || $b - логичесое ИЛИ, TRUE если или $a, или $b TRUE.
  • $a && $b - лигическое И, TRUE если и $a, и $b TRUE.
  • !$a - отрицание, TRUE если $a не TRUE.
  • $a or $b - логическое ИЛИ, TRUE если или $a, или $b TRUE.
  • $a and $b - логическое И, TRUE если и $a, и $b TRUE.
  • $a xor $b - исключающее или, TRUE если $a, или $b TRUE, но не оба.
{if $b && $c} ... {/if}

Смысл двух разных вариантов для операторов and и or в том, что они работают с различными приоритетами.

Операторы сравнения

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

  • $a < $b - меньше, TRUE если $a строго меньше $b.
  • $a > $b - больше, TRUE если $a строго больше $b.
  • $a <= $b - меньше или равно, TRUE если $a меньше или равно $b.
  • $a >= $b - больше или равно, TRUE если $a больше или равно $b.
  • $a == $b - равно, TRUE если $a равно $b после преобразования типов.
  • $a === $b - тождественно равно, TRUE если $a равно $b и имеет тот же тип.
  • $a !== $b - тождественно не равно, TRUE если $a не равно $b или они разных типов.
  • $a != $b - не равно, TRUE если $a не равно $b после преобразования типов.
  • $a <> $b - не равно, TRUE если $a не равно $b после преобразования типов.
{if $b >= 5} ... {/if}

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

{if 0 == "a"} {* 0 == 0 -> true *} {/if}
{if "1" == "01"} {* 1 == 1 -> true *} {/if}
{if "10" == "1e1"} {* 10 == 10 -> true *} {/if}
{if 100 == "1e2"} {* 100 == 100 -> true *} {/if}

Преобразование типов не происходит при использовании === или !== так как в этом случае кроме самих значений сравниваются еще и типы.

Таблица сравнения различных типов:

Тип операнда 1 Тип операнда 2 Результат
null или строка строка NULL преобразуется в "", числовое или лексическое сравнение
булев или null что угодно Преобразуется в bool, FALSE < TRUE
объект объект Встроенные классы могут определять свои собственные правила сравнения, объекты разных классов не сравниваются, объекты одного класса - сравниваются свойства тем же способом, что и в массивах
строка или число строка или число Строки переводятся в числа, обычная математика
массив массив Массивы с меньшим числом элементов считаются меньше, если ключ из первого операнда не найден во втором операнде - массивы не могут сравниваться, иначе идет сравнение соответствующих значений
объект что угодно object всегда больше
массим что угодно array всегда больше

Побитовые операторы

Побитовые операторы позволяют считывать и устанавливать конкретные биты целых чисел.

  • $a | $b - битовое ИЛИ, устанавливаются те биты, которые установлены в $a или в $b.
  • $a & $b - битовое И, устанавливаются только те биты, которые установлены и в $a, и в $b.
  • $a ^ $b - битовое исключающее ИЛИ, устанавливаются только те биты, которые установлены либо только в $a, либо только в $b, но не в обоих одновременно.
  • ~$a - битовое отрицание, устанавливаются те биты, которые не установлены в $a, и наоборот.
  • $a << $b - битовый сдвиг влево, все биты переменной $a сдвигаются на $b позиций влево (каждая позиция подразумевает "умножение на 2")
  • $a >> $b - битовый сдвиг вправо, все биты переменной $a сдвигаются на $b позиций вправо (каждая позиция подразумевает "деление на 2")
{if $a & 1} {var $b = 4 | $flags} {/if}

Оператор присваивания

Базовый оператор присваивания обозначается как =. На первый взгляд может показаться, что это оператор "равно". На самом деле это не так. В действительности, оператор присваивания означает, что левый операнд получает значение правого выражения, (т.е. устанавливается значением).

В дополнение к базовому оператору присваивания имеются "комбинированные операторы" для всех бинарных арифметических операций и строковых операций, которые позволяют использовать некоторое значение в выражении, а затем установить его как результат данного выражения. То есть выражение $a = $a + 2 может быть записано как $a += 2.

  • $a = $b - присвоение
  • $a += $b - присвоение с добалением.
  • $a -= $b - присвоение с вычитанием.
  • $a *= $b - присвоение с умножением.
  • $a /= $b - присвоение с делением.
  • $a %= $b - присвоение с делением по модулю.
  • $a &= $b - присвоение с битовыйм И.
  • $a |= $b - присвоение с битовыйм ИЛИ.
  • $a ^= $b - присвоение с битовыйм исключением ИЛИ
  • $a <<= $b - присвоение с битовым сдвигом влево.
  • $a >>= $b - присвоение с битовым сдвигом врпаво.
{var $b |= $flags}

Операторы инкремента и декремента

Fenom поддерживает префиксные и постфиксные операторы инкремента и декремента в стиле PHP или C.

Замечание: Операторы инкремента/декремента не влияют на булевы значения. Декремент NULL также не даст никакого эффекта, однако инкремент даст значение 1.

  • ++$a - префиксный инкремент, увеличивает $a на единицу, затем возвращает значение $a.
  • $a++ - постфиксный инкремент, возвращает значение $a, затем увеличивает $a на единицу.
  • --$a - префиксный декремент, уменьшает $a на единицу, затем возвращает значение $a.
  • $a-- - постфиксный декремент, возвращает значение $a, затем уменьшает $a на единицу.

Строковые операторы

Оператор объединения ~ возвращает строку, представляющую собой соединение левого и правого аргумента.

  • $a ~ $b - возвращает результат объединения сток $a и $b
  • $a ~~ $b - возвращает результат объединения сток $a и $b через пробел
  • $a ~= $b - присвоение с объединением

Тернарные операторы

Еще одним условным оператором являются тернарные операторы ?: и !:. Выражения (expr1) ? (expr2) : (expr3) и (expr1) ! (expr2) : (expr3) интерпретируется как expr2, если expr1 имеет значение TRUE, или как expr3 если expr1 имеет значение FALSE.

Тернарый оператор ?: проверяет условие expr1 на не "пустое" значение, то есть expr1 при конвертирование в булевое значение должен вернуть TRUE. Следующие значения воспринимаются как пустые:

  • "" (пустая строка)
  • 0 (целое число)
  • 0.0 (дробное число)
  • "0" (строка)
  • NULL
  • FALSE
  • array() (пустой массив)
  • переменная не объявлена
  • элемента массива не существует
  • свойство объекта не существует
{$request.action ? $request.action : 'default'}

Пример выше стоит интерпретировать так: если $request.action не пустое то вернуть $request.action иначе вернуть default. Приведенный пример можно записать в упрощенном формате:

{$request.action ?: 'default'}

Тернарый оператор ?: проверяет условие expr1 на существование и относится больше к работе с переменными, то есть переменная в выражении expr1 должна существовать даже если она "пустая", но не NULL. Данный оператор не имеет значения если expr1 функция или метод, так как в этом случае всегда будет TRUE.

{$request.action ! $request.action : 'default'}

Пример выше стоит интерпретировать так: если переменна я $request существует, является массивом и существует ключ $request.action то вернуть $request.action иначе вернуть default. Приведенный пример можно записать в упрощенном формате:

{$request.action !: 'default'}

Как видно, оператор :? более расширенный чем :! и включает в себя функциональность оператора !:.

Для упрощения понимания можно подвести итог:

  • $a ? $b : $c - вернет $b если $a не пустое, иначе вернет $c.
  • $a ! $b : $c - вернет $b если $a существует, иначе вернет $c.
  • $a ?: $c - вернет $a если $a не пустое, иначе вернет $b.
  • $a !: $c - вернет $a если $a существует, иначе вернет $b.
{var $a = true}
{$a ? 5 : 10} {* вернет 5 *}
{var $a = false}
{$a ? 5 : 10} {* вернет 10 *}

Операторы проверки

Оператор проверки это упрощенный тернарный оператор от которого осталась только часть проверки без возвращаемых вариантов. Суть операторов — быстро произвести проверку на не пустое значение и существование пременной.

  • $a? - вернет TRUE если $a не пустое
  • $a! - вернет TRUE если $a существует
{if $a?} {* вместо {if !empty($a)} *}
{if $a!} {* вместо {if isset($a)} *}

Оператор тестирования

Оператор is производит тесты над переменными или выражением. Левый операнд считается тестируемым, а правый операнд — название теста:

{* проверка переменной на не четность *}

{$a is odd}

Результат тестирования может быть инвертирован с помощью is not оператора:

{* проверяем переменную что ее значение не является числом *}

{$a is not integer}

Список допустимых тестов:

  • $a is integer - тестирует перменную на тип. Тестом может быть
    • int, integer — целое число
    • bool, boolean — булево значение
    • float, double, decimal - дробное число
    • array — массив
    • object — объект
    • scalar — скалярное значение (не массив и не объект)
    • string — строка
    • callback, callable — функция
    • number, numeric — число, в общем понимании
  • $a is iterable - тестирует переменную на возможность итеративного обхода (для foreach).
  • $a is template - переменная $a содержит название существующего шаблона.
  • $a is empty - переменная пустая.
  • $a is set - переменная существует.
  • $a is even - переменная $a имеет четное значение.
  • $a is odd - переменная $a имеет не четное значение.
  • $a is MyClass или $a is \MyClass - переменная $a является сущностью класса MyClass
  • $a is $b - $a тождественна $b

Оператор присутствия

Оператор in проверяет присутствие скалярного значения слева в массиве или строке справа. Результат тестирования может быть инвертирован с помощью not ni оператора.

  • $a in list $b - значение $a содержится в массиве значений $b
  • $a in keys $b - массив $b имеет ключ $a
  • $a in string $b - значение $a содержится в $b как подстрока.
  • $a in $b - значение $a содержится в $b, где $b может быть строкой, обычным или ассоциативным массивом. Этот вариант долгий так как требуется проверить типы переменной $b. Однако если вместо $b явно задан массив или строка то оператор сам адаптируется для быстрого поиска.
{'df' in 'abcdefg'}
{5 in [1, 5, 25, 125]}
{99 in keys [1, 5, 25, 99 => 125]}