On 1/4/19 11:39 AM, ToddAndMargo via perl6-users wrote:
On 1/3/19 2:58 AM, Brad Gilbert wrote:
On Thu, Jan 3, 2019 at 12:43 AM ToddAndMargo via perl6-users
<perl6-us...@perl.org> wrote:

On 1/2/19 10:17 PM, ToddAndMargo via perl6-users wrote:
  > On Wed, Jan 2, 2019 at 8:41 PM ToddAndMargo via perl6-users
  > <perl6-us...@perl.org> wrote:
  >>
  >> Hi All,
  >>
  >> Looking at
  >>
  >>      https://docs.perl6.org/routine/print
  >>
  >> I see
  >>
  >>      multi sub print(**@args --> True)
  >>
  >> Question.  If I wanted to create my own print routine
  >> using **@args, how would I declare it?
  >>
  >>      sub printx( **@args data ) {...}
  >>
  >>
  >> Many thanks,
  >> -T


On 1/2/19 10:06 PM, Brad Gilbert wrote:
The variable name in :(**@args) is @args, it could be any valid array
identifier like @data

      sub printx( **@data ){…}

Note that there are several forms for slurpy positional arguments.

      :(   @a ) # not slurpy at all, takes one Positional argument and
aliases it as @a.

      :(  *@a ) # flattening slurpy  (1,),2,3 → 1,2,3 and ((1,),2,3) →
1,2,3
      :( **@a ) # structured slurpy (1,),2,3 → (1,),2,3 and ((1,),2,3) →
((1,),2,3) # note there is no change
      :(  +@a ) # one-arg rule slurpy (1,),2,3 → (1,),2,3 and ((1,),2,3)
→ (1,),2,3 # note that the second one changes

Note that itemized values do not get flattened for :(*@a), and that
Array values are itemized.

I like to consider the one-arg rule slurpy :(+@a) to be like a
combination between non-slurpy :(@a) and structured slurpy :(**@a)
That is a one-arg rule slurpy will sometimes be like an alias to a
singular positional, otherwise it will act like a structured slurpy.

Note that all but the [aliasing] non-slurpy :(@a) are [almost] always
Array's.

---

The one-arg rule slurpy is the oddest one of the bunch so here is some
brief information:

The one-arg rule slurpy can be sigiless :(+a), in which case it will
be a List instead of an Array or an alias to the single argument
depending on what it was.

      sub one-arg-rule ( +args ){
          say args.^name, " # ", args.perl;
      }

      one-arg-rule(  (1,),2,3  ); # List # ((1,), 2, 3)
      one-arg-rule( ((1,),2,3) ); # List # ((1,), 2, 3) # one-arg rule
      one-arg-rule( ((1,),2,3).Seq ); # Seq # ((1,), 2, 3).Seq #
one-arg rule
      one-arg-rule(  1..3   ); # List # (1, 2, 3)
      one-arg-rule( (1..3,) ); # List # (1..3,)

      sub one-arg-Array ( +@args ){
          say @args.^name, " # ", @args.perl;
      }

      one-arg-Array(  (1,),2,3  ); # Array # [(1,), 2, 3]
      one-arg-Array( ((1,),2,3) ); # Array # [(1,), 2, 3]
      one-arg-Array( ((1,),2,3).Seq ); # List # ((1,), 2, 3)
      one-arg-Array(  1..3   ); # Array # [1, 2, 3]
      one-arg-Array( (1..3,) ); # Array # [1..3,]

The one-arg rule exists because people tend to write the following:

      my @a = [1,2,3];

When the correct way to write it is:

      my @a = 1,2,3;

There are various other places where the one-arg rule is also used, so
it was made available to everyone.

---

Don't get too flustered if you don't understand all of the nuances, it
take everybody a while to understand them.


Thank you!

The term "slurpy" did help a lot.

:-)

I am writing your explanation down for my records.


Well Golly!

$ p6 'sub printx(**@args){print(@args)}; printx("abc",1,"def\n");'
abc 1 def

$ p6 'sub printx(**@args){print @args, "\n"}; printx("abc",1,"def");'
abc 1 def

Question:
$ p6 'sub printx(**@args){print(@args)}; printx("abc","xyz","def\n");'
abc xyz def

Are the spaces suppose to be there?

The spaces are there because you are passing `@args` to `print` as a
single value.
`print` coerces all its values to `Str` before printing, and an Array
adds spaces between elements when turned into a Str.

Simple fix use `|@args` to Slip it into the call to `print`

     $ p6 'sub printx(**@args){print( |@args, "\n" )};
printx("abc","xyz","def");'
     abcxyzdef


$ p6 'sub printx(**@args){print(|@args)}; printx("abc", "xyz","def\n");'
abcxyzdef

Sweet!  Thank you!


Follow up:

<PrintColors.pm6>
unit module PrintColors;

#`{

There subs give you the ability to print to the stand output and standard error
     with color.

     To use these, place the following at the top(ish) of your program
        use lib "/home/linuxutil";
use PrintColors; # qx[ PrintRed PrintGreen PrintBlue PrintErr PrintRedErr PrintGreenErr PrintBlueErr ]

}

use Terminal::ANSIColor;  # qx[ color ];

sub PrintRed ( **@args ) is export { print color('bold'), color('red'), |@args, color('reset'); } sub PrintGreen ( **@args ) is export { print color('bold'), color('green'), |@args, color('reset'); } sub PrintBlue ( **@args ) is export { print color('bold'), color('blue'), |@args, color('reset'); }

sub PrintErr   ( **@args ) is export { $*ERR.print: |@args; }

sub PrintRedErr ( **@args ) is export { $*ERR.print: color('bold'), color('red'), |@args, color('reset'); } sub PrintGreenErr ( **@args ) is export { $*ERR.print: color('bold'), color('green'), |@args, color('reset'); } sub PrintBlueErr ( **@args ) is export { $*ERR.print: color('bold'), color('blue'), |@args, color('reset'); }

# $ perl6 -I. -MPrintColors -e 'PrintRedTest( "abc", 1, "def", "\n" );'
sub PrintRedTest( **@args ) is export { print color('bold'), color('red'), |@args, color('reset'); }
</PrintColors.pm6>

Reply via email to