`eval { $constant_name }` 给出名称,而不是值
`eval { $constant_name }` gives the name, not the value
我已经定义了几个 Perl 常量,例如 use constant LVL_FATAL => 1;
(perl 5.18.2)。
当试图创建一个需要名称和常量值的函数时,我尝试了:
my $level = eval { 'LVL_' . $_ };
当$_
为FATAL
时,$level
包含LVL_FATAL
,但不包含LVL_FATAL
的值。
我还尝试了变体 eval { $level }
、eval { ($level) }
、eval { my x = $level }
和 eval { print $level }
。
他们都用LVL_FATAL
.
但是当我使用 eval "$level"
时,我得到 1
。
另外,当我使用 eval { LVL_FATAL }
时,我也会得到 1
。
出于稳健性和性能原因,我可以使用块变体而不是字符串变体吗?
备注
记住 Perl 常量基本上是函数,我尝试了 eval ${level}()
,但是没有用; eval { $level->() }
似乎在调试器中完成了这项工作,但是当我在我的程序代码中使用它时,它并没有起作用。
(不使用 eval
时,LVL_FATAL->()
会报错("Undefined subroutine &main::1 ..."),但LVL_FATAL()
是OK的。)
以下似乎有效:
my $level = eval { my $name = "LVL_$_"; __PACKAGE__->$name() };
Constants belong to the package they are defined in. [...]
Constants may be exported by modules, and
may also be called as either class or instance methods, that is, as
Some::Package->CONSTANT
or as $obj->CONSTANT
where $obj
is an instance
of Some::Package
. Subclasses may define their own constants to
override those in their base class.
eval BLOCK
和eval EXPR
有很大的不同。
eval BLOCK
捕获块中代码抛出的异常。它在其他一些语言中被称为 try
。
eval EXPR
编译并执行EXPR
返回的字符串。 (也捕获异常。)
你想要后者。
my $level = eval("LVL_$_");
die $@ if $@;
但是由于常量可以用作子变量,所以您也可以使用
my $level = do { no strict qw( refs ); "LVL_$_"->() };
您也可以将此“子”称为方法。
my $name = "LVL_$_";
my $level = __PACKAGE__->$name();
我更喜欢倒数第二个版本,因为它很明显表明您正在做一些奇怪和危险的事情(并且它不会假装不是方法的 sub 是方法)。
我已经定义了几个 Perl 常量,例如 use constant LVL_FATAL => 1;
(perl 5.18.2)。
当试图创建一个需要名称和常量值的函数时,我尝试了:
my $level = eval { 'LVL_' . $_ };
当$_
为FATAL
时,$level
包含LVL_FATAL
,但不包含LVL_FATAL
的值。
我还尝试了变体 eval { $level }
、eval { ($level) }
、eval { my x = $level }
和 eval { print $level }
。
他们都用LVL_FATAL
.
但是当我使用 eval "$level"
时,我得到 1
。
另外,当我使用 eval { LVL_FATAL }
时,我也会得到 1
。
出于稳健性和性能原因,我可以使用块变体而不是字符串变体吗?
备注
记住 Perl 常量基本上是函数,我尝试了 eval ${level}()
,但是没有用; eval { $level->() }
似乎在调试器中完成了这项工作,但是当我在我的程序代码中使用它时,它并没有起作用。
(不使用 eval
时,LVL_FATAL->()
会报错("Undefined subroutine &main::1 ..."),但LVL_FATAL()
是OK的。)
以下似乎有效:
my $level = eval { my $name = "LVL_$_"; __PACKAGE__->$name() };
Constants belong to the package they are defined in. [...] Constants may be exported by modules, and may also be called as either class or instance methods, that is, as
Some::Package->CONSTANT
or as$obj->CONSTANT
where$obj
is an instance ofSome::Package
. Subclasses may define their own constants to override those in their base class.
eval BLOCK
和eval EXPR
有很大的不同。
eval BLOCK
捕获块中代码抛出的异常。它在其他一些语言中被称为 try
。
eval EXPR
编译并执行EXPR
返回的字符串。 (也捕获异常。)
你想要后者。
my $level = eval("LVL_$_");
die $@ if $@;
但是由于常量可以用作子变量,所以您也可以使用
my $level = do { no strict qw( refs ); "LVL_$_"->() };
您也可以将此“子”称为方法。
my $name = "LVL_$_";
my $level = __PACKAGE__->$name();
我更喜欢倒数第二个版本,因为它很明显表明您正在做一些奇怪和危险的事情(并且它不会假装不是方法的 sub 是方法)。