免费注册 查看新帖 |

Chinaunix

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

Perl 语言缺失的语言特性 [复制链接]

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-08-21 15:12 |只看该作者 |倒序浏览
在用 Perl 编程的过程中,实际中遇到一个问题,就是遍历一个数组的数组,针对这些每条数据执行一些规则。然后把改变后的数据保存回去。

我于是做了一个深度优先的迭代器,然后写了一个获取元素位置的算法。每次获取一个位置,然后根据这个位置保存回去。
感觉这种情况让代码的复杂度增加了一层。

后来发现 Ruby 的迭代器加代码块是解决这个问题的好办法,Python 的生成器也是类似的东西。

当然 Lisp 有很多机制可以实现简化这种编程模式。

但我在 Perl 中找不到这种简化的好办法。难道是 Perl 中缺失了这个特性吗?

我原来以为设计一个传递函数的函数能解决这个办法。但定义的函数本身不能在 调用的上下文中 获取所有局部变量。

大家认为呢?

论坛徽章:
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
2 [报告]
发表于 2013-08-21 15:45 |只看该作者
@AoA = (
    [1..10],
    [11 .. 20],
);

for my $ary (@AoA) {
    for (@$ary) {
        $_ *= 2;
    }
}

矩阵每个元素 x2

是这样吗?

论坛徽章:
1
操作系统版块每日发帖之星
日期:2016-06-12 06:20:00
3 [报告]
发表于 2013-08-21 15:59 |只看该作者
本帖最后由 yakczh_cu 于 2013-08-21 16:02 编辑

  1. sub   passfunc($){

  2.   my $para=shift;
  3.   my $code=shift;
  4.    
  5.   my @out=$code->($para);
  6. }




  7. $handle = sub {
  8. my $para=shift;

  9.   @out=map { s/http/ftp/g; $_} @$para;

  10. };


  11. @data=('http://www.baidu.com','http://www.google');
  12. @out=passfunc(\@data,$handle);

  13. print join("\n",@out);
复制代码
要什么变量传进去就行了,只需要准备数据和处理单元,不用改变程序主流程

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
4 [报告]
发表于 2013-08-21 16:12 |只看该作者
本帖最后由 104359176 于 2013-08-21 16:21 编辑

回复 2# zhlong8
是这样的,但实际的数据结构是一个数组的数组,每个数组可能是一个单独的数组,也可能是数组的数组,还可能是数组的数组的数组。要实现一个统一的接口,能迭代这个复杂结构中的每个独立的数组,并且能保存回去。

@array = (

  [1, 2, 3],
  [ [4,5,6], [7,8,9],
  [ [ [ 1,2,3],[4,5,6] ], [ [7,8,9], [1,2,3]]],

);

我针对三种结构做了一个统一的迭代器 get_array();

但只能用 while 来遍历,每次处理完,用一个 set_array() 来保存数据。

get_array() 和 set_array() 必须成对使用。

如果数据结构在发生变化,迭代器的设计就非常复杂了。

有没有一个通用的模式能处理这个问题呢?

因为这个更新结构的过程,要抽象成一个函数,传递到其他的函数中。而且要留几个参数,来控制这个过程的一些行为。


   

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
5 [报告]
发表于 2013-08-21 16:15 |只看该作者
回复 3# yakczh_cu

需要在一个通用控制结构中调用这个函数,要求这个函数能继承所有可见上下文的变量,靠传递变量的方式不靠谱。


   

论坛徽章:
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
6 [报告]
发表于 2013-08-21 16:32 |只看该作者
回复 4# 104359176
  1. use strict;
  2. use warnings;

  3. sub forall {
  4.     my($sub, $sth) = @_;
  5.     for my $v (@$sth) {
  6.         if (ref $v eq 'ARRAY') {
  7.             forall($sub, $v); # 新版本5.16用 __SUB__->($sub, $v);
  8.         } else {
  9.             $v = $sub->($v);
  10.         }
  11.     }
  12. }

  13. my @array = (
  14.     [1, 2, 3],
  15.     [ [4,5,6], [7,8,9]],
  16.     [ [ [ 1,2,3],[4,5,6] ], [ [7,8,9], [1,2,3]]],
  17. );

  18. forall sub { shift() * 2 }, \@array;

  19. use Data::Dumper;
  20. say Dumper \@array;
复制代码
这算基本的递归把,如果要在运行中改变数组的大小结果可能是未定义的

论坛徽章:
6
卯兔
日期:2013-11-26 14:52:02丑牛
日期:2014-02-19 18:01:25卯兔
日期:2014-05-20 20:34:06白羊座
日期:2014-05-23 13:39:232015亚冠之大阪钢巴
日期:2015-08-07 20:57:582015亚冠之大阪钢巴
日期:2015-09-02 14:09:09
7 [报告]
发表于 2013-08-21 16:44 |只看该作者
闭包?         

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
8 [报告]
发表于 2013-08-21 19:27 |只看该作者
回复 7# 只是一个红薯
闭包是在固定的一个上下文环境中定义的代码块或函数。如果需要在动态的调用环境中使用上下文的环境,函数该如何实现呢?


   

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
9 [报告]
发表于 2013-08-21 19:32 |只看该作者
回复 6# zhlong8

这个实现了遍历数据结构,如果对遍历出的数据进行处理完后,再保存回去的话,怎么办呢?

我设计了个迭代器,有个当前的迭代状态信息,可以调用这个信息,获取当前位置的定位信息。就能保存回去了。

1维数组只需要一个状态信息,2维就需要两个了。。


   

论坛徽章:
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
10 [报告]
发表于 2013-08-21 19:34 |只看该作者
回复 9# 104359176


    这和第一个是一样的啊,就是直接修改原来的数组每一维都是
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP