Why does `will end` behave differently than `will leave` in program-level scope?

Viewed 122

I thought that in the top level of a program that will end and will leave would behave the same way, since there is only one big outer scope to exit/leave from. I thought that either one would be a good way to check a variable's final value.

But with will end it acts like the variable has never been initialized:

my $foo will end { put "Final value for \$foo is '$_'"} = 'bar';

put "\$foo is now '$foo'";

$foo ~= ' baz';

OUTPUT

$foo is now 'bar'
Use of uninitialized value $_ of type Any in string context.
Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful.
  in block  at phaser_end.p6 line 1
Final value for $foo is ''

However, simply changing will end to will leave does what I would expect from either one:

my $foo will leave { put "Final value for \$foo is '$_'"} = 'bar';

put "\$foo is now '$foo'";

$foo ~= ' baz';

OUTPUT

$foo is now 'bar'
Final value for $foo is 'bar baz'

Why is there a difference in behavior here?

I am using Rakudo-Star 2017.07.

UPDATE

To get the effect that I'm expecting with will end, I have to use a separate END block:

END block:

my $foo = 'bar';

END { put "Final value for \$foo is '$foo'"};

put "\$foo is now '$foo'";

$foo ~= ' baz';

I guess the real question boils down to why does the END block behave differently than the will end block.

will end block:

my $foo will end { put "Final value for \$foo is '$_'"} = 'bar';

put "\$foo is now '$foo'";

$foo ~= ' baz';
1 Answers
Related