7

I want a script to run a subroutine exported from a module, with the exported sub to be run as MAIN in the script. The subroutine does all that I want, except that it returns the result instead of printing it.

RUN-MAIN seems to achieve most of what I'm aiming for, but I'm not sure how to grab the returned value of the routine.

Is there a way I can capture the output of the routine given to RUN-MAIN to be printed? Is RUN-MAIN the right approach for this sort of thing?

Daniel Mita
  • 512
  • 2
  • 9

3 Answers3

5

You could use the function composition operator infix:<∘> or infix:<o>

sub foo ($name, Int $n=1) { 
    "Hello $name\n" xx $n 
}; 
RUN-MAIN &say o &foo, Nil; #or &foo Ro &say

but unfortunately, it is changing the signature

sub foo ($name, Int $n=1) { 
    "Hello $name\n" xx $n 
};

say &foo.signature;
say (&foo Ro &say).signature;

so default USAGE message does not work.

jjmerelo
  • 22,578
  • 8
  • 40
  • 86
wamba
  • 3,883
  • 15
  • 21
  • The lack of USAGE is indeed unfortunate, but infix:<∘> is a nice idea! I'll have a play around with it. – Daniel Mita Nov 20 '19 at 17:42
  • 1
    I'm playing around with the following which seems to doing what I want so far: our &MAIN = &say ∘ &foo; RUN-MAIN( &foo, Nil ); – Daniel Mita Nov 20 '19 at 18:03
2

The following seems to accomplish what I intended (where foo is the target sub).

RUN-MAIN( &foo, Nil );

sub MAIN ( |c --> Nil ) {
  foo(|c).say;
}

EDIT: Unfortunately this solution is not ideal, as it runs &foo twice.

Daniel Mita
  • 512
  • 2
  • 9
  • It is not a typo. The first `|c` is a Capture parameter, and the additional prepended `|` is to make it a Slip. This didn't quite work as I'd expected, although I'll need to remind myself why, and if it was exactly this or something else that caused my issue (IIRC I was running MAIN twice somehow, once with and once without `say`). After playing around a bit this was the final result I came up with: https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-035/daniel-mita/perl6/ch-1.p6 – Daniel Mita Dec 19 '19 at 15:09
  • It seems I misunderstood the documentation, so yes the extra pipe is in fact a typo :) – Daniel Mita Dec 19 '19 at 16:39
2

Redispatch can be used within a wrapped routine to call the original. say can then be used on the result of the redispatch within the wrap. This will also generate usage from the original routine.

sub foo (
  $input #= The data we want
) {
  return $input;
}

&foo.wrap( sub (|) { callsame.say } );

RUN-MAIN &foo, Nil;

$ raku filename.raku

Usage:
  filename.raku <input>
  
    <input>    The data we want
Daniel Mita
  • 512
  • 2
  • 9