Category: Modules Keywords: scalar list
Util 是 Utility 的缩写,意为有用的工具。
此三模块以前看过但没用过,昨晚在 Perl Best Practices 里听 Damain Conway 又提及。觉得用处挺大的,就简单翻译下用途。需要的参阅 perldoc, 此三模块在 5.8 后为标准模块,安装 Perl 后就有了。
Scalar::Util
blessed $scalar
如果 $scalar 是一个对象的引用,则返回这个对象的类的名字,否则返回 undefrefaddr $scalar
如果 $scalar 是一个引用,则返回一个数字代表该引用的所指向的内存地址,否则返回 undef这个可以对两个变量是否同一提供判断。
reftype $scalar
如果 $scalar 是一个引用,则返回相应的类型值(如 'SCALAR', 'HASH', 'ARRAY', 'CODE', 'Regexp'),否则返回 undefreadonly $scalar
如果 $scalar 只读返回真openhandle $scalar
如果不是一个文件句柄或着该文件句柄没有开着的话,返回 undefuse Scalar::Util qw/openhandle/; open(FH, 'nonexist'); print openhandle(*FH); # 返回 undef open(FILE, 'exist'); print openhandle(*FILE); # 返回如 GLOB(0x162538c) close(FILE); print openhandle(*FILE); # 返回 undef
weaken $scalar/is_weak $scalar
使用这个对防止循环数据结构的内存泄露有帮助。详细参阅该书和 perldocdualvar NUM, STRING
设置一个变量在数字环境和字符串环境下返回不同的值。$foo = dualvar 10, "Hello"; $num = $foo + 2; # 12 $str = $foo . " world"; # Hello world
looks_like_number, set_prototype etc.
参阅书籍或 perldoc Scalar::UtilList::Util
first { <condition> } @list
返回 @list 中满足该 condition 的第一个元素。该函数与 grep 有点类似,但它是搜寻到第一个匹配时就停止了,而 grep 要搜索完整个 @list
max/min @list
返回数组中用 >/< 号比较后的最大最小值maxstr/minstr @list
返回数组中用 gt/lt 比较后的最大最小值shuffle @list
象 ipod shuffle 一样,随机在 @list 挑一个元素sum @list
对整个 @list 求和,然后返回值reduce BLOCK LIST
这个其实挺有用的。上面的这些 max, min, first, sum 等都可以用 reduce 来操作。该函数首先将 LIST 中的第一和第二个元素赋予 $a 和 $b (与 sort 有点类似),然后执行 BLOCK, 将其返回值赋予 $a, 然后取第三个元素赋予 $b, 再执行 BLOCK, 就这样多次执行,然后返回值。
$foo = reduce { $a < $b ? $a : $b } 1..10; # 这句与 min 1..10 一样效果
$foo = reduce { defined($a) ? $a : defined($b) ? $b : undef } undef, @list; # 这句效果与 $foo = first { defined($_) } @list 同
my $overall_probablity = reduce { $a * $b } @partial_probabilities; # 将列表中的所有元素相乘
List::MoreUtils
all/any/notall/none { <condition> } @list
# @list 中有任意一个元素有定义
print "At least one value undefined" if any { !defined($_) } @list;
# @list 中所有的元素都有定义
print "All items defined" if all { defined($_) } @list;
# @list 中没有元素被定义,它是 any 的反义
print "No value defined" if none { defined($_) } @list;
# @list 中至少有一个元素没定义,它是 all 的反义
print "Not all values defined" if notall { defined($_) } @list;
first_index { <condition> } @list
返回第一个满足条件的列表索引号。last_index 返回最后一个满足的索引号。没有找到满足的都返回 -1
my @list = (1, 4, 3, 2, 4, 6);
printf "item with index %i in list is 4", firstidx { $_ == 4 } @list;
__END__
item with index 1 in list is 4
apply { <transform> } @list
对于每个 @list 中的元素执行 transform, 然后在列表环境下返回改变后的列表,在标量环境下返回最后一个值。它与 map 有点类似,但是 apply 不改变原来 @list 的值。
my @list = (1 .. 4);
my @mult = apply { $_ *= 2 } @list;
print "\@list = @list\n";
print "\@mult = @mult\n";
__END__
@list = 1 2 3 4
@mult = 2 4 6 8
my @nice_words = apply { s/$EXPLETIVE/[DELETED]/gxms } @words;
# 这面的这句如果用 map 写的话
my @nice_words
= map {
my $copy = $_;
$copy =~ s/$EXPLETIVE/[DELETED]/gxms;
$copy;
} @words;
after/before BLOCK LIST
返回满足 BLOCK 后面或前面的列表元素。如@x = after { $_ % 5 == 0 } (1..9); # returns 6, 7, 8, 9
而 after_incl/before_incl 也包括满足 BLOCK 的元素,如上面就会多一个 5
pairwise BLOCK ARRAY1 ARRAY2
将 ARRAY1 与 ARRAY2 对应平行的元素(设置成 $a 和 $b)做 BLOCK 后返回。如@a = (1 .. 5);
@b = (11 .. 15);
@x = pairwise { $a + $b } @a, @b; # returns 12, 14, 16, 18, 20
# mesh with pairwise
@a = qw/a b c/;
@b = qw/1 2 3/;
@x = pairwise { ($a, $b) } @a, @b; # returns a, 1, b, 2, c, 3
如果数组元素个数不同的话,自己试验下。
注意这里的 $a 和 $b 是绑定数组元素,所以如果对 $a/$b 进行更改的话会对应修改数组。
zip/mesh @array1, @array2, ...
跟 Perl 6 中一样。不同数组依次取一个,然后循环。@x = qw/a b c d/; @y = qw/1 2 3 4/; @z = zip @x, @y; # returns a, 1, b, 2, c, 3, d, 4
uniq @list
uniq 是 unique 的缩写,独一无二的。my @x = uniq 1, 1, 2, 2, 3, 5, 3, 4; # returns 1 2 3 5 4 my $x = uniq 1, 1, 2, 2, 3, 5, 3, 4; # returns 5 不同的个数
Others
- insert_after BLOCK VALUE LIST / 在满足 BLOCK 的列表元素后插入 VALUE
- insert_after_string STRING VALUE LIST / 在等于 STRING 的列表元素后插入 VALUE
- indexes BLOCK LIST / 与 first_index 不同,它返回一个由所有的索引号组成的列表
不想写太多了。详细的查阅文档。其实不是 Perl 不够强大,只是你没发现而已。