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

语法 – Perl 6是否应该能够解释来自不同来源的相同角色的包含?

发布时间:2020-12-15 21:52:29 所属栏目:大数据 来源:网络整理
导读:想象一下代表角色的一系列复杂语法,尽管这个简单的例子足以显示冲突: role Alpha { token alpha { :i [A..Z] } }role Digit { token digit { [0..9] } }role Either does Alpha does Digit { token either { alpha | digit } }grammar Thingy does Either d
想象一下代表角色的一系列复杂语法,尽管这个简单的例子足以显示冲突:
role Alpha {
    token alpha { :i <[A..Z]> }
    }

role Digit {
    token digit { <[0..9]> }
    }

role Either
    does Alpha
    does Digit {
    token either { <alpha> | <digit> }
    }

grammar Thingy
    does Either
    does Alpha
    {
    token TOP { <alpha> <either>* }
    }

my $match = Thingy.parse( '1a3' );
dd $match;

这不起作用,因为Perl 6没有解开关系,以确定冲突实际上是来自同一来源的相同内容:

Method ‘alpha’ must be resolved by class Thingy because it exists in multiple roles

但是,阅读S14,我看到:

A role may not inherit from a class,but may be composed of other roles. However,this “crony” composition is not evaluated until class composition time. This means that if two roles bring in the same crony,there’s no conflict–it’s just as if the class pulled in the crony role itself and the respective roles didn’t. A role may never conflict with itself regardless of its method of incorporation.

我读到这意味着角色尽可能晚地应用,因此Thingy类能够解开Alpha包含在两个不同的部分.我认为这可能会像创建构成最终类的所有角色的列表,然后将该列表仅应用于最终类.这样,像Either这样的东西只混合它定义的东西,并依赖于后来的构图来引入Alpha.

当我尝试为各种(IETF)RFC实现语法时,我碰到了这个问题.其中许多引用了其他RFC的语法,这使得Perl 6无法通过C3解析继承.所以,我认为角色会断开关系.显然它没有.

解决方法

是的,Perl 6应该能够解开来自不同来源的相同角色的包含.

role的简单definition是:

A role encapsulates some piece of behavior or state that can be shared between classes.

要么

A role is a name for a discrete collection of behaviors.

因此,假设我们对可以在水上浮动的对象具有Floatable行为,并且对于可以航行的对象具有Sailable行为.当然,可以航行的物体可以漂浮. Sloop天然可浮动且可以播放. Floatable和Sailable角色都传达了相同的Floatable行为,这一事实没有冲突.

在Perl中,这可以按预期工作(它也适用于Moose):

#!/usr/bin/env perl

use v5.24; # why not
use warnings;

package Floatable {
    use Moo::Role;
    sub float { say "float" }
}

package Sailable {
    use Moo::Role;
    with 'Floatable';
    sub sail { $_[0]->float; say "sail" };
}

package Sloop {
    use Moo;
    with qw( Floatable Sailable );
}

my $s = Sloop->new;

$s->sail;

这种行为是直观明显的行为.

在查看Perl6 documentation for roles时我注意到的一个问题是缺少简单的一句话定义:

Roles are in some ways similar to classes,in that they are a collection of attributes and methods. They differ in that roles are also meant for describing only parts of an object’s behavior and in how roles are applied to classes. Or to phrase it differently,classes are meant for managing objects and roles are meant for managing behavior and code reuse.

Role application differs significantly from class inheritance. When a role is applied to a class,the methods of that role are copied into the class. If multiple roles are applied to the same class,conflicts (e.g. attributes or non-multi methods of the same name) cause a compile-time error,which can be solved by providing a method of the same name in the class.

显然,当perl6遇到两个提供完全相同行为的角色时,它会认为这是一种我认为不合理的冲突.

请注意以下示例中的细微区别:

#!/usr/bin/env perl

use v5.24; # why not
use warnings;

package Floatable {
    use Moo::Role;
    sub float { say "float" }
}

package Sailable {
    use Moo::Role;
    sub float { say "floating bonds to finance journey "}
    sub sail { $_[0]->float; say "sail" };
}

package Sloop {
    use Moo;
    with qw( Floatable Sailable );
}

my $s = Sloop->new;

$s->sail;

在这种情况下,可能会发生冲突,因为两个不同的角色想声称提供相同的行为.

(编辑:李大同)

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

    推荐文章
      热点阅读