Home > Software design >  Why doesn't String.replace work with single-quoted strings?
Why doesn't String.replace work with single-quoted strings?

Time:11-23

It works if I hardcode my string when passing it to String.replace(/3):

String.replace("username", "", ".")
=> ".u.s.e.r.n.a.m.e.

But I´d like to run String.replace(/3) on the content that I have in my variable:

 username = 'marcel_huber'
 new_username = String.replace(username, "", ".")
** (FunctionClauseError) no function clause matching in String.replace/4

    The following arguments were given to String.replace/4:

        # 1
        'marcel_huber'

        # 2
        ""

        # 3
        "."

        # 4
        []

    Attempted function clauses (showing 1 out of 1):

        def replace(subject, pattern, replacement, options) when is_binary(subject) and is_binary(replacement) or is_function(replacement, 1) and is_list(options)

    (elixir 1.14.0) lib/string.ex:1521: String.replace/4
    iex:7: (file)

How can I make this work?

CodePudding user response:

See https://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html

username = 'marcel_huber'

Here you are creating a charlist (enclosed in single quotes) but you want to use a string (enclosed in double quotes):

username = "marcel_huber"

Now everything should work.

CodePudding user response:

This is an XY Problem.

You have assumed that the issue is due to using a literal vs. a variable, but the actual issue is completely unrelated: it's whether you use single or double quotes:

Works:

iex(1)> String.replace("double-quotes", "-", " ")
"double quotes"
iex(2)> string = "double-quotes"
"double-quotes"
iex(3)> String.replace(string, "-", " ")
"double quotes"

Doesn't work:

iex(4)> String.replace('single-quotes', "-", " ")
** (FunctionClauseError) no function clause matching in String.replace/4
iex(4)> charlist = 'single-quotes'
[115, 105, 110, 103, 108, 101, 45, 113, 117, 111, 116, 101, 115]
iex(5)> String.replace(charlist, "-", " ")
** (FunctionClauseError) no function clause matching in String.replace/4

The reason is that single-quoted words are not strings, they are charlists: lists of unicode code-points, thus invalid arguments to the functions in the String module.


Note that I have set IEx.configure(inspect: [charlists: :as_lists]) so that the iex(4) line shows us the underlying numbers in the charlist, rather than the single-quoted syntax sugar.

  • Related