Perl6 one liner execution. How is the topic updated?

  • A+

Executing the one liner to process CSV a line at a time from stdin:

perl6 -ne 'my @a; $_.split(",") {@a[$^k]+=$^v}; say @a; ENTER {say "ENTER"}; BEGIN {say "BEGIN"}; LEAVE {say "LEAVE"}; END {say "END"}'; 

Typing in:

1,1 1,1 ^D 

Gives the following output:

BEGIN ENTER 1,1 [1 1] 1,1 [2 2] LEAVE END 

Here we can see that the one liner is not a block executed multiple times as the ENTER and LEAVE phaser are only executed once.

This makes sense as the variable @a is accumulating. If the one liner was a block the value of @a would be reset each time.

My question is how does the topic variable $_ get updated? The topic variable is a Str (at least that's what $_.^name says). How does its value update without re-entering the block?

What am I missing?


When you add -n it adds a for loop around your code.

You think it adds one like this:

for lines() {   # Your code here } 

The compiler just adds the abstract syntax tree nodes for looping without actually adding a block.

(    # Your code here ) for lines() 

(It could potentially be construed as a bug.)

To get it to work like the first one:

(             # -n adds this    -> $_ {     # <-- add this                # Your code here    }( $_ )     # <-- add this  ) for lines() # -n adds this 

I tried just adding a bare block, but the way the compiler adds the loop causes that to not work.

In general ENTER and LEAVE are scoped to a block {}, but they are also scoped to the “file” if there isn't a block.

ENTER say 'ENTER file'; LEAVE say 'LEAVE file'; {   ENTER say '  ENTER block';   LEAVE say '  LEAVE block'; } 
ENTER file   ENTER block   LEAVE block LEAVE file 

Since there is no block in your code, everything is scoped to the “file”.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: