加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl6 – 如何将类方法作为参数传递给perl 6中的另一个类方法

发布时间:2020-12-15 23:22:54 所属栏目:大数据 来源:网络整理
导读:我有一个如下的脚本.意图是使用不同的过滤方法来过滤列表. 这是代码. 2 3 class list_filter { 4 has @.my_list = (1..20); 5 6 method filter($l) { return True; } 7 8 # filter method 9 method filter_lt_10($l) { 10 if ($l 10) { return False; } 11 r
我有一个如下的脚本.意图是使用不同的过滤方法来过滤列表.

这是代码.

2 
  3 class list_filter {
  4   has @.my_list = (1..20);
  5 
  6   method filter($l) { return True; }
  7 
  8   # filter method
  9   method filter_lt_10($l) {
 10     if ($l > 10) { return False; }
 11     return True;
 12   }
 13 
 14   # filter method
 15   method filter_gt_10($l) {
 16     if ($l < 10) { return False; }
 17     return True;
 18   }
 19 
 20   # expecting a list of (1..10) to be the output here
 21   method get_filtered_list_lt_10() {
 22     return self.get_filtered_list(&{self.filter_lt_10});
 23   }
 24 
 25   # private
 26   method get_filtered_list(&filter_method) {
 27     my @newlist = ();
 28     for @.my_list -> $l {
 29       if (&filter_method($l)) { push(@newlist,$l); }
 30     }
 31     return @newlist;
 32   }
 33 }
 34 
 35 my $listobj = list_filter.new();
 36 
 37 my @outlist = $listobj.get_filtered_list_lt_10();
 38 say @outlist;

期待[1..10]成为这里的输出.但得到以下错误.

Too few positionals passed; expected 2 arguments but got 1

  in method filter_lt_10 at ./b.pl6 line 9
  in method get_filtered_list_lt_10 at ./b.pl6 line 22
  in block <unit> at ./b.pl6 line 37

我在这做错了什么?

解决方法

在Perl 6中将方法作为参数传递要么需要使用MOP(元对象协议)方法,要么按名称传递方法(然后在运行时为您执行查找).

但是,如果你没有真正对这些方法中的对象做某事,为什么要使用方法呢?它们也可能是潜艇,你可以作为参数传递.

也许这是最好的例子:

class list_filter {
    has @.my_list = 1..20;  # don't need parentheses

    sub filter($--> True) { } # don't need code,signature is enough

    # filter sub
    sub filter_lt_10($l) { not $l > 10 }

    # filter sub
    sub filter_gt_10($l) { not $l < 10 }

    # private
    method !get_filtered_list(&filter_sub) {
        @.my_list.grep(&filter_sub);
    }

    # expecting a list of (1..10) to be the output here
    method get_filtered_list_lt_10() {
        self!get_filtered_list(&filter_lt_10);
    }
}

my $listobj = list_filter.new();
my @outlist = $listobj.get_filtered_list_lt_10();
say @outlist; # [1 2 3 4 5 6 7 8 9 10]

第一个子过滤器只返回一个常量值(在本例中为True),可以在具有空体的签名中更容易地表示.

filter_lt_10和filter_gt_10 subs只需要否定条件,因此使用not.

get_filtered_list方法应该是私有的,所以通过前缀来使它成为私有方法!

在get_filtered_list_lt_10中,您现在需要使用!调用get_filtered_list!而不是..而你通过前缀&传递filter_lt_10子作为参数. (否则它将被视为对没有任何参数的sub的调用,这将失败).

更改get_filtered_list以使用内置的grep方法:这需要一个Callable块,它接受一个参数,并返回一些True,以包含它所处理的列表的值.由于采用单个参数的子是Callable,我们可以直接指定子.

希望这是有道理的.我试图尽可能接近预期的语义.

一些一般的编程说法:我觉得潜艇的命名令人困惑:我觉得它们应该被称为filter_le_10和filter_ge_10,因为这正是他们所做的事情.另外,如果你真的不想要任何特别的过滤,而只是从一组特定的预定义过滤器中过滤,你可能会更好的方法是使用常量或枚举创建一个调度表,并使用它来指示你的哪个过滤器想要而不是用另一种方法来制作和维护这些信息.

希望这可以帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读