Подтвердить что ты не робот

Почему я не могу связать String.replace?

Я работаю над функцией формата цены, которая берет float и представляет ее правильно.

ех. 190,5, должно быть 190,50

Вот что я придумал

  def format_price(price) do
    price
    |> to_string
    |> String.replace ".", ","
    |> String.replace ~r/,(\d)$/, ",\\1 0"
    |> String.replace " ", ""
  end

Если я запустил следующее.

format_price(299.0)
# -> 299,0

Похоже, он пробежал только первую замену. Теперь, если я изменю это на следующее.

  def format_price(price) do
    formatted = price
    |> to_string
    |> String.replace ".", ","

    formatted = formatted
    |> String.replace ~r/,(\d)$/, ",\\1 0"

    formatted = formatted
    |> String.replace " ", ""
  end

Тогда все работает нормально.

format_price(299.0)
# -> 299,00

Почему это?

4b9b3361

Ответ 1

EDIT На главной ветке Elixir компилятор будет предупреждать, если функция передана без круглых скобок, если есть аргументы.


Это проблема приоритета, которая может быть зафиксирована с явными скобками:

price
|> to_string
|> String.replace(".", ",")
|> String.replace(~r/,(\d)$/, ",\\1 0")
|> String.replace(" ", "")

Поскольку вызовы функций имеют более высокий приоритет, чем оператор |>, ваш код будет таким же, как:

price
|> to_string
|> String.replace(".",
  ("," |> String.replace ~r/,(\d)$/,
    (",\\1 0" |> String.replace " ", "")))

Что, если мы заменим последнее предложение:

price
|> to_string
|> String.replace(".",
  ("," |> String.replace ~r/,(\d)$/, ".\\10"))

И снова:

price
|> to_string
|> String.replace(".", ",")

Должен объяснить, почему вы получили этот результат.