3

我想用 perl 写一些函数来设置 $! 以类似于内置 perl 函数的方式。当我尝试这样做时,它抱怨“参数“无法创建管理员用户”在标量赋值中不是数字”。我试过用谷歌搜索,但不幸的是谷歌不会在 $ 上观看!所以很难得到结果。

if(!createUser('admin')) { print $!; }

sub createUser
{
  my ($user) = @_;
  if($user eq "admin")
  {
    $! = "Cannot create admin user";
    return 0;
  }
  #create user here
  return 1;
}

PS。我知道 Try::Tiny 等,但我想与脚本的其余部分保持一致,如果我切换到 try/catch,我想移动我还没有准备好的整个脚本。

4

3 回答 3

12

$!是一个魔法变量,对应于操作系统的数字错误代码(errno在 Unix-ylibc库中,GetLastError()kernel32.dllWindows 中类似)。

您只能将其设置为一个数字。当 Perl 想在字符串上下文中使用它时,它会将其转换为适当的文本错误消息。

例子:

$! = 4;
print $!, "\n";
print 0+$!, "\n";

产生(无论如何在我的系统上):

Interrupted system call
4

$!设置为与系统上的某些标准错误相对应是完全合适的(如果不可移植,因为不同的系统可以自由使用不同的整数值来表示标准错误代码) :

sub my_do_something_with_file {
    my $file = shift;
    if (! -f $file) {
        $! = 2; # "No such file or directory" on my system
        return;
    }
    ...
}

但是没有工具可以创建您自己的自定义错误消息以与$!.

于 2013-03-07T23:24:30.587 回答
3

perlvar中所述,$!包含一个 C errno,它是一个数字。文本的 Perl 级别错误消息出现在 中$@通常由 设置die。我建议手动设置它,尤其是因为它是一个全局转包。

Try::Tiny如果那是你需要的,就使用它。如果脚本的其余部分写得不好,那么与它保持一致不会有太多收获。

于 2013-03-07T23:22:34.897 回答
1

你可以设置$!到恰好匹配 C errno 值并设置预期字符串值的数值。不幸的是,这不是很便携。

如果 $! 不是一个神奇的变量,您可以使用 dualvar() 分配一个双重数字/字符串值,这在 Scalar::Util 中可用,它是一个核心包。

使用 Scalar::Util qw(dualvar) ;
我的 $x = dualvar( 44, "Hello, world" );
打印 "string=$x, number=" 。(0+$x), "\n"

但是用美元!只有这个数字在我之前的尝试中幸存下来。

于 2013-03-07T23:40:15.640 回答