(編集:pipe
以下の関数は、オーバーロードが正しく機能するために祝福されたオブジェクトを返す必要があります。受け入れられた答えを参照してください。)
私はperlのoverload
機能を使用して単純な解析ツリーを構築しようとしています。私は多くを必要としません-実際、私が必要とするのは、左結合である1つの演算子だけです。しかし、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'], 'foo' ),[bless( ['x'], 'foo' ),bless( ['y'], 'foo' )]]
p4 = [bless( ['w'], 'foo' ),[bless( ['z'], 'foo' ),[bless( ['x'], 'foo' ),bless( ['y'], 'foo' )]]]
p5 = [bless( ['z'], 'foo' ),[bless( ['x'], 'foo' ),bless( ['y'], 'foo' )]]
s2 = [bless( ['x'], 'foo' ),bless( ['y'], 'foo' )]
s3 = [bless( ['x'], 'foo' ),[bless( ['y'], 'foo' ),bless( ['z'], 'foo' )]]
s4 = [bless( ['x'], 'foo' ),[bless( ['y'], 'foo' ),[bless( ['z'], 'foo' ),bless( ['w'], 'foo' )]]]
p2
他の場合と一致させるために、xとyを逆にするべきではありませんか?注意して、同じ出力p3
をp5
生成します-では、どうすればそれらを区別できますか?
右結合演算子でも同じ問題は発生しません**
。
これに対する回避策はありますか?