我想创建一个动态函数,该函数在声明函数时使用(评估?)变量的值。
下面的示例要求 $var 作为全局变量存在,以便在调用函数时可以使用它:
my $var = 'something';
someFunction(sub { return $_[0] eq $var; });
但我猜有一些方法可以创建动态函数,所以它是这样声明的:
someFunction(sub { return $_[0] eq 'something'; });
我怎样才能做到这一点!?:)
我想创建一个动态函数,该函数在声明函数时使用(评估?)变量的值。
下面的示例要求 $var 作为全局变量存在,以便在调用函数时可以使用它:
my $var = 'something';
someFunction(sub { return $_[0] eq $var; });
但我猜有一些方法可以创建动态函数,所以它是这样声明的:
someFunction(sub { return $_[0] eq 'something'; });
我怎样才能做到这一点!?:)
有点草率,但它有效:
#!/usr/bin/env perl
use warnings;
use strict;
my $var = 'something';
my $f1 = sub { my $v = $_[0]; return sub { return $_[0] eq $v } };
my $f2 = $f1->($var);
$var = 'other thing';
print $f2->('something');
有了 lambda,一切皆有可能。
旧的、简单的、直接的封闭有什么问题?
sub genf { my $v = shift; sub { shift eq $v } }
my $f = genf('something'); # Or genf($var)
print &$f('something');
print &$f('another thing');
像其他人一样,我认为为此目的关闭是可以的。如果编译器可以将其优化到您期望的水平,我什至不会感到惊讶,尽管我没有专家来证明这一点。
不过,我可以尝试你的要求,但我不推荐它。
my $var = 'something';
my $sub = eval 'sub { return $_[0] eq \'' . $var . '\'}';
someFunction( $sub );
您将代码引用构建为字符串,使用 的值,$var
然后将eval
其编译为 Perl 代码。请注意,您必须包含额外的引号,因为在评估代码时,内容$var
将是一个裸字符串。
同样,不建议这样做。为什么?因为它很危险,尤其是如果内容$var
来自外部世界。
如何捕获它的本地副本?
someFunction( do { my $v = $var; sub { $_[0] eq $v } } );
这样,即使$var
后来被修改,匿名子仍然使用其原始值的本地副本。