如何设置$!在perl

时间:2013-03-07 23:18:54

标签: perl

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

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我想移动我不准备做的整个脚本。

3 个答案:

答案 0 :(得分:12)

$!是一个魔术变量,对应于操作系统的数字错误代码(在Unix-y errno库中为libc,其他内容如GetLastError() Windows中的kernel32.dll

您只能将其设置为数字。当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;
    }
    ...
}

但是无法使用$!创建自己的自定义错误消息。

答案 1 :(得分:3)

正如perlvar中所述,$!包含一个C errno,这是一个数字。文本Perl级错误消息显示在$@中,通常由die设置。我会建议手动设置它,尤其是因为它是一个全球性的包装。

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

答案 2 :(得分:1)

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

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

use Scalar::Util qw(dualvar) ; 
my $x = dualvar( 44, "Hello, world" );
print "string=$x,  number=" . (0+$x), "\n"

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