raku

Avoid repeating the same variable in a chain of conditions


I have a script with a conditional and a pile of checks using the same variable. Something similar to this:

my $size = "123B";
say "OK" if $size ~~ Str && $size.ends-with("B") && $size.chop >= 0;

Would it be possible to rewrite the line in a way that would avoid the repetition of $size? I thought something like junctions which I have no idea how to apply to that. Or maybe something else, but shorter to my line.


Solution

  • How about:

    my $size1 = "123B";
    given $size1 {
          say "OK" if .isa(Str) && .ends-with("B") && .chop >= 0;
    };
    

    The given statement "topicalizes" the $size1 object, in other words loads it into $_, the topic variable in Raku (and Perl as well). Raku code like $_.isa(Str) can be shortened to .isa(Str). Subsequent tests like $_.ends-with("B") and .chop >= 0 are shortened to the "leading dot" as well.


    Or using the [&&] reduction meta-operator:

    my $size2 = "123B";
    given $size2 {
          say "OK" if  [&&] .isa(Str), .ends-with("B"), .chop >= 0;
    };
    

    Or with an all() junction:

    my $size3 = "123B";
    given $size3 {
          say "OK" if  $_ ~~ all( .isa(Str), .ends-with("B"), .chop >= 0);
    }
    

    Or eliminate the given block entirely:

    my $size4 = "123B";
    say "OK" if  $size4 ~~ all( .isa(Str), .ends-with("B"), .chop >= 0);
    

    Note some exceptions as pointed out by @raiph in the comments (e.g. final example above will accept a string "B" without complaining about missing digits).

    https://course.raku.org/essentials/loops/topic/