gpt4 book ai didi

Perl 作用域

转载 作者:行者123 更新时间:2023-12-04 14:02:28 24 4
gpt4 key购买 nike

根据 perldoc,String Eval 应该在当前范围内执行。但下面的简单测试似乎与此相矛盾。

我们需要以下两个简单的文件来设置测试。请将它们放在同一个文件夹下。

test_eval_scope.pm

package test_eval_scope;

use strict;
use warnings;

my %h = (a=>'b');

sub f1 {
eval 'print %h, "\n"';

# print %h, "\n"; # this would work
# my $dummy = \%h; # adding this would also work
}

1

test_eval_scope.pl

#!/usr/bin/perl

use File::Basename;
use lib dirname (__FILE__);
use test_eval_scope;

test_eval_scope::f1();

运行程序时出现如下错误

$ test_eval_scope.pl
Variable "%h" is not available at (eval 1) line 1.

我的问题是为什么变量 %h 超出范围。

我做了一些修改,发现如下:

  1. 如果我在没有 eval() 的情况下运行,就像上面的评论一样,它将起作用。这意味着 %h 应该在范围内。
  2. 如果我只是在代码中添加一个看似无用的提及,如上面评论,eval() 也可以。
  3. 如果我将 pl 和 pm 文件合并到一个文件中,eval() 也可以工作。
  4. 如果我用“我们的”而不是“我的”声明 %h,eval() 也会起作用。

我在编写一个在运行时解析用户提供的代码的大程序时遇到了这个问题。我不需要解决方案,因为上面有很多解决方法。但我无法解释为什么上面的代码不起作用。这影响了我对 perl 的自豪感。

我的 perl 版本是 linux 上的 v5.26.1。

感谢您的帮助!

最佳答案

Sub 只捕获他们使用的变量。由于 f1 不使用 %h,因此它不会捕获它,并且 %h 变得无法访问 f1 在模块完成执行后超出范围。

任何对 var 的引用,包括被优化掉的引用,都会导致 sub 捕获变量。因此,以下内容确实有效:

sub f1 {
%h if 0;
eval 'print %h, "\n"';
}

演示:

$ perl -M5.010 -we'
{
my $x = "x";
sub f { eval q{$x} }
sub g { $x if 0; eval q{$x} }
}

say "f: ", f();
say "g: ", g();
'
Variable "$x" is not available at (eval 1) line 1.
Use of uninitialized value in say at -e line 8.
f:
g: x

关于Perl 作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69559859/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com