在适当位置修改输入的Perl运算符



我最近进行了一次Perl测试,其中一个问题是找到所有可以用来修改其输入的Perl操作。选项是

  • sort
  • map
  • do
  • grep
  • eval

我认为这些都不能修改现有的输入。我是遗漏了什么,还是问题错了?

试试这个:

my @array = qw(1 2 3 4);
print "@arrayn";
my @new_array = map ++$_, @array;
print "@new_arrayn";
print "@arrayn";  # oops, we modified this in-place

CCD_ 6也是类似的。对于sort$a$b变量是原始数组的别名,因此也可以用来修改它。结果有些不可预测,这取决于Perl使用的排序算法(在不同版本的Perl中,排序算法在历史上发生了变化,但有一段时间没有变化)。

my @arr = qw(1 2 3 4 5);
my @new = sort { ++$a } @arr;
print "@arrn";

doeval可以采用任意的代码块,因此显然可以修改任何非只读变量,尽管尚不清楚这是否算作修改输入。Slade的例子使用了字符串形式的eval,这当然值得一提。

我假设问题是测试学生是否知道正确使用sortmap等的返回值,而不是在void上下文中使用它们并预期副作用。不过,完全可以修改给定的参数。

mapgrep$_别名为每个元素,因此修改$_将更改传递给它的列表中变量的值(假设它们不是常量或文字)。

eval EXPRdo EXPR或多或少可以做任何事情,所以没有什么可以阻止你做这样的事情:

my $code = q($code = 'modified');
eval $code;
say $code;

do BLOCKeval BLOCK的自变量始终是一个文本代码块,据我所知,它们都不是有效的lvalue。

CCD_ 23在调用时与CCD_ 24一样具有特殊的优化。如果您使用B::Concise查看由此生成的操作码,您将看到类似于:的内容

9  <@> sort lK/INPLACE,NUM

但对于语言语义的问题,实现细节是无关紧要的。

最新更新