Skip to content

Commit 5e050f2

Browse files
authored
Rework if/2 docs and mention variable scope (#14452)
1 parent 7e33cee commit 5e050f2

File tree

1 file changed

+46
-27
lines changed

1 file changed

+46
-27
lines changed

lib/elixir/lib/kernel.ex

+46-27
Original file line numberDiff line numberDiff line change
@@ -3898,51 +3898,70 @@ defmodule Kernel do
38983898
38993899
## One-liner examples
39003900
3901-
if(foo, do: bar)
3901+
iex> if 7 > 5, do: "yes"
3902+
"yes"
39023903
3903-
In the example above, `bar` will be returned if `foo` evaluates to
3904-
a truthy value (neither `false` nor `nil`). Otherwise, `nil` will be
3905-
returned.
3904+
iex> if "truthy value", do: "yes"
3905+
"yes"
3906+
3907+
In the examples above, the `do` clause is evaluated and `"yes"` will be returned
3908+
because the condition evaluates to a truthy value (neither `false` nor `nil`).
3909+
Otherwise, the clause is not evaluated and `nil` will be returned:
3910+
3911+
iex> if 3 > 5, do: "yes"
3912+
nil
3913+
3914+
iex> if nil, do: IO.puts("this won't be printed")
3915+
nil
39063916
39073917
An `else` option can be given to specify the opposite:
39083918
3909-
if(foo, do: bar, else: baz)
3919+
iex> if 3 > 5, do: "yes", else: "no"
3920+
"no"
39103921
39113922
## Blocks examples
39123923
39133924
It's also possible to pass a block to the `if/2` macro. The first
39143925
example above would be translated to:
39153926
3916-
if foo do
3917-
bar
3918-
end
3927+
iex> if 7 > 5 do
3928+
...> "yes"
3929+
...> end
3930+
"yes"
39193931
3920-
Note that `do`-`end` become delimiters. The second example would
3932+
Note that `do`-`end` become delimiters. The third example would
39213933
translate to:
39223934
3923-
if foo do
3924-
bar
3925-
else
3926-
baz
3927-
end
3928-
3929-
## Examples
3930-
3931-
iex> if 5 > 7 do
3932-
...> "This will never be returned"
3935+
iex> if 3 > 5 do
3936+
...> "yes"
39333937
...> else
3934-
...> "This will be returned"
3938+
...> "no"
39353939
...> end
3936-
"This will be returned"
3937-
3938-
iex> if 2 + 2 == 4, do: :correct
3939-
:correct
3940-
3941-
iex> if 2 + 2 == 5, do: :correct
3942-
nil
3940+
"no"
39433941
39443942
If you find yourself nesting conditionals inside conditionals,
39453943
consider using `cond/1`.
3944+
3945+
## Variables scope
3946+
3947+
Variables set within `do`/`else` blocks do not leak to the outer context:
3948+
3949+
x = 1
3950+
if x > 0 do
3951+
x = x + 1
3952+
IO.puts(x) # prints 2
3953+
end
3954+
x # 1
3955+
3956+
Variables set in the condition are available in the outer context:
3957+
3958+
fruits = %{oranges: 3}
3959+
if count = fruits[:apples] do
3960+
# won't be evaluated
3961+
IO.puts(count + 1)
3962+
end
3963+
count # nil
3964+
39463965
"""
39473966
defmacro if(condition, clauses) do
39483967
build_if(condition, clauses)

0 commit comments

Comments
 (0)