免费注册 查看新帖 |

Chinaunix

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

[已解决]一个作用域的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-09-27 13:19 |只看该作者 |倒序浏览
本帖最后由 伍式南 于 2015-09-27 15:17 编辑

有两个几乎一样的程序,只在第9,10行处有区别:一个声明变量时用了my,一个没用.结果是,一个可以正常运行,一个不能

可以正常运行的代码:
  1. while (<DATA>) {
  2.   chomp;
  3.   my ($head, $all) = /^(.) (.*)$/;
  4.   
  5.   $pytable{$head} = $all;
  6. }

  7. sub getheadstr {
  8.   @str = split '', $_[0];
  9.   @res = ();
  10.   
  11.   sub loop {
  12.     my ($no, $head) = @_;
  13.    
  14.     for (split ' ', $pytable{$str[$no]}) {
  15.       if ($no == $#str) {
  16.         push @res, $head . $_;
  17.       } else {
  18.         loop($no + 1, $head . $_);
  19.       }
  20.     }
  21.   }
  22.   
  23.   loop(0, "");
  24.   
  25.   undef %count;
  26.   return join ' ', grep { ++$count{ $_ } < 2; } @res;
  27. }

  28. print getheadstr("ab") . "\n";
  29. print getheadstr("ab") . "\n";

  30. __DATA__
  31. a alpha ALPHA
  32. b beta BETA
复制代码
有问题的代码:
  1. while (<DATA>) {
  2.   chomp;
  3.   my ($head, $all) = /^(.) (.*)$/;
  4.   
  5.   $pytable{$head} = $all;
  6. }

  7. sub getheadstr {
  8.   my @str = split '', $_[0];
  9.   my @res = ();
  10.   
  11.   sub loop {
  12.     my ($no, $head) = @_;
  13.    
  14.     for (split ' ', $pytable{$str[$no]}) {
  15.       if ($no == $#str) {
  16.         push @res, $head . $_;
  17.       } else {
  18.         loop($no + 1, $head . $_);
  19.       }
  20.     }
  21.   }
  22.   
  23.   loop(0, "");
  24.   
  25.   undef %count;
  26.   return join ' ', grep { ++$count{ $_ } < 2; } @res;
  27. }

  28. print getheadstr("ab") . "\n";
  29. print getheadstr("ab") . "\n";

  30. __DATA__
  31. a alpha ALPHA
  32. b beta BETA
复制代码
它们的输出:
  1. timmy@wh1te:~/jianweizhizhuo$ perl good.pl
  2. alphabeta alphaBETA ALPHAbeta ALPHABETA
  3. alphabeta alphaBETA ALPHAbeta ALPHABETA
  4. timmy@wh1te:~/jianweizhizhuo$ perl bad.pl
  5. alphabeta alphaBETA ALPHAbeta ALPHABETA

  6. timmy@wh1te:~/jianweizhizhuo$ diff good.pl bad.pl
  7. 9,10c9,10
  8. <   @str = split '', $_[0];
  9. <   @res = ();
  10. ---
  11. >   my @str = split '', $_[0];
  12. >   my @res = ();
复制代码
"有问题的代码"中的getheadstr函数只能被调用一次,如果我再调用一次,它就会返回一个空值

我想知道,为什么会这样?

论坛徽章:
0
2 [报告]
发表于 2015-09-27 13:21 |只看该作者
这个代码的功能是排列组合,跟数学中的排列组合差不多,像123,132,213,231,312,321这样的
__DATA__里面的是排列规则,getheadstr返回所有排列的情况,用空格分割

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
3 [报告]
发表于 2015-09-27 15:07 |只看该作者
回复 1# 伍式南


    这就是不开警告的后果。

论坛徽章:
0
4 [报告]
发表于 2015-09-27 15:17 |只看该作者
回复 3# MMMIX


    哈哈 太笼统了吧
找到原因了.用my定义的变量不能被嵌套sub所使用,用local就好了.

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
5 [报告]
发表于 2015-09-27 20:46 |只看该作者
函数是不能嵌套定义的,行为非常的奇葩。sub {} 这样的函数引用才是在运行时创建的,my $loop = sub {...} ; 调用时 $loop->(参数们);

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
6 [报告]
发表于 2015-09-27 22:07 |只看该作者
Perl 变量使用前必须声明,否则会出现不可预知的后果。函数默认是包范围的,嵌套的是5.16 以后才增加的功能。你如果是 javascript 用的熟悉,在 Perl 中,可以自由的定义函数,不必隐藏在函数中,因为在 Perl 中,函数总是在命名空间范围内有效,不是全局的。

不知道为什么现在 Perl 对于新增加的功能总是报警,例如 given .. when.. values($ref) ..

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
7 [报告]
发表于 2015-09-27 22:11 |只看该作者
测试特性现在全部都警告,应该是因为之前的 given when ~~ 太失败了

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
8 [报告]
发表于 2015-09-28 01:52 |只看该作者
回复 4# 伍式南


   
用local就好了.

3 Q  ~

论坛徽章:
0
9 [报告]
发表于 2015-09-30 16:14 |只看该作者
回复 5# zhlong8


    谢谢!学习了。一直以为可以像pascal,scheme那样嵌套定义的。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
10 [报告]
发表于 2015-09-30 20:23 |只看该作者
回复 9# 伍式南


    可以嵌套定义呀,只要你了解对应的语义就行了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP