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

«Сначала смотри, потом думай, а потом тестируй. Но всегда смотрите сначала. В противном случае вы увидите только то, что ожидали».

- Дуглас Адамс

Пример приоритета Ruby

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

10 + 20 * 10 = 300

Это вызвано тем фактом, что когда мы прибавляем 10 к 20, мы получаем 30, а затем умножаем это на 10, чтобы получить 300. Когда вы просите Ruby выполнить те же вычисления, вы получаете совсем другой результат:

irb(main):003:0> 10 + 20 * 10
=> 210

Это связано с приоритетом оператора. В Ruby есть набор правил, указывающих, как оценивать операторы в выражении. Ясно, что Ruby дает оператору умножения (*) приоритет над оператором сложения (+).

Преобладающий приоритет

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

(10 + 20) * 10
=> 300

Фрагмент выражения, заключенный в круглые скобки в предыдущем примере, вычисляется до умножения с более высоким приоритетом. Подобно тому, как скобки всегда оцениваются первыми при выполнении математических операций вручную.

Таблица приоритетов

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

Операторы со значением «Да» в столбце «Метод» — это методы, которые можно переопределить.

Порядок оценки

Возможно, вы где-то слышали или читали, что приоритет определяет порядок, в котором вычисляются выражения. Однако процесс оценки сложнее, чем просто решить, что будет оцениваться в первую очередь. На самом деле приоритет — это только часть истории Ruby; другие части - это вычисление слева направо, вычисление справа налево, короткое замыкание и троичные выражения. Каждый из них уникальным образом изменяет порядок операций. Обсуждение точных различий выходит за рамки этой статьи, но я призываю вас поэкспериментировать с ними и убедиться в этом самим.

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

Заключение

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