是否可以使用pert来实现以下语法?
sub a {
my ($first, $second) = @_;
print "$first $second";
}
sub b {
my ($param, $code) = @_;
my $res = $code->();
return "$param $res";
}
a 'param1' b 'param2' => sub { return "param3" };
#output would be "param1 param2 param3"
a是sub,它会进入@_' param1'什么b(它会得到' param2'以及@_中的subref)返回。我喜欢在' b之前没有逗号。有可能吗?
答案 0 :(得分:5)
我强烈建议不要这样做。你省略逗号的动机是什么?
语言 X 此处不需要逗号。
Perl不是 X 。 X 可能有很多功能,但Perl没有。这还包括静态类型,缩进敏感的解析和Lisp风格的宏。如果你绝对需要 X 的功能,也许你应该使用 X 。
我正在用Perl编写一个DSL,其中逗号会很烦人。
我知道这种趋势是编写远程看起来像普通文本的精美API,并将它们称为“DSL”。他们不是; DSL要求你实际解析一些东西。如果您正在编写API,那么最好使用宿主语言。即使这涉及流浪逗号等。
无论出于何种原因,无论结果多么脆弱,我都非常想这样做。
在这种特定情况下,我可以根据需要编写代码。它使用荒谬和沮丧的“dative”形式的方法调用(也称为“间接对象符号”)。
param1
将是我们称之为a
方法的类。参数列表将调用b
:
use feature 'say';
package param1 {
sub a {
my ($first, $second) = @_;
say "$first $second";
}
}
sub b {
my ($param, $code) = @_;
my $res = $code->();
return "$param $res";
}
a param1 b param2 => sub { "param3" }; # look, optional quotes for param1
当然,这只是'param1'->a(b(param2 => sub { 'param3' }))
的语法糖。并且它要求您事先知道param1
的所有值 - 除非您首先创建一个包装第一个arg的对象:
use feature 'say';
package MyApi {
sub a {
my ($first, $second) = @_;
say "$$first $second";
}
}
sub b {
my ($param, $code) = @_;
my $res = $code->();
return "$param $res";
}
sub api($) { bless \shift() => 'MyApi' }
my $param1 = api 'param1';
a $param1 b param2 => sub { "param3" };
但那太傻了。
我仍然想这样做,但没有那种脆弱的废话。我也不在乎为实现这项工作需要花费多少精力。
您可以向Perl解析器添加关键字,以便您接管解析。这要求您对Perl的解析器API有一定的了解,并且您的代码不适用于旧的Perls。因为您可能不想在C中编写解析器,所以您可能希望查看类似Devel::Declare::Lexer的内容,但这些模块往往有点不确定。祝你好运!