什么是 Perl 中的魔法数组?

What is a magical array in Perl?

在 Perl 中 documentation for reverse 我找到了这个:

"Note that reversing an array to itself (as in @a = reverse @a ) will preserve non-existent elements whenever possible; i.e., for non-magical arrays or for tied arrays with EXISTS and DELETE methods."

魔法阵列与非魔法阵列的区别是什么?

魔法变量是那些具有该类型的普通变量所没有的特殊功能的变量。

请参阅 Magic Variables in perlguts. See also Variable::Magic,它可以让您 "Associate user-defined magic to variables from Perl."

神奇的 数组是一种对它执行的操作不仅仅是简单地改变内容的数组。唯一有魔力的内置数组是 @ISA,而且是以一种非常不明显的方式。正如这句话所暗示的那样,一个神奇的数组主要是一个 tied 数组,参见 tie and perltie

在 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

据说这样的变量有魔力。

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([=12=])
    MG_OBJ = 0x28f9660
    MG_LEN = 1
    MG_PTR = 0x2903230 "!"

这只是魔法在核心中的众多用途之一。在 perlguts 中搜索 "The current kinds of Magic" 以获得其他一些值,包括左值 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)