在单行调用Win32 :: MsgBox的测试中,我对以下内容感到困惑:给出MsgBox可能的参数是消息,一组标志来选择按钮的类型(值0..5)和消息框图标“常量”(MB_ICONSTOP,…)和标题
调用perl -MWin32 -e“Win32 :: MsgBox world,4 MB_ICONQUESTION,hello”给出了预期的结果
而看起来类似的代码perl -MWin32 -e“Win32 :: MsgBox世界,MB_ICONQUESTION 4,你好”是错误的
我首先虽然它来自我缺少括号,但添加一些perl -MWin32 -e“Win32 :: MsgBox(world,hello)”给出了完全相同的错误结果.
我尝试与同事深入挖掘并显示传递给函数调用的参数(因为MB_xxx常量实际上是子函数),使用以下代码
>perl -Mstrict -w -e"sub T{print $/,'called T(#'.join(',',@_).'#)'; 42 }; print $/,'results:',join ',T(1),T+1,1+T"
那个输出
called T(#1#) called T(##) called T(#1,43#) results:42,42
但我无法理解为什么在传递给join()的列表中,args T 1,1 T被解析为T(1,43)…
解决方法
C:>perl -MO=Deparse -MWin32 -e"Win32::MsgBox world,MB_ICONQUETION+4,hello" use Win32; Win32::MsgBox('world',MB_ICONQUESTION(4,'hello')); -e Syntax OK C:>perl -MO=Deparse -MWin32 -e"Win32::MsgBox world,4+MB_ICONQESTION,4 + MB_ICONQUESTION(),'hello'); -e Syntax OK
第一种情况下的MB_ICONQUESTION调用被认为是带有参数4,’hello’的函数调用.在第二种情况下,它被认为是一个没有参数的函数调用,并添加了4.它似乎不是一个常数,而是一个功能.
在源代码中,我们得到了验证:
sub MB_ICONQUESTION { 0x00000020 }
它是一个返回32的函数(00100000二进制,表示有一个位被设置).另外当Sobrique指出时,这是一个标志变量,所以你不应该使用加法,而是使用按位逻辑和/或运算符.
在您的情况下,它只接受任何参数并忽略它们.如果你期望一个常数,这有点令人困惑.
在您的实验案例中,声明
print $/,1+T
是解释
print $/,T(+1,(1+T))
因为从右到左执行
1+T = 43 T +1,43 = 42 T(1) = 42
因为加上precedence比逗号更高,而且一元甚至更高.
要消除歧义,您需要使用括号来阐明优先级:
print $/,T()+1,1+T # ^^-- parentheses
作为一般规则,应始终使用带有子程序调用的括号.在perldoc perlsub
有4个呼号:
NAME(LIST); # & is optional with parentheses. NAME LIST; # Parentheses optional if predeclared/imported. &NAME(LIST); # Circumvent prototypes. &NAME; # Makes current @_ visible to called subroutine.
在我看来,只有第一个是透明的,而其他的有点模糊.