免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6903 | 回复: 13

谈谈 Perl 的文件句柄和 typeglob 的关系 [复制链接]

论坛徽章:
0
发表于 2010-12-31 11:54 |显示全部楼层
本帖最后由 黑色阳光_cu 于 2010-12-31 12:18 编辑

Perl 的文件句柄本质上是保存在 typeglob 里的,当你调用 open 时,有一些奇妙的事发生了:
  1. open(FH, "<", "urfile.txt");
  2. warn *FH{IO};
复制代码
可以看到,FH 的文件句柄保存在 *FH 里,具体的是保存在 *FH{IO} 里。FH 是一个裸词,在 open 调用里,Perl 会把裸词转为对应的 typeglob,相当于
  1. open(*FH, "<", "urfile.txt");
复制代码
所以,当要传递句柄时,要把裸词形式的句柄转成对应的 typeglob 或者 typeglob 的引用:
  1. sub func
  2. {
  3.         my $fp = $_[0];
  4.         while (<$fp>)
  5.         {
  6.                 print;
  7.         }
  8. }

  9. open(FH, "<", "urfile.txt");
  10. func(\*FH);
复制代码
这样子相当不方便,后来,Perl 允许这样子的语法:
  1. open(my $fp, "<", "urfile.txt");
  2. warn $fp;
  3. while (<$fp>)
  4. {
  5.         print;
  6. }
复制代码
可以看到 $fp 就是一个 typeglob 的引用。打印 *{$fp} 时显示 *main::$fp , 但下面这个代码表明,直接用当前的 *main::$fp 却不行:
  1. open(my $fp, "<", "urfile.txt");
  2. warn *{$fp};
  3. while (<*{'main::$fp'}>)
  4. {
  5.         print;
  6. }
复制代码
再则,当 $fp 超过作用域时,文件会自动被关闭, $fp 这个句柄是词法作用域的。 看来 $fp 不简单的等同于 \*{'main::$fp'} ,那又是怎么做到的?

因为,typeglob 是一个全局的资源,为了取得词法域的效果,可以借助于 local 。open($fp, "<", "urfile.txt") 大概等同于这个写法:
  1. my $fp;
  2. {
  3.         local *{'main::$fp'};
  4.         open(*{'main::$fp'}, "<", "urfile.txt");
  5.         my $tmp = *{'main::$fp'};
  6.         $fp = \$tmp;
  7. }

  8. warn $fp;
  9. while (<$fp>)
  10. {
  11.         print;
  12. }
复制代码
注意那个 $tmp ,当 my $tmp = *{'main::$fp'} 后,$tmp 和 *{'main::$fp'} 指向同一个 typeglob 值。当超过作用域后,*{'main::$fp'} 恢复原值,则 $fp 是 $tmp 的唯一引用。所以,超过作用域后,$fp 就不简单的等同于当前的 \*{'main::$fp'} ,而当 唯一引用 $fp 也超过作用域时,文件就被自动关闭了。借助于 local ,Perl 提供了词法作用域的文件句柄。在这里,也可以看出 Perl 解决问题的智慧。

论坛徽章:
0
发表于 2010-12-31 13:43 |显示全部楼层
你知道的太多了

论坛徽章:
0
发表于 2010-12-31 13:57 |显示全部楼层
写的真不错,深刻

论坛徽章:
0
发表于 2010-12-31 14:11 |显示全部楼层
没研究过没有发言权,我只知道我相当的不看不顺眼这种打开文件的方式

最顺眼,最省事的是这种,算上空格少敲4个键,曾经还看到过一道题,问这两种方式有啥不同!出这题的人脑残!!!

open(FH, "<urfile.txt");

论坛徽章:
0
发表于 2010-12-31 15:11 |显示全部楼层
本帖最后由 tmp 于 2010-12-31 15:19 编辑

楼上, 这个区别很大, 具体我也记不清楚了

http://www.modernperlbooks.com/m ... to-modern-perl.html

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2010-12-31 15:50 |显示全部楼层
四楼装逼失败了。

论坛徽章:
0
发表于 2010-12-31 16:13 |显示全部楼层
UP

论坛徽章:
0
发表于 2010-12-31 17:39 |显示全部楼层
居然有人攻击我!

6楼的人品太差

只是写个脚本而已,对大多数人来说没必要搞清楚他们的区别

选一个简单的,自己喜欢的方式而已

论坛徽章:
0
发表于 2010-12-31 17:51 |显示全部楼层
只是写个脚本而已,对大多数人来说没必要搞清楚他们的区别


这种态度很有问题。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2010-12-31 19:27 |显示全部楼层
是你先攻击我的好不好。
那问题就是我出的,怎么脑残了?
你可以不会,你也可以不答,但你不能骂我对吧?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP