Navigation Menu

Skip to content

Commit

Permalink
Improve error message for non-dwimmy hyper ops
Browse files Browse the repository at this point in the history
Patch courtesy by Timothy Bollman
With some wording improvements by moritz.

This recursively tracks the indexing path in hyperops, and prints that path
on error. Also elaborates on the nature of the different shapes, either
different length or types (Hash vs Scalar/List or so)
  • Loading branch information
moritz committed Oct 19, 2010
1 parent 3905e0e commit 6f30584
Showing 1 changed file with 40 additions and 12 deletions.
52 changes: 40 additions & 12 deletions src/core/metaops.pm
Expand Up @@ -45,7 +45,7 @@ our multi reduce(&op, *@list) {
@list.reduce(&op)
}

our multi sub hyper(&op, @lhs, @rhs, :$dwim-left, :$dwim-right) {
our multi sub hyper(&op, @lhs, @rhs, :$dwim-left, :$dwim-right, :@path) {
my sub repeating-array(@a) {
gather loop {
my $prev-a;
Expand All @@ -61,7 +61,13 @@ our multi sub hyper(&op, @lhs, @rhs, :$dwim-left, :$dwim-right) {
my $length;
if !$dwim-left && !$dwim-right {
if +@lhs != +@rhs {
die "Sorry, sides are of uneven length and not dwimmy.";
my $msg = "Sorry, lists on both sides of non-dwimmy hyperop are not of same length:\n"
~ " left: @lhs.elems() elements\n"
~ " right: @lhs.elems() elements\n";

This comment has been minimized.

Copy link
@kboga

kboga Oct 19, 2010

Contributor

Shouldn't line 66 have @rhs.elems() instead of @lhs.elems()?

edit:
got beaten to it by TimTom =)

if (+@path) {
$msg ~= "At path [@path.join(', ')]";
}
die $msg;
}
$length = +@lhs;
} elsif !$dwim-left {
Expand All @@ -84,21 +90,21 @@ our multi sub hyper(&op, @lhs, @rhs, :$dwim-left, :$dwim-right) {
my @result;
for ^$length -> $i {
if Associative.ACCEPTS(@lhs[$i]) || Associative.ACCEPTS(@rhs[$i]) {
@result.push(hyper(&op, @lhs[$i], @rhs[$i], :$dwim-left, :$dwim-right).item);
@result.push(hyper(&op, @lhs[$i], @rhs[$i], :$dwim-left, :$dwim-right, path => (@path, $i)).item);
} elsif Iterable.ACCEPTS(@lhs[$i]) || Iterable.ACCEPTS(@rhs[$i]) {
@result.push([hyper(&op, @lhs[$i].list, @rhs[$i].list, :$dwim-left, :$dwim-right)]);
@result.push([hyper(&op, @lhs[$i].list, @rhs[$i].list, :$dwim-left, :$dwim-right, path => (@path, $i))]);
} else {
@result.push(op(@lhs[$i], @rhs[$i]));
}
}
@result
}

our multi sub hyper(&op, $lhs, $rhs, :$dwim-left, :$dwim-right) {
hyper(&op, $lhs.list, $rhs.list, :$dwim-left, :$dwim-right);
our multi sub hyper(&op, $lhs, $rhs, :$dwim-left, :$dwim-right, :@path) {
hyper(&op, $lhs.list, $rhs.list, :$dwim-left, :$dwim-right, :@path);
}

our multi sub hyper(&op, %lhs, %rhs, :$dwim-left, :$dwim-right) {
our multi sub hyper(&op, %lhs, %rhs, :$dwim-left, :$dwim-right, :@path) {
my %result;
my @keys;
if $dwim-left && $dwim-right {
Expand All @@ -114,7 +120,13 @@ our multi sub hyper(&op, %lhs, %rhs, :$dwim-left, :$dwim-right) {
}

for @keys -> $key {
%result{$key} = &op(%lhs{$key}, %rhs{$key});
if Associative.ACCEPTS(%lhs{$key}) || Associative.ACCEPTS(%rhs{$key}) {
%result{$key} = hyper(&op, %lhs{$key}, %rhs{$key}, :$dwim-left, :$dwim-right, path => (@path, $key)).item;
} elsif Iterable.ACCEPTS(%lhs{$key}) || Iterable.ACCEPTS(%rhs{$key}) {
%result{$key} = hyper(&op, %lhs{$key}.list, %rhs{$key}.list, :$dwim-left, :$dwim-right, path => (@path, $key));
} else {
%result{$key} = op(%lhs{$key}, %rhs{$key});
}
}
%result;
}
Expand All @@ -127,17 +139,33 @@ our multi sub hyper(&op, %arg) {
%result;
}

our multi sub hyper(&op, %lhs, $rhs, :$dwim-left, :$dwim-right) {
die "Sorry, right side is too short and not dwimmy." unless $dwim-right;
our multi sub hyper(&op, %lhs, $rhs, :$dwim-left, :$dwim-right, :@path) {
unless ($dwim-right) {
my $msg = "Sorry, structures on both sides of non-dwimmy hyperop are not of same shape:\n"
~ " left: Hash\n"
~ " right: $rhs.WHAT.perl()\n";
if (+@path) {
$msg ~= "At path [@path.join(', ')]";
}
die $msg;
}
my %result;
for %lhs.keys -> $key {
%result{$key} = &op(%lhs{$key}, $rhs);
}
%result;
}

our multi sub hyper(&op, $lhs, %rhs, :$dwim-left, :$dwim-right) {
die "Sorry, left side is too short and not dwimmy." unless $dwim-left;
our multi sub hyper(&op, $lhs, %rhs, :$dwim-left, :$dwim-right, :@path) {
unless ($dwim-left) {
my $msg = "Sorry, structures on both sides of non-dwimmy hyperop are not of same shape:\n"
~ " left: $lhs.WHAT.perl()\n"
~ " right: Hash\n";
if (+@path) {
$msg ~= "At path [@path.join(', ')]";
}
die $msg;
}
my %result;
for %rhs.keys -> $key {
%result{$key} = &op($lhs, %rhs{$key});
Expand Down

0 comments on commit 6f30584

Please sign in to comment.