微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

perl – (4 sub)不等于(sub 4)?

(编辑)TL; DR:我的问题是我虽然Win32 API定义的是真正的整数常量(如在平台SDK头文件中),而Win32 Perl包装器将它们定义为subs.因此导致单线解析被误解.

在单行调用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)…

解决方法

B ::拯救:
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.

在我看来,只有第一个是透明的,而其他的有点模糊.

原文地址:https://www.jb51.cc/Perl/171772.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐