我有一个用perl6的子集命令构造的类型层次结构,以及一些专门针对这些类型的多子类.当多调度发生时,如何通过最窄的子类型赋予最高优先级?
这是简化的代码:
#! /usr/bin/env perl6
use v6.c;
proto check($value) { * }
subset Positive of Int where * > 0;
subset PositiveEven of Positive where * %% 2;
multi check(Int $value) {
say "integer"
}
multi check(Positive $value) {
say "positive"
}
multi check(PositiveEven $value) {
say "positive & even"
}
# example:
check(32);
# expected output:
# positive & even
# actual output:
# positive
Run Code Online (Sandbox Code Playgroud) 我有一个这样的课:
class Foo {
method some-method(Str $name) { ... }
}
Run Code Online (Sandbox Code Playgroud)
用法简单:
my $foo = Foo.new;
$foo.some-method("peter");
Run Code Online (Sandbox Code Playgroud)
由于"some-method"将被频繁调用,我想做一些事情以允许用户使用它,如下所示:
$foo.peter;
Run Code Online (Sandbox Code Playgroud)
我知道FALLBACK会完成这项工作,但它已被用于另一种方法.我试图定义一个中缀运算符:
sub infix:<%>(Foo $foo, $name) {
$foo.some-method($name);
}
Run Code Online (Sandbox Code Playgroud)
下面的代码有效,但双引号很烦人.
$foo % "peter";
Run Code Online (Sandbox Code Playgroud)
那么有什么方法可以避免引号?或者以何种方式简化调用?
我写了一个这样的语法:
grammar StatementFormat {
token TOP { (<plain> | '%' <placeholder>)* }
token plain { <-[%]> }
token placeholder {
| <verb>
| <noun>
| <adverb>
}
token verb {
'v'
{
# some actions
}
}
token noun {
'n'
{
# some actions
}
}
token adverb {
'a'
{
# some actions
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以我可以用它来解析像“someone %v %n %a”这样的字符串。
但是,我发现有很多像“%v %n %a”这样的用法,我想给它一个别名,比如“%b”,这样解析“someone %b”就相当于解析“someone %” v %n %a”。
那么有没有办法做到这一点?
当然token alias { 'b' { ... } } …
我AT-POS为类定义了方法并导出了[]运算符.[]但是,当我在该类的实例上使用时,编译器忽略了我定义的运算符.
这是代码:
unit module somelib;
class SomeClass is export {
method AT-POS(@indices) {
say "indices are {@indices.perl}"
}
}
multi postcircumfix:<[ ]> (SomeClass:D $inst, *@indices) is export {
$inst.AT-POS(@indices)
}
Run Code Online (Sandbox Code Playgroud)
#! /usr/bin/env perl6
use v6.c
use lib ".";
use somelib;
my $inst = SomeClass.new;
$inst[3, 'hi'];
# expected output:
# indices are 3, 'hi'
# actual output:
# Type check failed in binding to parameter '@indices';
# expected Positional but got Int (3)
# …Run Code Online (Sandbox Code Playgroud) 我的代码花了很多时间在正则表达式插值上.由于模式很少改变,我想缓存这些生成的正则表达式应该加快代码.但我无法找到一种正确的方法来缓存和使用缓存的正则表达式.
该代码用于解析一些算术表达式.由于允许用户定义新运算符,因此解析器必须准备好将新运算符添加到语法中.因此,解析器使用表来记录这些新运算符,并在运行时从表中生成正则表达式.
#! /usr/bin/env perl6
use v6.c;
# the parser may add new operators to this table on the fly.
my %operator-table = %(
1 => $['"+"', '"-"'],
2 => $['"*"', '"/"'],
# ...
);
# original code, runnable but slow.
grammar Operator {
token operator(Int $level) {
<{%operator-table{$level}.join('|')}>
}
# ...
}
# usage:
say Operator.parse(
'+',
rule => 'operator',
args => \(1)
);
# output:
# ?+?
Run Code Online (Sandbox Code Playgroud)
以下是一些实验:
# try to cache the generated regexes but not work. …Run Code Online (Sandbox Code Playgroud) 我正在制作一个perl6包,其中包含一些将被编译成动态链接库的c源文件.我发现在"zef install"之后,库的名称(如libperl.so)将更改为"A858A3D6EC5363B3D3F59B1.so"之类的内容.但是,该名称在python代码中用作模块名称(libperl).更改后,它不再是有效的标识符.那么,是否有可能阻止这种变化?如果是,我该怎么办?
我正在创建一个包,我必须通过它在sub中的名称来获取符号的值,而符号在sub之外定义.
这是简化的代码,它按预期工作:
#! /usr/bin/env perl6
sub dump_value($symbol) {
say ::("$symbol")
}
# usage:
my $x = 10;
dump_value('$x');
# expected output: 10
# actual output: 10
Run Code Online (Sandbox Code Playgroud)
然后我将'dump_value'放在一个独立的文件中,如下所示:
# somelib.pm6
unit module somelib;
sub dump_value($symbol) is export {
say ::("$symbol")
}
Run Code Online (Sandbox Code Playgroud)
# client.pl6
#! /usr/bin/env perl6
use lib ".";
use somelib;
my $x = 10;
dump_value('$x');
Run Code Online (Sandbox Code Playgroud)
编译抱怨:
No such symbol '$x'
in sub dump_value at xxx/somelib.pm6 (somelib) line 3
in block <unit> at ./client.pl6 line 8
Run Code Online (Sandbox Code Playgroud)
以下是一些实验.他们都没有成功.
say ::("MY::$symbol")
say ::("OUR::$symbol") …Run Code Online (Sandbox Code Playgroud) 我正在将软件包安装到虚拟机(ubuntu18.04)上.以下是我使用的说明:
apt-get install perl6 && \
git clone https://github.com/ugexe/zef.git && cd zef && perl6 -I. bin/zef install . && \
/usr/lib/perl6/site/bin/zef install Shell::Command && \
PYTHON_CONFIG=/usr/bin/python3-config \
/usr/lib/perl6/site/bin/zef -v install https://github.com/eatingtomatoes/Inline-Python3.git --/test --debug
Run Code Online (Sandbox Code Playgroud)
以下是输出:
....
===> Building [OK] for Inline::Python3:ver<0.1>
===> Installing: LibraryMake:ver<1.0.0>:auth<github:retupmoca>
===> Install [OK] for LibraryMake:ver<1.0.0>:auth<github:retupmoca>
===> Installing: Inline::Python3:ver<0.1>
===> Install [FAIL] for Inline::Python3:ver<0.1>: ===SORRY!===
Probable version skew in pre-compiled
'site#sources/95D204DDA68A3E05E891AA531EBED9270C46B3F7
(Inline::Python3::InstanceConverter)' (cause: no object at index 499)
===SORRY!===
Probable version skew in pre-compiled
'site#sources/95D204DDA68A3E05E891AA531EBED9270C46B3F7
(Inline::Python3::InstanceConverter)' (cause: no …Run Code Online (Sandbox Code Playgroud) 我发现用 Common Lisp 进行面向对象编程很痛苦。主要问题是方法的命名。请参见下面的代码。
\n(defclass foo () ())\n\n(defmethod action ((object foo))\n (write-line "hello"))\n\n\n(defclass bar () ())\n\n(defmethod action ((object bar) boo)\n t)\n\n\n(print\n (action (make-instance \'foo)))\n\n(print\n (action (make-instance \'bar) 1))\n\nRun Code Online (Sandbox Code Playgroud)\n这两种action方法并不是同一通用函数的不同实现。它们偶然具有相同的名称。\n但是 Common Lisp 要求所有具有相同名称的方法具有相同数量的参数。
为了避免名称冲突,我通常在方法名称前加上类名称前缀,例如foo-action和bar-action。但这会导致实际程序中的代码非常冗长,例如(lengthy-class-name-do-something some-variable)。
其他面向对象的编程语言,如 C++ 和 Java\xef\xbc\x8c 则不存在此类问题。你可以这样写,some_variable.do_something()其中没有名称冲突。
所以我想知道是否有更好的解决方案来解决上述问题?
\n