如何在Perl6中编写自定义访问器方法?
如果我有这个课程:
class Wizard {
has Int $.mana is rw;
}
Run Code Online (Sandbox Code Playgroud)
我可以做这个:
my Wizard $gandalf .= new;
$gandalf.mana = 150;
Run Code Online (Sandbox Code Playgroud)
假设我想在我的Perl6类中为一个setter添加一点检查而不放弃$gandalf.mana = 150;表示法(换句话说,我不想写这个:) $gandalf.setMana(150);.如果它试图设定负面法术力,该程序应该死亡.我该怎么做呢?Perl6文档提到它可以编写自定义访问器,但没有说明如何.
我正在浏览例程中的Perl 6文档shift并看到了这个片段:
定义为:
Run Code Online (Sandbox Code Playgroud)multi sub shift(Array:D ) multi method shift(Array:D:)
我知道:D指的Array就是defined不Any和Nil,但有什么:D:?搜索起来非常困难.
类型签名文档的这一部分包含更多语法示例,但没有(据我所知)解释它.
我以为在互联网上的某个地方会有一个简单的答案,但似乎我找不到解决方案.我首先想知道是否有一个简单的方法或功能:
例如,~~或array.contains()来自Perl 5
在Perl 6中有多少不同的方法可以实现这一结果也很好,因为考虑到问题的情况,有些方法可能比其他方法更好.
是否有一种简单的方法可以将定义常量的值用作Perl6中的散列/对键?
例如 :
constant KEY = "a string";
my %h = ( KEY => "a value" );
Run Code Online (Sandbox Code Playgroud)
这将创建"KEY"而不是"字符串"的键.
我可以 :
my %h = ( "{KEY}" => "a value" );
Run Code Online (Sandbox Code Playgroud)
但这似乎有点笨重.我想知道是否有更好的方法?
有人可以提供从Perl 6开始的材料链接吗?还有人可以指出已经用Perl 6开发的真实应用程序吗?
我有两个Perl 6文件:
hello.p6:
sub hello
{
say 'hello';
}
Run Code Online (Sandbox Code Playgroud)
和main.p6:
require 'hello.p6';
hello();
Run Code Online (Sandbox Code Playgroud)
但是不要工作.如何在主脚本中包含第一个文件?
该int类有一个方法is_prime,所以我想,只是笑声,我想一些其他方法增加Int了一些做数论的东西我的爱好项目.
我以为我可以这样做:
class Int {
method is-even (Int:D $number ) returns Bool:D {
return False if $number % 2;
return True;
}
}
say 137.is-even;
Run Code Online (Sandbox Code Playgroud)
但这不起作用:
===SORRY!===
P6opaque: must compose before allocating
Run Code Online (Sandbox Code Playgroud)
我不知道这是否意味着我不能这样做或者我做错了.
我可以很容易地创建一个继承自的新类Int,但这不是我感兴趣的:
class MyInt is Int {
method is-even () returns Bool:D {
return False if self % 2;
return True;
}
}
my $n = MyInt.new(138);
say $n.is-even;
Run Code Online (Sandbox Code Playgroud)
我不是在寻找变通方法或替代解决方案.
Clickbaity标题,但它太多了,不能放弃.我有这个运算符,我希望是正确的关联:
sub infix:<?> ( Int:D \n, Int:D \m --> Int:D )
is assoc<right>
is equiv(&infix:<**>)
{ n ** m }
put "2**2**2**2 = ", 2**2**2**2;
put "2?2?2?2 = ", 2?2?2?2;
put "2? (2? (2?2) ) = ", 2? (2? (2?2) );
Run Code Online (Sandbox Code Playgroud)
这是不正确的联想:
2**2**2**2 = 65536
2?2?2?2 = 256
2? (2? (2?2) ) = 65536
Run Code Online (Sandbox Code Playgroud)
我做得不对(咳咳)?
我不明白这种行为:
> sort([1,2,3,4]) ~~ sort([1,2,3,4])
False
Run Code Online (Sandbox Code Playgroud)
你能解释一下吗?根据Perl 6,为什么这两个列表(显然相等)不相等.
更新
有趣,但它取决于Perl6版本(我刚刚注意到它):
$ which perl6
/usr/bin/perl6
$ dpkg -S `which perl6`
rakudo: /usr/bin/perl6
$ perl6 --version
This is perl6 version 2015.11 built on MoarVM version 2015.11
$ perl6
> sort([1,2,3]) ~~ sort([1,2,3])
True
>
$ export PATH=~/.rakudobrew/bin:$PATH
$ perl6 --version
This is Rakudo version 2017.12 built on MoarVM version 2017.12.1
implementing Perl 6.c.
$ perl6
To exit type 'exit' or '^D'
> sort([1,2,3]) ~~ sort([1,2,3])
False
>
Run Code Online (Sandbox Code Playgroud)
从#perl6的讨论开始:
[19:35] <+committable6> AlexDaniel,
¦2015.12,2016.01.1,2016.02,2016.03,2016.04,2016.05,2016.06,2016.07.1,2016.08.1,2016.09,2016.10,2016.11,2016.12: …Run Code Online (Sandbox Code Playgroud) 我正在玩这个小东西,其中一组可以通过翻转测试来充当它的补充.为了实现这一目标,我创建了会员运营商的特殊版本.
class Complement {
has $.set;
}
multi infix:<?> ( $a, Complement:D $c ) { $a ? $c.set }
multi infix:<?> ( $a, Complement:D $c ) { $a ? $c.set }
my $set = (1, 2, 3).Set;
my $c = Complement.new: set => $set;
put 3 ? $set;
put 4 ? $c;
Run Code Online (Sandbox Code Playgroud)
根据我infix:<?>对另一个的定义,更普遍的似乎已经消失了.没有其他候选人:
True
Cannot resolve caller infix:<?>(Int, Set); none of these signatures match:
($a, Complement:D $c)
in sub infix:<?> at /Users/brian/Desktop/complement.p6 line 11
in block <unit> at …Run Code Online (Sandbox Code Playgroud)