免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 思平
打印 上一主题 下一主题

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

论坛徽章:
0
11 [报告]
发表于 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
12 [报告]
发表于 2005-12-05 20:05 |只看该作者
以上我的解释过程中,有一个疑点,那就是,$main::{sym} 的类型到底是 GLOB 还是 REF of GLOB?
再或者 GLOB 和 REF of GLOB 根本就是一个类型?

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

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

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

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

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

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

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

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

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
16 [报告]
发表于 2005-12-06 08:36 |只看该作者

  1. #!/usr/bin/perl

  2. our %hash = ( a=>1);
  3. my $glob = *hash;
  4. print ${$glob}{a}."\n";
复制代码

你的语法错误....
{} 回传的是一个ref to hash的引用....你把他负值给hash...是会有问题的....
$glob其实就是等於一个ref to typeglob 也可以把他看成pointer...
透过${$glob}可以将$glob指向hash的实际位址,然後
你就可以利用${$glob}{a}取值...
用C的pointer可以很容易解释这些问题 ...
只是有些在C里面不合道理的.type cast问题...在perl是正确的.不需要理会type cast问题....

论坛徽章:
0
17 [报告]
发表于 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
18 [报告]
发表于 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 语法的层面上,找到它的解释,而不是从实现的层面上。

论坛徽章:
0
19 [报告]
发表于 2005-12-06 10:48 |只看该作者
本回复已被合并。

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

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
20 [报告]
发表于 2005-12-06 11:42 |只看该作者
啪啪...你不错喔...很有研究精神...

我不大管compile的内部运作,
也没有兴趣管那麽多....或许你该去问Larry本人...

就我的理解perl里面都是reference....也可以看成位址....
$a="aa" 实际是先存aa的位址...然後在某个地方有个hash会存一笔..

key=a value=address of "aa"; 还有type是SCALAR....

然後你可以透过$a取出来....@(ARRAY),%(HASH)同理....
但是如果address of "aa"存的内容跟@,%,$取值型态不同...
或许应该说找不到一个key是a且type是ARRAY或HASH的数据可以取用,
此时perl会给你一个null值....

address of aa所指向的memory,可以存的是另一个address of data....
例如:
aa->address of "aa"  type : SCALAR-->"aa"

aa->address of 'address of "aa"' type : REF--->address of "aa" type:SCALAR -->"aa"

至於type glob...是个特例..他可以ref到各种变量包括filehandle,@,$,%..他只是一个reference到不定address(或类似pointer的东西)..
至於address里面放什麽数据...没有限制..也就是上面例子中..他可以动态reference到第一层address的地方...

你爱用什麽方式就用什麽方式取出来...只是取错型态了(@,$,%,filehandle)
perl就给你一个空的值...你如果前面用$glob他就会先指向hash里面key是$glob的位址..看看里面的数值....

从C pointer的角度去看这个问题...会比较容易理解...

建议你可以看看advance perl programming里面有段在写type glob的问题...



好啦..不想争辩啦!!
没事可以多画画图..习惯C的用法(pointer to pointer)..
然後再想一下如果你是Larry..你要作没有int,float,double这些型态的宣告
你要怎麽作?

然後再回头来看这个问题会比较容易..

[ 本帖最后由 apile 于 2005-12-6 14:56 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP