什么是Perl中的神奇数组?

14
在Perl的reverse函数文档中我找到了以下内容: "注意,将数组反转到它本身(例如 @a = reverse @a )将尽可能保留不存在的元素;即对于非神奇数组或存在EXISTS和DELETE方法的tied数组。" 哪些属性区分了神奇数组和非神奇数组?

@_ 数组是“神奇的”。 - serenesat
6
@_ 数组并不神奇。 - mob
3个回答

12

神奇变量是具有特殊功能的变量,普通类型的变量没有这些功能。

请参见perlguts中的神奇变量。还可以参见Variable::Magic,该模块允许您“将用户定义的魔法与Perl变量相关联”。


10
一个“神奇”的数组是指对其进行操作时,其所产生的影响不仅仅是修改其内容。唯一具有魔力的内置数组是@ISA,而它的魔力方式非常不明显。正如该句所暗示的那样,一个“神奇”的数组大多是一个“tied”数组,详见tieperltie。请注意,此处需要保留HTML标记。

@ikegami:谢谢。我没看懂mob的意思是什么。 - Borodin

3
在Perl中,变量上的操作可以触发调用代码。例如,
use Variable::Magic qw( wizard cast );

my $wiz = wizard(
   get  => sub { print "get\n" },
   set  => sub { print "set\n" },
);

cast my $x, $wiz;

$x = 1; print("$x\n");
$x = 2; print("$x\n");

输出

set
get
1
set
get
2

这些变量被称为“magic”(魔术变量)。

perlvar 中的许多变量都是魔术变量。例如,$! 使用魔法代理 errnostrerror

$ perl -E'for (1..5) { $! = $_; say $!; }'
Operation not permitted
No such file or directory
No such process
Interrupted system call
Input/output error

$ perl -MDevel::Peek -e'Dump($!)'
SV = PVMG(0x292fdf0) at 0x28f9648
  REFCNT = 1
  FLAGS = (GMG,SMG)        <--- Has get and set magic
  IV = 0
  NV = 0
  PV = 0
  MAGIC = 0x28e0f50
    MG_VIRTUAL = &PL_vtbl_sv
    MG_TYPE = PERL_MAGIC_sv(\0)
    MG_OBJ = 0x28f9660
    MG_LEN = 1
    MG_PTR = 0x2903230 "!"

这只是核心中魔法的众多用途之一。在perlguts中搜索“当前类型的魔法”,可以找到其他许多用途,包括lvalue substr

# When substr is used as an lvalue, it returns a
# magical variable that changes $s when it's changed.
substr($s, 0, 1) = "abc";

tie 函数使用魔法将类似于魔法的东西暴露给 Perl 代码。

魔法哈希和数组比魔法标量更为罕见。 %ENV 代理了 getenvputenv@ISA 具有使方法查找缓存失效的魔法。

$ perl -MDevel::Peek -e'Dump(@ISA, 0);'
SV = PVAV(0x1087e88) at 0x10a3a78
  REFCNT = 1
  FLAGS = (SMG,RMG)        <--- Has set and other magic
  MAGIC = 0x108b380
    MG_VIRTUAL = &PL_vtbl_isa
    MG_TYPE = PERL_MAGIC_isa(I)
    MG_OBJ = 0x10a3a90
  ARRAY = 0x0
  FILL = -1
  MAX = -1
  ARYLEN = 0x0
  FLAGS = (REAL)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接