Хотя ответ @fhdhsni совершенно верен, я бы добавил некоторые уточнения.
Точный эквивалент Kernel#send
из ruby в эликсире невозможно, потому что Kernel#send
позволяет вызывать private методы на получателе. В elixir частные функции никогда не существуют в скомпилированном коде.
Если вы имели в виду Kernel#public_send
, это может быть достигнуто с помощью Kernel.apply/3
, как упоминалось @fhdhsni. Единственное исправление состоит в том, что таблица атомов не является сборщиком мусора, и, безусловно, нужно вызвать действительно существующую функцию , это следует сделать с помощью String.to_existing_atom/1
.
apply(
String,
String.to_existing_atom("u#{:pcase}"),
["uppercase"]
)
Кроме того, можно использовать макросы на этапе компиляции для генерации соответствующих предложений, когда список вызываемых функций предсказуем (в противном случае код уже пахнет).
defmodule Helper do
Enum.each(~w|upcase|a, fn fname ->
def unquote(fname)(param),
do: String.unquote(fname)(param)
# or
# defdelegate unquote(fname)(param), to: String
end)
end
Helper.upcase("uppercase")
#⇒ "UPPERCASE"