develooper Front page | perl.perl6.users | Postings from January 2019

Re: **@args question

Thread Previous | Thread Next
From:
ToddAndMargo via perl6-users
Date:
January 4, 2019 19:39
Subject:
Re: **@args question
Message ID:
a602f67e-0be6-a7f7-df87-e1fcdfe4ce03@zoho.com
On 1/3/19 2:58 AM, Brad Gilbert wrote:
> On Thu, Jan 3, 2019 at 12:43 AM ToddAndMargo via perl6-users
> <perl6-users@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-users@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!

-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Computers are like air conditioners.
They malfunction when you open windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About