(编辑:下面的管道功能应返回一个受祝福的对象,以便重载正常工作.请参阅接受的答案.)
我正在尝试使用perl的重载功能来构建一个简单的解析树.
我不需要太多 – 实际上,我只需要一个左关联的运算符.
但是,perl解析$x op $y与更长时间的方式似乎存在不一致
像$x op $y op $z op ….
这就是我所拥有的:
package foo; use overload '|' => \&pipe,"**" => \&pipe,">>" => \&pipe; sub pipe { [ $_[0],$_[1] ] } package main; my $x = bless ["x"],"foo"; my $y = bless ["y"],"foo"; my $z = bless ["z"],"foo"; my $w = bless ["w"],"foo"; # how perl parses it: my $p2 = $x | $y; # Cons x y my $p3 = $x | $y | $z; # Cons z (Cons x y) my $p4 = $x | $y | $z | $w; # Cons w (Cons z (Cons x y)) my $p5 = $z | ($x | $y); # same as p3??? my $s2 = $x ** $y; # Cons x y my $s3 = $x ** $y ** $z; # Cons x (Cons y z) my $s4 = $x ** $y ** $z ** $w; # Cons x (Cons y (Cons z w)) sub d { Dumper(\@_) } say "p2 = ".d($p2); say "p3 = ".d($p3); say "p4 = ".d($p4); say "p5 = ".d($p5); say "s2 = ".d($s2); say "s3 = ".d($s3); say "s4 = ".d($s4);
输出类似于:
p2 = [bless( ['x'],'foo' ),bless( ['y'],'foo' )] p3 = [bless( ['z'],[bless( ['x'],'foo' )]] p4 = [bless( ['w'],[bless( ['z'],'foo' )]]] p5 = [bless( ['z'],'foo' )]] s2 = [bless( ['x'],'foo' )] s3 = [bless( ['x'],[bless( ['y'],bless( ['z'],'foo' )]] s4 = [bless( ['x'],bless( ['w'],'foo' )]]]
p2不应该反转x和y与其他情况一致吗?
请注意,p3和p5产生相同的输出 – 所以我如何分辨它们?
我没有看到右关联运算符**的相同问题.
有没有解决这个问题?
解决方法
use feature ":5.14"; use warnings FATAL => qw(all); use strict; use Data::Dump qw(dump pp); sub foo() {package foo; use overload '|' => \&p; sub p {bless [@{$_[0]},@{$_[1]}]} } my $x = bless ["x"],"foo"; my $p = $x | $y | $z; pp($p)
生产:
bless(["x","y","z"],"foo")