Home > Raku > nomen est omen

nomen est omen

Even with the help of his time machine, delivering all presents in a single night keeps Santa extremely busy. With little time to spare he does all his coding in Raku. One of the advantages of time travel, is the option to use the last version of the last programming language.

use v6.∞;

With prizing time so high, wasting it on typing wont make sense. Santa found a way to get double purchase on variable names.

sub drop-package($chimney-id, Channel \p1, Channel \p2) {
     my $stdout = p1.VAR.name.ends-with('-out')
         ?? p1 
         !! p2.VAR.name.ends-with('-out') 
             ?? p2 
             !! fail(‚I don't know what to do with p1‘);

    my $stderr = p1.VAR.name.ends-with('-err')
         ?? p1
         !! p2.VAR.name.ends-with('-err')
             ?? p2
             !! fail(‚I don't know what to do with p1‘);

     px«sledctl --drop-package-in=$chimney-id» |» $stdout :$stderr;
}

my Channel $std-out .= new;
my Channel $std-err .= new;
drop-package(6955057934, $std-out, $std-err);

In Raku we can tell the compiler quite precise how to turn symbols on the caller side to symbols on the callee side. By using a sigilless or is raw parameter in a Signature, we ask not to introducing any new container. When the routine is called either a value or a container is bound to that parameter. Containers got the .VAR method which in turn has a .name method. Since we bind we get the original container from the caller side. With this little trick, Santa does not need to remember the order of positional parameters.

This year I ask Santa for a crowbar so I have a chance to pry my tongue out of my cheek — getting it stuck there is one of the perils of being a blogger.

update:

Lizmat didn’t like Santas ternary operator construct and simplified it a bit.

sub drop-package($chimney-id, Channel \p1, Channel \p2) {       
    sub assign(\target) {       
        my $suffix = target.VAR.name.substr(*-4);       
        target = p1.VAR.name.ends-with($suffix)       
          ?? p1          
          !! p2.VAR.name.ends-with($suffix)         
            ?? p2            
            !! fail       
    }          
                
    assign(my $stdout);       
    assign(my $stderr);       
}

Since we are matching against a string and run some code, we might as well use a lookup table.

sub drop-package($chimney-id, Channel \p1, Channel \p2) {
    my ($stdout, $stderr);
    constant %lookup =
        '-out' => -> \v { $stdout = v },
        '-err' => -> \v { $stderr = v };

    for p1, p2 {
        .&( %lookup{.VAR.name.substr(*-4)} // fail(‚I don't know what to do with ‘ ~ .VAR.name) );
    }

    px«sledctl --drop-package-in=$chimney-id» |» $stdout :$stderr;
 }

A multi with a where-clause that checks against a constant is a lookup table. So we can combine both ideas.

sub drop-package($chimney-id, Channel \p1, Channel \p2) {
    my ($stdout, $stderr);
    
    multi sub assign(\v where {.VAR.name.ends-with('-out')}) { $stdout = v }
    multi sub assign(\v where {.VAR.name.ends-with('-err')}) { $stderr = v }
    
    assign(p1); assign(p2);

    px«sledctl --drop-package-in=$chimney-id» |» $stdout :$stderr;
}

Categories: Raku