Defining a variable according to an if-else statement

Sometimes I need to define a variable based on a branch like:

foo = []
if condition
  foo = "Julia"
else
  foo = "is awesome"
end

but I need to define it outside of the branch so that it becomes visible in the outside scope.

Is there a more idiomatic Julian way of achieving this result?

Make it a local variable, e.g.


 function f(cond::Bool)
       local x

       if cond
          x = 2
       else
          x = 3
       end
       x
end

@musm this saves us from typing the type of the object, right? I was thinking of doing this, but wondered if another approach with let-blocks or something existed.

But if blocks don’t impact scope, so this is not needed:

julia> if rand()>.5
       a = 7
       else
       b = 9
       end                                                                                                                             
9                                                                                                                                      

julia> a                                                                                                                               
ERROR: UndefVarError: a not defined                                                                                                    

julia> b                                                                                                                               
9                                                                                                                                      

julia> function foo()
       if rand()>.5
       a = 7
       else
       b = 9
       end
       @show a
       end                                                                                                                             
foo (generic function with 1 method)                                                                                                   

julia> foo()
ERROR: UndefVarError: a not defined
Stacktrace:
 [1] macro expansion at ./show.jl:243 [inlined]
 [2] foo() at ./REPL[3]:7

julia> foo()                                                                                                                           
a = 7                                                                                                                                  
7                                                                                                                                      

(Edited to reflect mistake pointed out by @yuyichao’s )

(but this does apply to try blocks, etc., which do impact scope.)

What gives you that impression? There was another recent thread claiming the same. Is it incorrectly mentioned in some doc somewhere or doesn’t work as intended in some cases?

2 Likes

This does not check local variables.

@yuyichao for some reason I assumed this didn’t work. I don’t know if it is because of an experience with a previous version of Julia, but I remember having issues with scope in this context in the past. I just tried it without predeclaring the variable and it works just fine. :blush:

Why not use a ternary operator?

foo = condition ? "Julia" : "is awesome"
2 Likes

@anon94023334, my conditions don’t fit in a line, I do the ternary operator whenever I can to increase code coverage :slight_smile:

Others have cleared up your misunderstanding, so I just want to add

foo = if condition
    "Julia"
else
    "is awesome"
end

which is of course more commonly written using the ternary operator (?:).

2 Likes

This also works:

foo = if cond
 ...
else
 ...
end
2 Likes

Depending on how complex things are, you can create a function that encompasses your conditions, but you’ve probably already decided against ternary operators for other reasons.

1 Like

I like this one! Clean and express the intent perfectly.

Use a ternary operator?
foo = (condition ? “Julia” : “is awesome”)