Hi Brad, This is what I see when I run your first example. (I've
numbered each command line prompt ">" to make it easier to reference
each REPL input):

mbook:~ homedir$ perl6 --version
This is Rakudo version 2019.07.1 built on MoarVM version 2019.07.1
implementing Perl 6.d.
mbook:~ homedir$ perl6
To exit type 'exit' or '^D'
1> $*VM
moar (2019.07.1)
2> say $*VM
moar (2019.07.1)
3> {say $*VM}
moar (2019.07.1)
4> lines {;}
No such method 'lines' for invocant of type 'Block'. Did you mean 'line'?
  in block <unit> at <unknown file> line 1

5> lines {say $*VM}
No such method 'lines' for invocant of type 'Block'. Did you mean 'line'?
  in block <unit> at <unknown file> line 1

6> lines {say $*VM;}
No such method 'lines' for invocant of type 'Block'. Did you mean 'line'?
  in block <unit> at <unknown file> line 1

7> for lines {;}
===SORRY!===
Function 'lines' needs parens to avoid gobbling block
------> for lines {;}<EOL>
Missing block (apparently claimed by 'lines')
------> for lines {;}<EOL>

8> for lines {say $*VM}
===SORRY!===
Function 'lines' needs parens to avoid gobbling block
------> for lines {say $*VM}<EOL>
Missing block (apparently claimed by 'lines')
------> for lines {say $*VM}<EOL>

9> for lines() {say $*VM}

moar (2019.07.1)

moar (2019.07.1)
mbook:~ homedir$

Examples 1-through-8 should be self-explanatory, and Example 4 is your
first line of code exactly. In Example 9 the REPL waits for input,
when return is pressed the REPL then prints out "moar (2019.07.1)".
I've checked this code in 6Pad (https://perl6.github.io/6pad/) and get
similar error messages. Also another user at this past weekend's Perl6
Meetup saw error messages--but different ones--presumably because that
user was running Rakudo 2019.03 / MoarVM 2019.03.

I didn't expect your first line of code (Example 4) to throw an error
since you labeled it "valid Perl6 code". Maybe I'm not understanding
what you were trying to show me, but I'm still not sure why I'm
getting an error or what's going on. Any help appreciated.

Best Regards, Bill.


On Fri, Aug 2, 2019 at 7:53 AM Brad Gilbert <b2gi...@gmail.com> wrote:
>
> `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