Вот самый простой подход, который я нашел, не прибегая к анонимным функциям и сложному коду.
Ваши методы, которые вы собираетесь цеплять и выходить из, должны иметь особую сущность, которая принимает кортеж {:error, _}
. Предположим, что у вас есть некоторые функции, которые возвращают кортеж {:ok, _}
или {:error, _}
.
# This needs to happen first
def find(username) do
# Some validation logic here
{:ok, account}
end
# This needs to happen second
def validate(account, params) do
# Some database logic here
{:ok, children}
end
# This happens last
def upsert(account, params) do
# Some account logic here
{:ok, account}
end
На данный момент ни одна из ваших функций не связана друг с другом. Если вы правильно отделили всю свою логику, вы можете добавить арность к каждой из этих функций, чтобы распространять ошибки, вызывая стек вызовов, если что-то пошло не так.
def find(piped, username) do
case piped do
{:error, _} -> piped
_ -> find(username)
end
end
# repeat for your other two functions
Теперь все ваши функции будут правильно размножать свои ошибки в стек вызовов, и вы можете трубы их в вызывающей, не беспокоясь о том или нет, они передают недопустимое состояние к следующему способу.
put "/" do
result = find(username)
|> validate(conn.params)
|> upsert(conn.params)
case result do
{:error, message} -> send_resp(conn, 400, message)
{:ok, _} -> send_resp(conn, 200, "")
end
end
В то время как вы можете в конечном итоге создает некоторый дополнительный код для каждой из функций, это очень легко читать, и вы можете трубы через большинство из них взаимозаменяемы, как вы бы с анонимной функции решения. К сожалению, вы не сможете передавать данные через них из канала без каких-либо изменений в работе ваших функций. Только мои два цента. Удачи.
Ack. Я должен был сначала прочитать ваш ответ @sasajuric. Я просто в основном сказал то же самое, что вы делали не совсем так красноречиво. Я оставлю свой ответ, хотя это немного лишнее, потому что дискуссия по железнодорожному программированию интересна. Приятно видеть, что я размышляю так же, как кто-то такой же умный, как ты. :) –
@OnorioCatenacci Ссылки в вашем ответе полезны и добавляют большую ценность. Кроме того, ваш код менее волшебный, поэтому он объясняет это проще. Так что это определенно добавляет ценность для этой дискуссии :-) – sasajuric