免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4382 | 回复: 15
打印 上一主题 下一主题

和仙子等众高手一起探讨一个问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-12-05 10:43 |显示全部楼层 |倒序浏览
our %sym = (
    name => 'hoowa',
    age  => 28,
    sex  => 'man',
);

print ${*{$::{sym}}{HASH}}{name};
会打印出 hoowa,为什么?

[ 本帖最后由 思平 于 2005-12-5 20:25 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2005-12-05 11:13 |显示全部楼层
原帖由 fayland 于 2005-12-5 11:00 发表
这个在  骆驼书 第十章 包 的符号表里有讲的。

不要这么早说出来嘛!

论坛徽章:
0
3 [报告]
发表于 2005-12-05 18:59 |显示全部楼层
不要打马虎眼,说!

论坛徽章:
0
4 [报告]
发表于 2005-12-05 20:03 |显示全部楼层
我来说说,仙子看我说的对不对:

print ${*{$::{sym}}{HASH}}{name};

%:: 等同于 %main::
也就是一个哈希表,
其中存放着
  1. '符号名称' => 指向 typeglob 的引用
复制代码

这样子的一些条目,
这个哈希表实际上就是 main 包的符号表。

因为前面 our %sym 了,所以 sym 就是个符号,可以通过
$main::{sym} 也就是 $::{sym} 来访问指向 sym 这个 typeglob 的引用
因此用 *{$::{sym}} 这种方式就可以解引用,

解引用的结果,是一个 typeglob,
而 typeglob 本身也是又是一个哈希表,
其中存放着一些
  1. '值类型' => 值引用
复制代码

这样的条目,
HASH 是这个哈希表其中的一个 key(此外还有 SCALAR 等 key,不然怎么叫类型“团”呢?)
所以用 *{$::{sym}}{HASH}  这种方式就可以取出一个指向 sym 这个 typeglob 中,HASH 分量的值,实际上也就是 \%{$::{sym}},同时也就是 \%::sym,在本例中也就是 \%sym
然后最后用解哈希表的方法就可以取出 $sym{name}
  1. ${*{$::{sym}}{HASH}{name}
复制代码

论坛徽章:
0
5 [报告]
发表于 2005-12-05 20:05 |显示全部楼层
以上我的解释过程中,有一个疑点,那就是,$main::{sym} 的类型到底是 GLOB 还是 REF of GLOB?
再或者 GLOB 和 REF of GLOB 根本就是一个类型?

论坛徽章:
0
6 [报告]
发表于 2005-12-05 20:10 |显示全部楼层
结论:Perl 5 的 GLOB 是个潜在的数据类型,不像 HASH SCALAR ARRAY CODE 等数据类型那样明显,
而它的语法,也很奇特:看上去像个 HASH,但是访问的方法又不像 HASH,我本来试图从 Perl5 语法的角度把它解释通,
但是仍然有疑点,实在不行,就只好不求甚解,
像仙子般给自己说:
  1. *pkg::sym{HASH}               # 和 \%pkg::sym 一样
复制代码

更何况这句话是 Larry Wall 本人说的,所以即使是拿来当“金科玉律”,亦并无不可。

论坛徽章:
0
7 [报告]
发表于 2005-12-05 20:15 |显示全部楼层
我感觉,GLOB 对于 LarryWall 来说,
更像是一个内部使用的数据结构/数据类型,
但是不知道怎么就给公布出来了,
因此,它看起来就怪怪的。
从一个优美的语言的角度来讲,是不应该出现这种畸形的东西的,
可惜 Perl 的目标不是优美的语言,而是“能完成任务”的语言,
于是这种怪怪的东西就越来越多……

如果我设计一种语言,一定要避免这些问题。凭心而论,这是语言的污点。

论坛徽章:
0
8 [报告]
发表于 2005-12-05 20:21 |显示全部楼层
不知道 Perl5 的哪本比较权威的书或者文档或者手册,
能够解释
  1. our %hash = ( a=>1 );
  2. my $glob = *hash;
复制代码

这个语法?
将一个 glob 赋值给一个标量,那么这个语句又是什么上下文?
等号两边的数据类型又怎么匹配?怎么解释?

作为一种语言来讲,如果需要用它的实现来解释,而不是用它的文法来解释,
那么这个语言就不是一个语言,而是一个工具。

[ 本帖最后由 思平 于 2005-12-6 10:30 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2005-12-06 10:38 |显示全部楼层
to apile 前辈:
1, apile 前辈写道
你的语法错误....
{} 回传的是一个ref to hash的引用....你把他负值给hash...是会有问题的....

非常抱歉,手误,已改正。

不过我的疑问并不是“这句话是什么意思”,因为它的意思我是知道的。
我只是想知道,这个语法,从 Perl 的角度,该如何去自圆其说。
注:Perl 里面最起码的一个规则就是,$ 表示一个量,@ 表示多个量。
$glob 经过赋值之后,到底是几个量?(答曰:一个 GLOB)
GLOB 到底是 HASH 还是 REF?

2, apile 前辈的意思是说:
$glob其实就是等於一个ref to typeglob 也可以把他看成pointer...

这个是错误的,
请看下面:
  1. print ref $glob, "\n";
  2. print ref \$glob, "\n";
复制代码

前者打印空格,而后者打印 GLOB,
由此可见,$glob 是一个 GLOB 而不是 REF of GLOB

3, 另外 apile 前辈说:
透过${$glob}可以将$glob指向hash的实际位址

也是错误的。
${$glob} 取到的并非是指向 hash 的实际地址。
而是 $glob 这个 GLOB 中,其中标量分量的值。
请看下面:
  1. our $hash = 'not_a_hash';


  2. our %hash = ( a=>1 );
  3. my $glob = *hash;
  4. print ${$glob};
  5. __END__
  6. output is 'not_a_hash'
复制代码


4, apile 前辈还说:
你就可以利用${$glob}{a}取值...

从这一点来看,$glob 更像一个 ref of hash,而不是你前面所说的 ref of typeglob
请看下面:
  1. our %hash = ( a => 1 );
  2. my $glob = \%hash;
  3. print ${$glob}{a};
  4. __END__
  5. output is '1';
复制代码

在这短短的几行之间,似乎已经自相矛盾了。

5, apile 前辈最后说:
用C的pointer可以很容易解释这些问题 ...
只是有些在C里面不合道理的.type cast问题...在perl是正确的.不需要理会type cast问题..

这个和 type cast 没关系。
C 里面需要 type cast,那是因为 C 的类型太多了(可以自定义 N 多)
Perl 里面不需要,是因为 Perl 的类型太少了。
Perl 是不允许 type cast 的,Perl 把 C 的 type cast 一部分转化成了 context,而另一部分则转化成了 syntax error.
也就是说,在 C 中,任何两个数据都是可以 type cast 的,只是结果无法保证而已。
但是在 Perl 中,一些有意义的 type cast 被理解成了“在特定上下文中的表达式计算”,而另一部分没意义的,则变成了语法错误。

[ 本帖最后由 思平 于 2005-12-6 11:05 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2005-12-06 10:43 |显示全部楼层
$string = "abc";  # $string 是标量
$ref_array = \@array; # $ref_array 还是标量,因为引用就是一个标量,
$item = $array[0]; # $item 还是一个标量,因为数组的成员肯定是标量
$value = $hash{name}; # $value 也是标量,因为哈希表的 value 是标量。

$glob = *sym;     # $glob 突然一下子就变成了 GLOB?不再是 SCALAR 了?再或者 GLOB 就像 REF 一样,本质上也是一个标量?

再声明一点:我认为,我们应该从 Perl5 语法的层面上,找到它的解释,而不是从实现的层面上。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP