Here's the very end plus one more example > for show_args({say "code here"}) { say "show_args returned $_" }
[-> ;; $_? is raw { #`(Block|140485954938480) ... }] show_args returned True > for show_args() { say "show_args returned $_" } [] show_args returned True > for (show_args) { say "show_args returned $_" } [] show_args returned True The point is to be clear about the block NOT being an argument to the sub before the block, when that sub having 0 or 1 arg are both valid options for that sub. "lines" is like that, same as "show_args". So either be explicit about the sub having no args, by using empty parens, or put parens around the sub call entirely, or re-arrange it with the sub call at the end- > say "show_args returned $_" for show_args [] show_args returned True -y On Sat, Aug 3, 2019 at 3:23 PM yary <not....@gmail.com> wrote: > Hi Bill, > > maybe this example will help clarify the "theoretical" syntax explanations > of what happens with, and without, the empty parens. > > First, there's a method ".perl" that shows what it's called on- it > serializes its object if it can. For code it shows that it's a block with a > ID. > > $ perl6 > > To exit type 'exit' or '^D' > > > > q<Here's a string>.perl > > "Here's a string" > > > > (2/3).perl > > <2/3> > > > > (11,22,33,44).perl > > (11, 22, 33, 44) > > > > { say "this is code" }.perl > > -> ;; $_? is raw { #`(Block|140455367275128) ... } > > > Here's a sub that says its arguments- > > sub show_args { say @_.perl } > > Called by itself, or in a context without any ambiguity, parens are > optional calling a sub. > > > > show_args > > [] > > > > show_args() > > [] > > > show_args 11,22,33 > > [11, 22, 33] > > > show_args(11,22,33) > > [11, 22, 33] > > > > show_args 11,22,33, { say "this is code" } > > [11, 22, 33, -> ;; $_? is raw { #`(Block|140455367731128) ... }] > > > show_args(11,22,33, { say "this is code" }) > > [11, 22, 33, -> ;; $_? is raw { #`(Block|140306311748968) ... }] > > Now let's say we want to loop over the return value of show_args (which is > the value of the last statement in it, "say", which returns True when it > says successfully ) > > > for show_args(11,22,33) { say "show_args returned $_" } > > [11, 22, 33] > > show_args returned True > > > > for show_args 11,22,33 { say "show_args returned $_" } > > [11, 22, 33] > > show_args returned True > > > for show_args 11, 22, 33, { say "this is code" } { say "show_args > returned $_" } > > [11, 22, 33, -> ;; $_? is raw { #`(Block|140306324890560) ... }] > > show_args returned True > > > That last two examples shows parens still optional, there's no ambiguity > where the list of args for "show_args" ends, and the start of for's block > begins. > > In the below, is the code block the first arg to show_args, or is it part > of the for loop? > > for show_args { say "this is code" } > > Perl6 is consistent and parses the block as show_args's first parameter- > these are all the same class of syntax error. > > > for show_args 11; > > ===SORRY!=== Error while compiling: > > *Missing block* > > > > for show_args(11); > > ===SORRY!=== Error while compiling: > > *Missing block* > > > > for show_args {say "code here"}; > > ===SORRY!=== > > Function 'show_args' needs parens to avoid gobbling block > > ------> for show_args {say "code here"}⏏; > > *Missing block* (apparently claimed by 'show_args') > > > for show_args({say "code here"}); > > ===SORRY!=== > > Function 'show_args' needs parens to avoid gobbling block > > at line 5 > > ------> for show_args({say "code here"}⏏); > > *Missing block* (apparently claimed by 'show_args') > > - the last two show the truth of the 'Missing block'- adding parens > doesn't create the block out of thin air, I placed the parens to emphasize > how Perl6 parses without them. > > > for show_args({say "code here"}) { say "show_args returned $_" } > > [-> ;; $_? is raw { #`(Block|140485954938480) ... }] > > show_args returned True > > > for show_args() { say "show_args returned $_" } > > [] > > show_args returned True > > Hope a light bulb went off—and sorry that I am not at this week's P6 study > group at the Oakland City Museum café, if you happen to be there this very > moment! > > -y > > > On Fri, Aug 2, 2019 at 11:12 PM William Michels via perl6-users < > perl6-us...@perl.org> wrote: > >> Hi Richard, I'm not able to come to the same conclusions. >> Specifically, the previous code examples starting with 'for lines()' >> always have to have parentheses following 'lines' (as in 'lines() >> {...}'), otherwise Perl_6 balks (examples 6 and 7 previously posted). >> This is whether 'information is being passed' or not (i.e. empty >> parentheses are required): >> >> #example 6: >> mbook:~ homedir$ perl6 -e ' for lines() { say .split(":")[0, 2, 1, >> 5].join("\t") };' six_fruits1.txt >> apple carrot banana favabean >> apricot cabbage basil fennel >> acai celery beets figs >> >> #example 6 no-parens: >> mbook:~ homedir$ perl6 -e ' for lines { say .split(":")[0, 2, 1, >> 5].join("\t") };' six_fruits1.txt >> ===SORRY!=== >> Function 'lines' needs parens to avoid gobbling block >> at -e:1 >> ------> say .split(":")[0, 2, 1, 5].join("\t") }; >> Missing block (apparently claimed by 'lines') >> at -e:1 >> ------> say .split(":")[0, 2, 1, 5].join("\t") }; >> >> #example 7: >> mbook:~ homedir$ perl6 -e 'for lines() {.split(":")[0, 2, 1, >> 5].join("\t").say};' six_fruits1.txt >> apple carrot banana favabean >> apricot cabbage basil fennel >> acai celery beets figs >> >> #example 7 no-parens: >> mbook:~ homedir$ perl6 -e 'for lines {.split(":")[0, 2, 1, >> 5].join("\t").say};' six_fruits1.txt >> ===SORRY!=== >> Function 'lines' needs parens to avoid gobbling block >> at -e:1 >> ------> {.split(":")[0, 2, 1, 5].join("\t").say}; >> Missing block (apparently claimed by 'lines') >> at -e:1 >> ------> {.split(":")[0, 2, 1, 5].join("\t").say}; >> >> mbook:~ homedir$ perl6 --version >> This is Rakudo version 2019.07.1 built on MoarVM version 2019.07.1 >> implementing Perl 6.d. >> mbook:~ homedir$ >> >> Other Perl_6 users have replied with a general discussion of >> differences between using lines() as a method, or in a subroutine. I >> still have to review some of those comments. However, as I'm using the >> latest Perl_6 version (2019.07.1), I'm fairly confident in the results >> above (and below). >> >> Also, the examples below show that 'for lines[0..2] {...}' works, >> despite the previous error message insisting on parentheses ("Function >> 'lines' needs parens to avoid gobbling block at -e:1"). Taken >> together, the results above and below seem to indicate to me that the >> use of a bare 'lines' sub is disallowed, at least in a 'for' loop. >> --Best Regards, Bill. >> >> #example 10: >> mbook:~ homedir$ perl6 -e 'for lines { say .split(":")[0, 2, 1, >> 5].join("\t") };' six_fruits1.txt >> ===SORRY!=== >> Function 'lines' needs parens to avoid gobbling block >> at -e:1 >> ------> say .split(":")[0, 2, 1, 5].join("\t") }; >> Missing block (apparently claimed by 'lines') >> at -e:1 >> ------> say .split(":")[0, 2, 1, 5].join("\t") }; >> >> #example 11: >> mbook:~ homedir$ perl6 -e 'for lines() { say .split(":")[0, 2, 1, >> 5].join("\t") };' six_fruits1.txt >> apple carrot banana favabean >> apricot cabbage basil fennel >> acai celery beets figs >> >> #example 12: >> mbook:~ homedir$ perl6 -e 'for lines[0..2] { say .split(":")[0, 2, 1, >> 5].join("\t") };' six_fruits1.txt >> apple carrot banana favabean >> apricot cabbage basil fennel >> acai celery beets figs >> >> >> On Fri, Aug 2, 2019 at 1:20 AM Richard Hainsworth >> >> <rnhainswo...@gmail.com> wrote: >> > >> > Not quite sure what sort of "rule" you want. >> > >> > You used () and [] which do different things and the results were >> exactly what I would expect. They are covered in the documentation. >> Basically, () without a space, eg xxxx() not xxxx (), is used to pass >> information to the sub or method xxxx. >> > If no information is being passed, then no need to use (). The way xxxx >> responds to no data provided depends on the way xxxx is written. The >> programmer could provide default values for the arguments it expects. Perl6 >> also makes the value of the default variable, eg $_, to xxxx. >> > If you put a space between xxxx (), then () is interpreted as an empty >> list and provide to xxxx as a single piece of information. >> > [] Are used to dereference a list (sequence or array, they are all >> slightly different). >> > >> > I'll comment more below. Sometimes I think through the process using >> slightly different and less exact words. My comments are illustrative. >> > >> > On Fri, 2 Aug 2019, 04:50 William Michels, <w...@caa.columbia.edu> >> wrote: >> >> >> >> Hi Richard, I'm trying to figure out when the parentheses in 'lines()' >> >> can be dropped, and 'lines' used instead. Any pointers? I have about >> >> nine or so working examples below, but formulating a clear >> >> rule-of-thumb is proving elusive. Any help appreciated, --Best, Bill. >> >> >> >> # test file: six_fruits1.txt >> >> mbook:~ homedir$ cat six_fruits1.txt >> >> apple:banana:carrot:dragonfruit:eggplant:favabean >> >> apricot:basil:cabbage:dill:escarole:fennel >> >> acai:beets:celery:daikon:endive:figs >> >> >> >> mbook:~ homedir$ perl6 -e '.say for lines()' six_fruits1.txt >> >> apple:banana:carrot:dragonfruit:eggplant:favabean >> >> apricot:basil:cabbage:dill:escarole:fennel >> >> acai:beets:celery:daikon:endive:figs >> > >> > Here 'lines ()' is the same as 'lines'. >> > The program in the string after -e is provided with the data inside the >> file. >> >> >> >> >> >> mbook:~ homedir$ perl6 -e '.say for lines' six_fruits1.txt >> >> apple:banana:carrot:dragonfruit:eggplant:favabean >> >> apricot:basil:cabbage:dill:escarole:fennel >> >> acai:beets:celery:daikon:endive:figs >> > >> > The top two are equivalent >> >> >> >> >> >> mbook:~ homedir$ perl6 -e '.say for lines("a\nb\n")' six_fruits1.txt >> >> a >> >> b >> > >> > Here you provided data to 'lines' which it was able to interpret as a >> set of lines. So it printed them. The data in six_fruits is ignored because >> you provided the data explicitly. >> >> >> >> >> >> mbook:~ homedir$ perl6 -e '.say for lines[0]' six_fruits1.txt >> >> apple:banana:carrot:dragonfruit:eggplant:favabean >> > >> > Six_fruits has 3 lines. Lines has processed the data. But you wrote >> '[0]' which extracted the first line, and that was processed by the 'for' >> loop. In other words the 'for' was only given one piece of information to >> process. >> >> >> >> >> >> mbook:~ homedir$ perl6 -e '.say for lines[0..1]' six_fruits1.txt >> >> apple:banana:carrot:dragonfruit:eggplant:favabean >> >> apricot:basil:cabbage:dill:escarole:fennel >> > >> > The '[0..1]' extracts the first three pieces of data from 'lines' and >> they are processed by the 'for' >> >> >> >> >> >> mbook:~ homedir$ perl6 -e ' for lines() { say .split(":")[0, 2, 1, >> >> 5].join("\t") };' six_fruits1.txt >> >> apple carrot banana favabean >> >> apricot cabbage basil fennel >> >> acai celery beets figs >> > >> > Could be just 'lines', which provides a list of the lines in the file >> to the 'for' >> > Inside the 'for' the data is in the topic or default variable. You >> could access it as $_ but '.split' accesses it automatically. Split >> generates another list. '[0,2,1,5]' extracts the relevant elements of the >> list and generates another list which is passed to the'join'. The output >> from join is passed to 'say' which is written in sub form. Sub form means >> you write the name of the sub first, then you write where the data is >> coming from. >> > >> >> >> >> mbook:~ homedir$ perl6 -e ' for lines() {.split(":")[0, 2, 1, >> >> 5].join("\t").say};' six_fruits1.txt >> >> apple carrot banana favabean >> >> apricot cabbage basil fennel >> >> acai celery beets figs >> > >> > Exactly the same for perl6 as before except that 'say' is written in >> sub form above and in method form here. Method form means you can append >> the 'say' to a chain of processing units. >> >> >> >> >> >> mbook:~ homedir$ perl6 -e 'for "six_fruits1.txt".IO.lines() >> >> {.split(/\:/)[0, 2, 1, 5].join("\t").say};' >> >> apple carrot banana favabean >> >> apricot cabbage basil fennel >> >> acai celery beets figs >> > >> > Here just accessing the data in the file explicitly in perl6. >> >> >> >> >> >> mbook:~ homedir$ perl6 -e 'for "six_fruits1.txt".IO.lines >> >> {.split(/\:/)[0, 2, 1, 5].join("\t").say};' >> >> apple carrot banana favabean >> >> apricot cabbage basil fennel >> >> acai celery beets figs >> > >> > Same as above. No () on lines >> >> >> >> >> >> >> >> >> >> >> >> On Mon, Jul 29, 2019 at 1:07 AM Richard Hainsworth >> >> <rnhainswo...@gmail.com> wrote: >> >> > >> >> > Also no need for all the brackets >> >> > >> >> > .say for lines; >> >> > >> >> > This is quite idiomatic Perl 6 and not golfing >> >> > >> >> > On Mon, 29 Jul 2019, 07:13 Joseph Brenner, <doom...@gmail.com> >> wrote: >> >> >> >> >> >> > Hmmm. I would expect that to be in the Perl 5 to Perl 6 Migration >> Guides, but I do not see it there. >> >> >> >> >> >> Exactly, I was just looking there, and I ended up playing around >> with >> >> >> the method form of lines, and didn't think to try the function >> >> >> form of it. >> >> >> >> >> >> To summarize, if the goal is to write a "simple_echo" script that >> >> >> can work with a file name or with lines on standard input: >> >> >> >> >> >> simple_echo lines.txt >> >> >> cat lines.txt | simple_echo >> >> >> >> >> >> The perl5 version would probably be: >> >> >> >> >> >> #!/usr/bin/env perl >> >> >> while(<>){ >> >> >> print; >> >> >> } >> >> >> >> >> >> The perl6 version would be something like: >> >> >> >> >> >> #!/usr/bin/env perl6 >> >> >> use v6; >> >> >> for lines() { >> >> >> say $_; >> >> >> } >> >> >> >> >> >> >> >> >> The kind of thing I was playing with was: >> >> >> >> >> >> #!/usr/bin/env perl6 >> >> >> use v6; >> >> >> my @lines = $*ARGFILES.IO.lines; >> >> >> say @lines; >> >> >> >> >> >> That works for lines from a file, but not from standard input, and >> the >> >> >> error message isn't tremendously helpful: >> >> >> >> >> >> No such method 'lines' for invocant of type 'IO::Special' >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> On 7/28/19, Bruce Gray <robertbrucegr...@gmail.com> wrote: >> >> >> > >> >> >> > >> >> >> >> On Jul 28, 2019, at 6:20 PM, Joseph Brenner <doom...@gmail.com> >> wrote: >> >> >> >> >> >> >> >> I was just wondering if there's some direct analog in perl6 to >> the >> >> >> >> perl5 construct: >> >> >> >> >> >> >> >> while(<>){ ... } >> >> >> >> >> >> >> >> If I'm planning on passing a filename on the command-line, I can >> just >> >> >> >> get it out of $*ARGFILES easily enough, but what if I also >> wanted it >> >> >> >> to work on lines passed in via standard input? >> >> >> > >> >> >> > >> >> >> > `lines` , as a sub instead of a method, and no arguments. >> >> >> > >> >> >> > See: https://docs.perl6.org/routine/lines#(Cool)_routine_lines >> >> >> > Without any arguments, sub lines operates on $*ARGFILES, >> which defaults to >> >> >> > $*IN in the absence of any filenames. >> >> >> > >> >> >> > For example: >> >> >> > perl6 -e 'say .join("\t") for lines().rotor(4);' >> path/to/file.txt >> >> >> > >> >> >> > Hmmm. I would expect that to be in the Perl 5 to Perl 6 Migration >> Guides, >> >> >> > but I do not see it there. >> >> >> > >> >> >> > — >> >> >> > Hope this helps, >> >> >> > Bruce Gray (Util of PerlMonks) >> >> >> > >> >> >> > >> >