我最近进行了一次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";
do
和eval
可以采用任意的代码块,因此显然可以修改任何非只读变量,尽管尚不清楚这是否算作修改输入。Slade的例子使用了字符串形式的eval
,这当然值得一提。
我假设问题是测试学生是否知道正确使用sort
、map
等的返回值,而不是在void上下文中使用它们并预期副作用。不过,完全可以修改给定的参数。
map
和grep
将$_
别名为每个元素,因此修改$_
将更改传递给它的列表中变量的值(假设它们不是常量或文字)。
eval EXPR
和do EXPR
或多或少可以做任何事情,所以没有什么可以阻止你做这样的事情:
my $code = q($code = 'modified');
eval $code;
say $code;
do BLOCK
和eval BLOCK
的自变量始终是一个文本代码块,据我所知,它们都不是有效的lvalue。
CCD_ 23在调用时与CCD_ 24一样具有特殊的优化。如果您使用B::Concise查看由此生成的操作码,您将看到类似于:的内容
9 <@> sort lK/INPLACE,NUM
但对于语言语义的问题,实现细节是无关紧要的。