请教scalar原理

请教scalar原理

$array_length = scalar(@array);
$time = scalar(localtime(time)); # !!!

localtime返回的是数组,scalar何以如此智能返回时间的自然语言表达形式??!!

另,? = scalar(%hash);


QUOTE:
原帖由 hgneng 于 2007-1-6 20:31 发表
$array_length = scalar(@array);
$time = scalar(localtime(time)); # !!!

localtime返回的是数组,scalar何以如此智能返回时间的自然语言表达形式??!!

另,? = scalar(%hash);

多数Perl表达式都有上下文的概念,在不同的上下文环境里,表达式返回值不同.
@array在标量上下文里,返回值是该数组的长度.
localtime同样,标量返回值是个可读的时间串.
scalar %hash的结果是该hash的长度.


QUOTE:
原帖由 shhgs 于 2007-1-6 21:57 发表
scalar %hash的结果应该不是hash的长度.

这是Perl的魔术,也是Larry觉得好,但是没有强迫Perler也觉得好的东西。

Oh,这里确实不是,偶想当然的.
scalar %hash是什么东东,谁来回答下?
"已使用的buckets/已分配的buckets", buckets是指开链实现的hash的key/value项。
摘自:http://community.csdn.net/Expert/TopicView3.asp?id=4689149
回复人:logo0775(suteki da ne) ( 一级(初级)) 信誉:100         2006-4-20 11:37:00         得分:0        

$c=qw("a" "b" "c");
$c为列表最后一个元素,perl 就是这么定义的, 列表不是数组。如果$c=@array,那么$c就是@array的元素个数,这个和 perl 的上下文有关.


If you evaluate a hash in scalar context, it returns false if the hash is empty. If there are any key/value pairs, it returns true; more precisely, the value returned is a string consisting of the number of used buckets and the number of allocated buckets, separated by a slash. This is pretty much useful only to find out whether Perl's internal hashing algorithm is performing poorly on your data set. For example, you stick 10,000 things in a hash, but evaluating %HASH in scalar context reveals "1/16" , which means only one out of sixteen buckets has been touched, and presumably contains all 10,000 of your items. This isn't supposed to happen. hash, scalar context hash, bucket bucket

You can preallocate space for a hash by assigning to the keys() function. This rounds up the allocated buckets to the next power of two:

keys(%users) = 1000; # allocate 1024 buckets



这也是 perl 中一个特殊的地方,在标量上下文中,perl 对数组和哈希表( Hash )的理解是不同的,如果等号右边的是数组,那么等号左边的标量值就是数组的元素个数,而如果等号右边是哈希表,那么等号左边的标量得到的返回值是一个字符串(如你例中得到的"2/8"),结合你的例子解释一下:

%hash=(US=>01,CH=>02);
$b=%hash;



由于 %hash=(US=>01,CH=>02); 中键值对的个数为2,没有超过 7个,而 perl 默认为每个哈希表分配8个元素空间(8个空间并不是全部可用,最后一个估计在 perl 的哈希表结构中用做它用),所以 $b=%hash 返回 2/8,意思是使当前 %hash 中8个元素空间中的两个已经被使用了
当然,%hash 的容量是可以动态增长的,你可以试试给 %hash 赋超过7个,再赋值给标量然后打印试试,你会发现返回的字符串变成了 7/16 呵呵,这个是和 perl 的哈希表结构以及哈希表动态增长的算法相关的,如果你想返回哈希表中键值对的个数, 可以
$b=keys %hash;
print $b;


QUOTE:
$ perl -e '%hash=(1,11,2,22,3,33,4,44,5,55,6,66,7,77);foreach(sort keys %hash){printf $hash{$_}."\n";};print $b=%hash'
11
22
33
44
55
66
77
6/8

这个hash中有7个键值对,怎么最后显示是6/8,而不是7/8?
我这里也很奇怪,觉得显示不正常,不知道为什么