Raku by Example: Conditionals

if/elsif/else/unless

The if keyword runs a block conditionally. Such block is only evaluated if the condition evaluates to True when the Bool method is called on it.

if 1 { say '1 evaluates to True.' } 
if 0 { say '0 evaluates to False.' } 

# Falsey values: 0, (), {}, "", `Nil`, types (e.g., `Int`) and `False` itself.
# Everything else is Truthy in Raku.
$ perl6 if01.p6
1 evaluates to True.
4 doesn't divide 45 evenly.

if/else

if 45 %% 4 {
    say '4 divides 45 evenly.'
}
else {
    say "4 doesn't divide 45 evenly."
}
$ perl6 if02.p6
4 doesn't divide 45 evenly.

if/elsif/else

my $n = 23;
if $n < 0 { 
    say "$n is negative."
}
elsif $n < 10 { 
    say "$n has 1 digit."
}
else  { 
    say "$n is non-negative and has multiple digits."
}
$ perl6 if03.p6
23 is non-negative and has multiple digits.

unless

The unless keyword inverts the sense of a conditional statement. Similar to if not(X). unless cannot be followed by an else or elsif.

my $age = 19;
unless $age < 18 {
    say "You're an adult."
}

# Similar to this:

if not($age < 18) {  # Or: `if !($age < 18) { ... }`
    say "You're an adult."
}
$ perl6 unless.p6
You're an adult.
You're an adult.

with

Unlike if that tests for truthness, with tests for definedness.

if "abc".index("a") {          # This is not evaluated since the expression
    say "'abc' contains 'a'"   # returns 0 which is a "falsey" value.
}

with "abc".index("a") {        # This does since 0 is a defined value.
    $_.say; 
    # Or just .say since `with`
    # topicalizes on the condition.
}  
$ perl6 with.p6
0

with/orwith/else

my $str = 'oro';
with $str.index("o") {
    say "Found 'o' at index."
}
orwith $str.index("r") {
    say "Found 'r' at index $_."
}
else {
    say "Didn't  find 'o' or 'r'."
}
$ perl6 with_orwith.p6
Found 'o' at index.

without

This keyword tests for undefinedness. Similar to unless, without cannot be followed by an else clause.

my $answer = Any;
without $answer {
    say "undefined answer"
}
$ perl6 without.p6
undefined answer

given...when

The given...when is considered Raku's topicalizing statement. Similar to the switch statement in other languages.

my $input = 3;
given $input {
    when Int { say 'An integer' } # $_ ~~ Int
    when Str { say 'A string'   } # $_ ~~ Str
    when 3   { say $_ ** 2      } # $_ ~~ 3
    default  { say 'Something'  }
}
$ perl6 given_when.p6
An integer

The if and when blocks are similar but unlike an if block, the execution control does not fall through with a when block: After control is passed to an enclosing when block, all subsequent blocks are ignored regardless of them being conditionally true.

gather...take

The statement gather returns a sequence of values which come from calls to take in the dynamic scope of the gather block. The gather...take construct can generate values lazily, depending on context and lazy evaluation can be forced by using the sub (or method) lazy.

my @nums = gather {
    take 1;
    take $_ for 2..3;
}

say "Numbers: @nums[]";

# gathering lazily
my @vals = lazy gather {
    take <🐭>;
    say "Hello!";
    take <🐿>;
}

say @vals[0];
say "Don't say 'Hello!' before this.";
say @vals[1];
$ perl6 gather_take.p6
Numbers: 1 2 3
🐭
Don't say 'Hello!' before this.
Hello!
🐿

For additional information, go to https://docs.perl6.org/language/control.

Back to main