为什么 sub 在 raku 的 "return"ed 映射中使用时不能访问动态变量?
Why can't a sub access dynamic variables when used in a "return"ed map in raku?
当在地图中使用时,似乎 sub
无法访问动态变量,并且该地图是“return”ed。
考虑这段代码:
sub start {
my $*something = 'foobar';
# WORKS
say 'first say-something:';
say-something;
# WORKS
say 'mapped say-something, no return:';
my @foo = (^2).map({say-something});
# ERROR: Dynamic variable $*something not found
say 'mapped say-something, with return:';
return (^2).map({say-something});
}
sub say-something {
say $*something;
1
}
start;
这将输出:
first say-something:
foobar
mapped say-something, no return:
foobar
foobar
mapped say-something, with return:
Dynamic variable $*something not found
in sub say-something at main.raku line 18
in block <unit> at main.raku line 14
为什么sub无法访问动态变量?有解决办法吗?
例程 map
是 lazy,因此块 运行 直到 start 返回。
来自文档:
multi method map(Hash:D \hash)
multi method map(Iterable:D \iterable)
multi method map(|c)
multi method map(\SELF: █; :$label, :$item)
multi sub map(&code, +values)
Examples applied to lists are included here for the purpose of
illustration.
For a list, it invokes &code for each element and gathers the return
values in a sequence and returns it. This happens lazily, i.e. &code
is only invoked when the return values are accessed.
所以在你的情况下,地图被评估一次 start returns,因此动态变量已经超出范围。
解决此问题的方法是通过添加 .eager
强制 map
急切地 发生
return (^2).map({say-something}).eager
当在地图中使用时,似乎 sub
无法访问动态变量,并且该地图是“return”ed。
考虑这段代码:
sub start {
my $*something = 'foobar';
# WORKS
say 'first say-something:';
say-something;
# WORKS
say 'mapped say-something, no return:';
my @foo = (^2).map({say-something});
# ERROR: Dynamic variable $*something not found
say 'mapped say-something, with return:';
return (^2).map({say-something});
}
sub say-something {
say $*something;
1
}
start;
这将输出:
first say-something:
foobar
mapped say-something, no return:
foobar
foobar
mapped say-something, with return:
Dynamic variable $*something not found
in sub say-something at main.raku line 18
in block <unit> at main.raku line 14
为什么sub无法访问动态变量?有解决办法吗?
例程 map
是 lazy,因此块 运行 直到 start 返回。
来自文档:
multi method map(Hash:D \hash) multi method map(Iterable:D \iterable) multi method map(|c) multi method map(\SELF: █; :$label, :$item) multi sub map(&code, +values)
Examples applied to lists are included here for the purpose of illustration.
For a list, it invokes &code for each element and gathers the return values in a sequence and returns it. This happens lazily, i.e. &code is only invoked when the return values are accessed.
所以在你的情况下,地图被评估一次 start returns,因此动态变量已经超出范围。
解决此问题的方法是通过添加 .eager
map
急切地 发生
return (^2).map({say-something}).eager