Почему операторы буфера необходимы в запросах Ecto?
В Elixir оператор булавки используется для предотвращения перепроверки переменных. Однако в отношении запроса Ecto, такого как
from u in User, where: u.username == ^username
авторы состояния программирования Phoenix (в главе 7), что
Помните, что оператор ^ (называемый оператором вывода) означает, что мы хотим сохранить ^ имя пользователя.
Но это звучит не так, потому что, по-видимому, сравнение в запросе не должно вызывать перезаписи переменных.
Ошибочны ли авторы книги (которые соавтор Хосе Валим)? Является ли оператор булавки в Ecto запрашивает просто конструкцию Ecto DSL вместо обычного оператора вывода Elixir? Или запрос действительно получит возможность перестроить username
после расширения макросов?
Ответы
Ответ 1
Ecto-запросы полагаются на макросы, чтобы обеспечить мощный DSL, который мы используем. Это означает, что все, что приходит после from
, не является "обычным" кодом Elixir, а DSL, которое в конечном итоге преобразуется в SQL-запрос. Таким образом, каретка не является оператором буксировки как таковой, и не имеет никакого отношения к сопоставлению с образцом (хотя, очевидно, его все еще можно назвать оператором булавки, потому что люди всегда забывают слова, такие как каретка, амперсанд и звездочка). Это просто удобный оператор, который авторы Ecto предпочитают быть "оператором интерполяции". Без него username
из вашего примера будет взято буквально и вставлено непосредственно в сгенерированный SQL (хотя Ecto достаточно умен, чтобы видеть, что это не то, что вы хотите, чтобы оно проливало ошибку).
Отличный вопрос BTW, вдохновил меня больше узнать о макросах (новичок в FP здесь).
Ответ 2
Согласно Документация по Ecto, оператор pin в ecto используется для интерполяции запросов:
Внешние значения и выражения Эликсира могут быть введены в запрос выражение с ^
def with_minimum(age, height_ft) do
from u in "users",
where: u.age > ^age and u.height > ^(height_ft * 3.28),
select: u.name
end
Попытка пропустить штырь даст вам ошибку, поскольку Ecto не может найти функцию базы данных или выражение запроса с именем age
:
(Ecto.Query.CompileError) переменная age
не является допустимым запросом выражение. Переменные должны быть явно интерполированы в запросах с ^
Ответ 3
Оператор булавки ^ должен использоваться, если вы хотите сопоставить шаблон с существующим значением переменной, а не переупорядочивать переменную:
Дополнительная информация: http://elixir-lang.org/getting-started/pattern-matching.html
Внешние значения и выражения Elixir могут быть введены в выражение запроса с помощью:
дальше: https://hexdocs.pm/ecto/Ecto.Query.html