我正在开发一个小型的领域特定语言,它使用重载的nomethod
回退来捕获在重载值上使用的运算符。这类似于overload
文档中描述的symbolic calculator的功能。
这对于标准比较运算符很有效,但请考虑以下几点:
my $ret = $overloaded =~ /regex/;
在这种情况下,会调用nomethod
对$overloaded
进行字符串化,之后重载就会丢失。我考虑过返回一个绑定变量,这至少可以让我携带原始的重载对象,但在执行regex的过程中,它仍然会丢失。
所以,最终的问题是,是否有任何方法可以扩展overload
的符号计算器的概念,以包括正则表达式绑定操作符=~
和!~
,以便上面的代码样例可以用($overloaded, qr/regex/, 0, '=~')
或类似的东西调用nomethod
?
我还简要地研究了重载smartmatch操作符~~
,但这似乎也没有起到作用(总是默认使用正则表达式匹配,而不是重载)。
编辑:我查看了~~
more,发现my $ret = $overloaded ~~ q/regex/
的工作归功于智能匹配规则。很接近,但不是一个理想的解决方案,我希望它能在5.10之前工作,所以我欢迎其他答案。
发布于 2010-09-16 08:15:26
我觉得DSL最好用Perl语言中的source filters编写。你可以做任何你想做的事。;-)在您的示例中,您可以使用正则表达式将FOO =~ BAR替换为myfunc(FOO,BAR)并运行任意代码。
下面是一个示例解决方案:
# THE "MyLang" SOURCE FILTER
package MyLang;
use strict;
use warnings;
use Filter::Util::Call;
sub import {
my ($type, @args) = @_;
my %p = @args;
no strict 'refs';
my $caller = caller;
# Create the function to call
*{"${caller}::_mylang_defaultmethod"} = sub {
my ($a, $op, $b) = @_;
$p{nomethod}->($a, $b, 0, $op);
};
my ($ref) = [];
filter_add(bless $ref);
}
sub filter {
my ($self) = @_;
my ($status);
if ($status = filter_read() > 0) {
$_ =~ s/([^=]+)(=~)([^;]+)/ _mylang_defaultmethod($1,'$2',$3)/g;
}
$status;
}
1;
示例用法
use MyLang nomethod => \&mywrap;
my $a = "foo";
my $b = "bar";
$x = $a =~ $b;
sub mywrap {
my ($a, $b, $inv, $op) = @_;
print "$a\n";
}
现在,上面的代码将打印"foo\n“,因为它就是"$a”变量中的内容。当然,您可能希望对过滤器中的正则表达式替换进行一些稍微更智能的解析,但这是一个简单的概念证明。
https://stackoverflow.com/questions/3704891
复制相似问题