Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why variables setted inside Enum.each is not saved?

Tags:

enums

elixir

I'm trying to set a value to a variable inside a function in Enum.each, but at the end of loop, variable is empty and I don't know exactly why this behaviour.

Code:

base = "master"
candidates = ["stream", "pigeons", "maters"]

return = []
Enum.each(candidates, fn candidate ->
    cond do
        String.length(base) == String.length(candidate) ->
            return = return ++ [candidate]
        true ->
            true
    end
end)
IO.inspect return

At this example, return is expected to be ["stream", "maters"], but instead, it is only an empty list: []

My question is why this happens.

like image 913
Alexandre S Hostert Avatar asked Mar 12 '23 07:03

Alexandre S Hostert


2 Answers

When dealing with languages like Elixir, it is better to think in terms of "values" and "names" instead of "variables".

The reason you cannot do what you want is that Elixir has "lexical scoping". When you assign to a "variable", you create a new value in the inner scope. You never change the "value" of a "name" defined in the outer scope.

(you probably can get what you want with Enum.filter/2, but I'm guessing this is just an illustrative example)

EDIT:

As of today, Elixir will allow you to write something like this:

if condition_that_evals_to_false do
  x = 1
else
  x = 2
end

IO.inspect x # => 2

```

But this will be deprecated in Elixir 1.3

like image 167
Renan Ranelli Avatar answered Mar 20 '23 08:03

Renan Ranelli


Any reason why you don't just filter?

Anyways it seems like you're trying to mutate the value of return which is not possible with Elixir.

base = "master"
candidates = ["stream", "pigeon", "maters"]
result = Enum.filter(candidates, fn(candidate) ->
  length(candidate) == length(base)
end

IO.inspect result

Edit: I'd also like to add that based on your logic, all of the candidates would be returned

like image 30
Christopher Yammine Avatar answered Mar 20 '23 09:03

Christopher Yammine