`lines` is a function, so it can take arguments.

A bare-block can be an argument:

    lines {;} # <- valid Perl6 code

So this:

    for lines {…}

is parsed the same as

    for lines( {…} )

Which means that `for` doesn't have a block. but you can give it one:

    for lines {;} {;}

---

If you try that you get an error like:

    > No such method 'lines' for invocant of type 'Block'. Did you mean
'line'?

This is because the `lines` function actually calls a method named `.lines`
on either its argument, or `$*ARGFILE` if there isn't an argument.
`Block` doesn't have a `.lines` method so this is an error.

I can prove it works like that by writing a different function to call.

    sub foo ($_) { .^name }
    for foo {;} { .say }
    # Block

---

So you can leave off the parens of `lines()` if it is obvious to Perl6 that
it doesn't have an argument.

    for ( lines ) {…}

    … for lines;

    my @lines = lines;

Or if you are giving it an argument, and it is obvious to Perl6 where the
argument list ends

    for lines $*ARGFILES {…}

(You would need a `,` after `$*ARGFILES` for the block to be considered an
argument.)

---

If it didn't work like this, none of the following line would not work,
without special handling:

    for map {…}, lines() {…}

    map {…}, lines;

---

One of the design goals of Perl6 is to have as few special cases as
possible.
Having `map` accept a block is really useful, so now all functions can take
a block.
(That was not the case in Perl5. At least not without using a more advanced
feature.)

The problem is may be that you expect there to be a special case for `for`
and other similar keywords and there just isn't one.

On Thu, Aug 1, 2019 at 10:50 PM William Michels via perl6-users <
perl6-us...@perl.org> 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
>
> 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
>
> mbook:~ homedir$ perl6 -e '.say for lines("a\nb\n")' six_fruits1.txt
> a
> b
>
> mbook:~ homedir$ perl6 -e '.say for lines[0]' six_fruits1.txt
> apple:banana:carrot:dragonfruit:eggplant:favabean
>
> mbook:~ homedir$ perl6 -e '.say for lines[0..1]' six_fruits1.txt
> apple:banana:carrot:dragonfruit:eggplant:favabean
> apricot:basil:cabbage:dill:escarole:fennel
>
> 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
>
> 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
>
> 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
>
> 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
>
>
>
>
> 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)
> >> >
> >> >
>

Reply via email to