Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I chain String.replace?

Tags:

elixir

I'm working on a price format function, which takes a float, and represent it properly.

ex. 190.5, should be 190,50

This is what i came up with

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

If i run the following.

format_price(299.0) # -> 299,0 

It looks like it only ran through the first replace. Now if i change this to the following.

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

Then everything seems to work just fine.

format_price(299.0) # -> 299,00 

Why is this?

like image 336
MartinElvar Avatar asked Sep 16 '15 17:09

MartinElvar


People also ask

Can you chain string replace?

String. replace() has two important properties: It returns a new string, so we can chain calls; and it allows us to replace a substring with any matched group in the search pattern.

Can I chain .replace Javascript?

You can use the | character in your regular expression to match the sub-expression on either side of it, and you can chain multiple calls to . replace() .

How do I replace multiple characters in a string?

Use the replace() method to replace multiple characters in a string, e.g. str. replace(/[. _-]/g, ' ') . The first parameter the method takes is a regular expression that can match multiple characters.

How do you replace a substring in Python?

Python String | replace() replace() is an inbuilt function in the Python programming language that returns a copy of the string where all occurrences of a substring are replaced with another substring. Parameters : old – old substring you want to replace. new – new substring which would replace the old substring.


1 Answers

EDIT On the master branch of Elixir, the compiler will warn if a function is piped into without parentheses if there are arguments.


This is an issue of precedence that can be fixed with explicit brackets:

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

Because function calls have a higher precedence than the |> operator your code is the same as:

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

Which if we substitute the last clause:

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

And again:

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

Should explain why you get that result.

like image 129
Gazler Avatar answered Oct 12 '22 16:10

Gazler