简介
Scalar::Util 包含很多可选的、通用的、对标题进行处理的函数。其实Scalar::Util就是一个标量通用函数的工具包。
use Scalar::Util qw(blessed dualvar isdual readonly refaddr reftype
tainted weaken isweak isvstring looks_like_number
set_prototype);
# and other useful utils appearing below
引用Scalar::Util包时,默认情况下不会导入任何函数。
对引用进行操作的函数
blessed
my $pkg = blessed( $ref );
如果 $ref 是一个被 bless 过的引用,则返回它被 bless 的包的 包名。否则返回undef。
$scalar = "foo";
$class = blessed $scalar; # undef
$ref = [];
$class = blessed $ref; # undef
$obj = bless [], "Foo";
$class = blessed $obj; # "Foo"
refaddr
my $addr = refaddr( $ref );
如果$ref是引用,则引用值的内部存储器地址会作为纯整数返回。否则返回undef。
$addr = refaddr "string"; # undef
$addr = refaddr \$var; # eg 12345678
$addr = refaddr []; # eg 23456784
$obj = bless {}, "Foo";
$addr = refaddr $obj; # eg 88123488
reftype
my $type = reftype( $ref );
如果$ref 是引用,则引用的变量的基本Perl类型作为纯字符串返回(如:ARRAY或HASH)。否则返回undef。
$type = reftype "string"; # undef
$type = reftype \$var; # SCALAR
$type = reftype []; # ARRAY
$obj = bless {}, "Foo";
$type = reftype $obj; # HASH
weaken
weaken( $ref );
使用此函数对$ref进行处理后,$ref将会变成“弱引用”,这意味着它不会对引用的对象持有引用计数。此外,当该对象的引用计数达到零时,引用将被设置为undef。
此函数可以用来保持一个变量的 引用“副本”,但在原引用不存在之后,你将无法使用这个副本访问变量。
{
my $var;
$ref = \$var;
weaken($ref); # Make $ref a weak reference
}
# $ref is now undef
注意:如果你使用 “弱引用”的变量对另一个变量进行赋值,得到的新变量是一个“强引用”的变量,而非“弱引用”。
my $var;
my $foo = \$var;
weaken($foo); # Make $foo a weak reference
my $bar = $foo; # $bar is now a strong reference
在一些情况下,由“弱引用”赋值而产生“强引用”的过程是不容易被发觉的,如在grep函数中。在下面的代码中,原列表中已经销毁的“弱引用”会被删除,但所有没有被删除的元素都会变成“强引用”。
@object = grep { defined } @object;
unweaken
unweaken( $ref );
这个函数是weaken函数的逆函数。它会对一个“弱引用”进行“强化”。使用下面的代码可以达到同步的效果,但不如此函数代码整齐,并且语义清晰。
my $tmp = $REF;
undef $REF;
$REF = $tmp;
注意:把一个“弱引用”给自身赋值($ref = $ref;)并不能达到“强化”的目的。
isweak
my $weak = isweak( $ref );
如果 $ref 是一个弱引用,则返回true。否则返回false。
$ref = \$foo;
$weak = isweak($ref); # false
weaken($ref);
$weak = isweak($ref); # true
注:用一个“弱引用”给另一个变量赋值,将得到一个“强引用”。
$copy = $ref;
$weak = isweak($copy); # false
其他功能函数
dualvar
my $var = dualvar( $num, $string );
返回一个标题值,它具有$num数值上下文中的值和$string字符串上下文中的值。
$foo = dualvar 10, "Hello";
$num = $foo + 2; # 12
$str = $foo . " world"; # Hello world
isdual
my $dual = isdual( $var );
如果变量$var同时具有数字和字符串值的标量,则结果为 true,否则返回false。
$foo = dualvar 86, "Nix";
$dual = isdual($foo); # true
注:可以通过把字符串使用在数值上下文中使字符串变量成为一个 同时具有数字和字符串值的标量。同时也可以通过把数字使用在字符串上下文中使数字变量成为一个同时具有数字和字符串值的标量。
$foo = "10";
$dual = isdual($foo); # false
$bar = $foo + 0;
$dual = isdual($foo); # true
$foo = 10;
$dual = isdual($foo); # false
$bar = $foo . "";
$dual = isdual($foo); # true
注意:$! 似乎是一个双重值的变量,但它实际上是在解释器内部实现,并非一个真正的双重值变量。
$! = 1;
print("$!\n"); # "Operation not permitted"
$dual = isdual($!); # false
isvstring
my $vstring = isvstring( $var );
如果 $var 是一个被编码为 vstring的标题,则返回true;否则返回false。
$vs = v49.46.48;
$fmt = isvstring($vs) ? "%vd" : "%s"; #true
printf($fmt,$vs);
looks_like_number
my $isnum = looks_like_number( $var );
如果Perl认为$var是一个数字,则返回 true;否则返回false。
openhandle
my $fh = openhandle( $fh );
如果$fh可以作为文件句柄使用并且已经被打开,则返回$fh自身;否则返回undef。
$fh = openhandle(*STDIN); # \*STDIN
$fh = openhandle(\*STDIN); # \*STDIN
$fh = openhandle(*NOTOPEN); # undef
$fh = openhandle("scalar"); # undef
readonly
my $ro = readonly( $var );
如果 $var 是只读的则返回true;否则返回 false。
sub foo { readonly($_[0]) }
$readonly = foo($bar); # false
$readonly = foo(0); # true
set_prototype
my $code = set_prototype( $code, $prototype );
给一个$code引用设置 prototype,如果参数 $ptototype是undef 则会删除原$code引用上的 prototype。返回 $code 自身。
set_prototype \&foo, '$$';
tainted
my $t = tainted( $var );
如果$var 是 tainted 则返回true;否则返回 false。
$taint = tainted("constant"); # false
$taint = tainted($ENV{PWD}); # true if running under -T