免费注册 查看新帖 |

Chinaunix

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

奇怪的参数检查 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-06-05 10:00 |只看该作者 |倒序浏览
我写了一个2000行以上的.pm库文件和100多行的.pl接口文件管理配置文件。在pm库文件中有一个函数在定义之前使用时函数工作不太正常。

在b.pl运行时没有发现任何警告,也不提示输入参数错误。大家能告诉我原因么?

文件结构如下:
  1. a.pm
  2. use strict;
  3. use warnings;
  4. use Data::Dumper;

  5. sub f()
  6. {
  7. my @arr = ();
  8. g(@arr);
  9. print Dumper(@arr);
  10. }

  11. sub ff()
  12. {
  13. my @arr = ();
  14. g(\@arr);
  15. print Dumper(@arr);
  16. }

  17. sub g(\@)
  18. {
  19. my $arr = shift;

  20. push @{$arr}, 12;
  21. }

  22. sub gf()
  23. {
  24. my @arr = ();
  25. g(@arr);
  26. print Dumper(@arr);
  27. }

  28. sub gff()
  29. {
  30. my @arr = ();
  31. g (\@arr); # 报错
  32. print Dumper(@arr);
  33. }
  34. 1;

  35. b.pl:
  36. use strict;
  37. use warnings;
  38. use a;

  39. f(); #无输出
  40. ff(); #输出12
  41. gf(); #输出12
  42. gff(); #编译错误
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2010-06-05 11:49 |只看该作者
g 用了原型,
所以调用时直接 g(@arr) 即可,
不需要也不能 g(\@arr)。

论坛徽章:
0
3 [报告]
发表于 2010-06-05 11:55 |只看该作者
回复 2# flw
谢谢回复

现在最大的问题是ff()为什么检查不出来?而且还工作正常的样子?

是因为没有原型的时候需要必须自己处理引用的转换么?

有没有文档专门说明这种问题?

论坛徽章:
0
4 [报告]
发表于 2010-06-05 13:02 |只看该作者

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
5 [报告]
发表于 2010-06-05 13:17 |只看该作者
因为 ff 还没见到原型。

论坛徽章:
0
6 [报告]
发表于 2010-06-05 17:26 |只看该作者
回复 4# 黑色阳光_cu
多谢

问题已解决。

函数原型不是强制的,在一些特定情况下函数会被当作旧格式的函数。如果
函数被当作无原型的旧函数时,函数请求的输入参数是引用,这就可以
解释我的函数为什么出错了。

再次感谢两位的帮助。

BTW:有没有什么方法彻底禁用无原型的旧格式的函数的使用?至少报出一个
警告?我觉得如果老是出这种问题的话,调试起来相当些麻烦,而且很难找到
出错原因

论坛徽章:
0
7 [报告]
发表于 2010-06-05 18:07 |只看该作者
回复  黑色阳光_cu
多谢

问题已解决。

函数原型不是强制的,在一些特定情况下函数会被当作旧格式的 ...
feiliang1983 发表于 2010-06-05 17:26



   
把参数原型提前说明

use strict;
use warnings;
use Data::Dumper;

sub g(\@);        # here

sub f()
{
my @arr = ();
g(@arr);
print Dumper(@arr);
}

sub ff()
{
my @arr = ();
g(\@arr);
print Dumper(@arr);
}

sub g(\@)
{
my $arr = shift;

push @{$arr}, 12;
}

sub gf()
{
my @arr = ();
g(@arr);
print Dumper(@arr);
}

sub gff()
{
my @arr = ();
g (\@arr); # 报错
print Dumper(@arr);
}

f(); #无输出
ff(); #输出12
gf(); #输出12
gff(); #编译错误

论坛徽章:
0
8 [报告]
发表于 2010-06-05 18:32 |只看该作者
本帖最后由 黑色阳光_cu 于 2010-06-05 18:39 编辑

更奇怪的是用prototype("inner")检查原型

  1. use strict;
  2. use warnings;

  3. # sub inner(\@);

  4. sub outer()
  5. {
  6.         my $prototype = prototype("inner");
  7.         if (defined $prototype)
  8.         {
  9.                 print "Subrounte inner's prototype is: $prototype\n";
  10.         }

  11.         inner();
  12. }

  13. sub inner(\@)
  14. {
  15.         ;
  16. }

  17. outer();
复制代码
明明可以检查到原型是\@了,但下面的inner()不工作,一定要把原型声明前置。结论就是prototype少用为妙

论坛徽章:
0
9 [报告]
发表于 2010-06-05 18:49 |只看该作者
本帖最后由 黑色阳光_cu 于 2010-06-05 19:05 编辑

而且用&调用函数不会被检查原型~~~


http://www.perl.com/language/misc/fmproto.html#Prototype_Bugs
  1. use strict;
  2. use warnings;

  3. BEGIN
  4. {
  5.         warn prototype("proc");
  6. }

  7. sub proc(\@)
  8. {
  9.         print "proc\n";
  10. }
复制代码

  1. use strict;
  2. use warnings;

  3. sub proc(\@)
  4. {
  5.         print "proc\n";
  6. }

  7. BEGIN
  8. {
  9.         warn prototype("proc");
  10. }



复制代码

论坛徽章:
0
10 [报告]
发表于 2010-06-07 12:01 |只看该作者
回复 9# 黑色阳光_cu

看了一下,感觉perl的原型系统基本不靠谱。

如果是写一堆功能单一的小文件还可以保证声明放在文件头上;对于一个罗列了一堆小函数
而且需要经常添加新函数的大文件声明基本无效。开始的时候接口数目不多,所有函数堆在
一个文件了

再次感谢各位前辈
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP