我最近一直在玩对 Code Golf 和编码挑战堆栈上的限制源代码挑战问题的 Perl 答案,并且很困惑为什么我希望工作的一些代码不起作用。
我的示例是尝试在使用
-p0513
调用时从脚本获取输出,但效果是等效的:
*_=\"this works!";
print; # outputs `this works!`
*\=\"this doesn't work :(";
print; # outputs `this works!` without `$\`
print$\; # outputs `this doesn't work :(`
我想知道为什么将
*\
设置为标量参考 (\"..."
) 会导致 $\
在 print
之后不正确地 $_
,当自然设置它时(例如 $\="test"
)会这样做。 $_
以相同方式设置(例如 *_=\"test"
)似乎不受影响。
我想知道是否有 Perl 专家知道为什么会发生这种情况,以及是否有办法可以使用
*\=\"..."
(给我留下一个免费的 _
来尝试获得第七个输出机制!)
如果我理解正确的话,你是在问为什么
perl -e'local *\ = \"!\n"; print "";'
不输出任何内容
perl -e'local $\ = "!\n"; print "";'
输出
!␊
。
首先,我们来看看
*x = \$y;
的作用。
*x
是一个 typeglob,简称 glob。这是一个符号表条目。它是一个包含许多指针的结构。一个指向标量,一个指向数组,一个指向哈希,一个指向子,等等
缺少名为
my
的词汇(
our
或
$x
)
$x
相当于
${ *x{SCALAR} }
这意味着它访问名为
x
的 glob 的标量槽所指向的标量。
*x = \$y;
将标量设置为 $y
,使这些等价:
$x
${ *x{SCALAR} }
$y
如果
local *\ = \"!\n";
使 $\
等价于包含 "!\n"
的标量,为什么程序不输出 !␊
?
嗯,肯定是print不使用
$\
。事实确实如此。
通常,
$\
是一个神奇的变量。[1]设置它会导致设置一个内部变量。读取它会导致读取内部变量。这个内部变量就是 print
使用的。
您用文字常量替换了神奇变量,并保持内部变量不变。因此
print
的输出保持不变。
$ perl -MDevel::Peek -e'Dump($\)'
SV = PVMG(0x55e7a72d00e0) at 0x55e7a728c2d0
REFCNT = 1
FLAGS = (GMG,SMG) <-- Scalar has get magic & set magic
IV = 0
NV = 0
PV = 0
MAGIC = 0x55e7a729da30
MG_VIRTUAL = &PL_vtbl_sv
MG_TYPE = PERL_MAGIC_sv(\0)
MG_OBJ = 0x55e7a728c240
MG_LEN = 1
MG_PTR = 0x55e7a72c4170 "\\"