Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

is-deeply not using custom eqv operators #5889

Closed
p6rt opened this issue Dec 16, 2016 · 6 comments
Closed

is-deeply not using custom eqv operators #5889

p6rt opened this issue Dec 16, 2016 · 6 comments
Labels

Comments

@p6rt
Copy link

p6rt commented Dec 16, 2016

Migrated from rt.perl.org#130362 (status was 'rejected')

Searchable as RT130362$

@p6rt
Copy link
Author

p6rt commented Dec 16, 2016

From tim.bollman@live.com

The is-deeply operator does not appear to pick up custom infix eqv variants. I can see on line 567 of rakudo/lib/Test.pm6 that _is_deeply is using infix​:<eqv>, but it doesn't pick up the custom variant. I attempted exporting the operator and moving the use Test below the multi declaration, but it didn't make any difference (I didn't expect it to, but didn't hurt to try).

use v6;
use Test;

class Custom-Equality {
  has $.a;
  has $.b;
}

# Define a custom equivalence operator that equates the opposite properties
# instead of the same properties.
multi infix​:<eqv>(Custom-Equality $l, Custom-Equality $r) {
  return !$r.defined unless $l.defined;
  return $r.defined && $l.a eqv $r.b && $l.b eqv $r.a;
}

my Custom-Equality $x .= new(​:a<cat>, :b<dog>);
my Custom-Equality $y .= new(​:a<dog>, :b<cat>);

ok($x eqv $y, 'x is equivalent to y'); # Passes
is-deeply($x, $y, 'x is deeply y'); # Fails

@p6rt
Copy link
Author

p6rt commented Dec 17, 2016

From @zoffixznet

On Fri, 16 Dec 2016 12​:40​:05 -0800, TimTom wrote​:

The is-deeply operator does not appear to pick up custom infix eqv
variants. I can see on line 567 of rakudo/lib/Test.pm6 that
_is_deeply is using infix​:<eqv>, but it doesn't pick up the custom
variant. I attempted exporting the operator and moving the use Test
below the multi declaration, but it didn't make any difference (I
didn't expect it to, but didn't hurt to try).

use v6;
use Test;

class Custom-Equality {
has $.a;
has $.b;
}

# Define a custom equivalence operator that equates the opposite
properties
# instead of the same properties.
multi infix​:<eqv>(Custom-Equality $l, Custom-Equality $r) {
return !$r.defined unless $l.defined;
return $r.defined && $l.a eqv $r.b && $l.b eqv $r.a;
}

my Custom-Equality $x .= new(​:a<cat>, :b<dog>);
my Custom-Equality $y .= new(​:a<dog>, :b<cat>);

ok($x eqv $y, 'x is equivalent to y'); # Passes
is-deeply($x, $y, 'x is deeply y'); # Fails

Thank you for the report. However, this is not a bug.

What is-deeply uses under the hood is secret and you should not be
relying on it. I noticed our documentation was worded in a way that may
make one think what you're doing should work. I have now reworded it[1].

As for the reason why it doesn't work, it's because your infix​:<eqv> routine is
not in lexical scope of is-deeply. In other words, defining an operator does not
make it available in the entire program. The behaviour is the same as it would
be with any other routine.

[1] Raku/doc@f705a6f

Cheers,
ZZ

@p6rt
Copy link
Author

p6rt commented Dec 17, 2016

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Dec 17, 2016

@zoffixznet - Status changed from 'open' to 'rejected'

@p6rt p6rt closed this as completed Dec 17, 2016
@p6rt
Copy link
Author

p6rt commented Dec 17, 2016

From @zoffixznet

Forgot to mention... Check out `cmp-ok` routine for your task​: https://docs.perl6.org/language/testing#index-entry-cmp-ok-cmp-ok%28%24value%2C_%24comparison%2C_%24expected%2C_%24description%3F%29

cmp-ok $got, 'eqv', $expected should pick up your custom operator.

@p6rt
Copy link
Author

p6rt commented Dec 17, 2016

From tim.bollman@live.com

I definitely went down that road because of the documentation (needed to compare type graphs with loops and I knew I could build a specialization of eqv). I'm not sure the change is strong enough to really dissuade that line of thinking, but it's at least better than it was so thanks. I would personally remove the reference to eqv entirely and put something like​:

| Marks a test as passed if C<$value> and C<$expected> are the same using
| canonical value-wise deep equivalence. This is the best way to check for
| equality of (deep) non-cyclic data structures. Accepts an optional
| C<$description> of the test.

Personally multi candidates feel like something that should be dynamic scope, but I understand the trade-off against action at a distance.

On Fri, 16 Dec 2016 17​:52​:33 -0800, cpan@​zoffix.com wrote​:

On Fri, 16 Dec 2016 12​:40​:05 -0800, TimTom wrote​:

The is-deeply operator does not appear to pick up custom infix eqv
variants. I can see on line 567 of rakudo/lib/Test.pm6 that
_is_deeply is using infix​:<eqv>, but it doesn't pick up the custom
variant. I attempted exporting the operator and moving the use Test
below the multi declaration, but it didn't make any difference (I
didn't expect it to, but didn't hurt to try).

use v6;
use Test;

class Custom-Equality {
has $.a;
has $.b;
}

# Define a custom equivalence operator that equates the opposite
properties
# instead of the same properties.
multi infix​:<eqv>(Custom-Equality $l, Custom-Equality $r) {
return !$r.defined unless $l.defined;
return $r.defined && $l.a eqv $r.b && $l.b eqv $r.a;
}

my Custom-Equality $x .= new(​:a<cat>, :b<dog>);
my Custom-Equality $y .= new(​:a<dog>, :b<cat>);

ok($x eqv $y, 'x is equivalent to y'); # Passes
is-deeply($x, $y, 'x is deeply y'); # Fails

Thank you for the report. However, this is not a bug.

What is-deeply uses under the hood is secret and you should not be
relying on it. I noticed our documentation was worded in a way that
may
make one think what you're doing should work. I have now reworded
it[1].

As for the reason why it doesn't work, it's because your infix​:<eqv>
routine is
not in lexical scope of is-deeply. In other words, defining an
operator does not
make it available in the entire program. The behaviour is the same as
it would
be with any other routine.

[1]
Raku/doc@f705a6f

Cheers,
ZZ

@p6rt p6rt added the Bug label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant