为什么 `will end` 的行为与程序级范围内的 `will leave` 不同?
Why does `will end` behave differently than `will leave` in program-level scope?
我认为在程序的顶层 will end
和 will leave
的行为方式相同,因为 exit/leave 只有一个大的外部作用域。我认为其中任何一个都是检查变量最终值的好方法。
但是对于 will end
它就像变量从未被初始化一样:
my $foo will end { put "Final value for $foo is '$_'"} = 'bar';
put "$foo is now '$foo'";
$foo ~= ' baz';
输出
$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 ''
但是,只需将 will end
更改为 will leave
即可满足我对其中任何一个的期望:
my $foo will leave { put "Final value for $foo is '$_'"} = 'bar';
put "$foo is now '$foo'";
$foo ~= ' baz';
输出
$foo is now 'bar'
Final value for $foo is 'bar baz'
为什么这里的行为有所不同?
我正在使用 Rakudo-Star 2017.07.
更新
为了获得我期望的 will end
效果,我必须使用单独的 END
块:
END
块:
my $foo = 'bar';
END { put "Final value for $foo is '$foo'"};
put "$foo is now '$foo'";
$foo ~= ' baz';
我想真正的问题归结为为什么 END
块的行为与 will end
块不同。
will end
块:
my $foo will end { put "Final value for $foo is '$_'"} = 'bar';
put "$foo is now '$foo'";
$foo ~= ' baz';
重写
Why does will end
behave differently than will leave
看起来 will end
有一个类似于 this old and now resolved bug for will begin
的错误。
除此之外,一切都如我所料:
my $leave will leave { say ['leave:', $_, OUTERS::<$leave>] } = 'leave';
my $end will end { say ['end:', $_, OUTERS::<$end>] } = 'end';
my $begin will begin { say ['begin:', $_, OUTERS::<$begin>] } = 'begin';
END { say ['END:', $_, OUTERS::<$end>, $end] }
$_ = 999;
显示
[begin: (Any) (Any)]
[leave: leave leave]
[END: 999 end end]
[end: 999 end]
Is the scope for the block with will end
different than the scope of the block with will leave
?
它们具有与 UNIT
作用域对应的相同外部 lexical scope。
他们运行在不同的dynamic scopes. Leave blocks run as part of leaving the enclosing block. End blocks run after the compiler has completely finished with your code and is cleaning up:
sub MAIN(@ARGS) {
...
# UNIT scope -- your code -- is about to be created and compiled:
$comp.command_line ...
# UNIT scope no longer exists. We compiled it, ran it, and left it.
...
# do all the necessary actions at the end, if any
if nqp::gethllsym('perl6', '&THE_END') -> $THE_END {
$THE_END()
}
}
why does the END
block behave differently than the will end
block?
因为你在一个中使用了 $foo
而在另一个中使用了 $_
。
我认为在程序的顶层 will end
和 will leave
的行为方式相同,因为 exit/leave 只有一个大的外部作用域。我认为其中任何一个都是检查变量最终值的好方法。
但是对于 will end
它就像变量从未被初始化一样:
my $foo will end { put "Final value for $foo is '$_'"} = 'bar';
put "$foo is now '$foo'";
$foo ~= ' baz';
输出
$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 ''
但是,只需将 will end
更改为 will leave
即可满足我对其中任何一个的期望:
my $foo will leave { put "Final value for $foo is '$_'"} = 'bar';
put "$foo is now '$foo'";
$foo ~= ' baz';
输出
$foo is now 'bar' Final value for $foo is 'bar baz'
为什么这里的行为有所不同?
我正在使用 Rakudo-Star 2017.07.
更新
为了获得我期望的 will end
效果,我必须使用单独的 END
块:
END
块:
my $foo = 'bar';
END { put "Final value for $foo is '$foo'"};
put "$foo is now '$foo'";
$foo ~= ' baz';
我想真正的问题归结为为什么 END
块的行为与 will end
块不同。
will end
块:
my $foo will end { put "Final value for $foo is '$_'"} = 'bar';
put "$foo is now '$foo'";
$foo ~= ' baz';
重写
Why does
will end
behave differently thanwill leave
看起来 will end
有一个类似于 this old and now resolved bug for will begin
的错误。
除此之外,一切都如我所料:
my $leave will leave { say ['leave:', $_, OUTERS::<$leave>] } = 'leave';
my $end will end { say ['end:', $_, OUTERS::<$end>] } = 'end';
my $begin will begin { say ['begin:', $_, OUTERS::<$begin>] } = 'begin';
END { say ['END:', $_, OUTERS::<$end>, $end] }
$_ = 999;
显示
[begin: (Any) (Any)]
[leave: leave leave]
[END: 999 end end]
[end: 999 end]
Is the scope for the block with
will end
different than the scope of the block withwill leave
?
它们具有与 UNIT
作用域对应的相同外部 lexical scope。
他们运行在不同的dynamic scopes. Leave blocks run as part of leaving the enclosing block. End blocks run after the compiler has completely finished with your code and is cleaning up:
sub MAIN(@ARGS) {
...
# UNIT scope -- your code -- is about to be created and compiled:
$comp.command_line ...
# UNIT scope no longer exists. We compiled it, ran it, and left it.
...
# do all the necessary actions at the end, if any
if nqp::gethllsym('perl6', '&THE_END') -> $THE_END {
$THE_END()
}
}
why does the
END
block behave differently than thewill end
block?
因为你在一个中使用了 $foo
而在另一个中使用了 $_
。