Re: [code-review] Please review String::FlexMatch
Fergal Daly <[email protected]> Sat, 6 Sep 2003 10:52:55 +0100
| Newsgroups | gmane.comp.lang.perl.code-review-ladder |
|---|---|
| Message-ID | <[email protected]> |
I've finally got to look at the module and the tests. Now I see what you're
doing with deep tests. This is something I wanted to do before and it became
Test::Deep. I wanted is_deeply to examine the class of blessed objects. I
suggested that we could make it check class if the expected argument was
blessed, otherwise it would ignore it. Michael said no way, is_deeply
shouldn't be changing it's behaviour depending on the data you put in.
I'd say you should be using Test::Deep instead of putting overloaded objects
into is_deeply (at the end I've rewritten one of your tests using it). For
me, the fact that it used to work previously is a bug. I haven't heard
Michael's opinion about it yet though.
Below are some more arguments for why is_deeply shouldn't do it.
On Thursday 04 September 2003 15:10, Marcel GrĂ¼nauer wrote:
> But I think with overloading it's ok, because in using overload, the
> object
> *asks* for it. In fact, if an object provides an overloaded
> stringification,
> it seems to be an error to try and circumvent it.
But the object isn't asking for string-wise equality, it's asking for deep
equality and the only thing that's deeply equal to "string" is "string", not
an object that is pretending to be "string". Deep is the key word here. The
docs don't say anything about string equality, they say that is_deeply will
walk the structures and that should include the structures of an overloaded
object.
What if you had overloaded eq on $ref and were accidentally always returning
true? is_deeply($ref, "any string") would be a pass.
I thought of another example of why it's wrong. Take $o1, $o2 and "string".
Say $o1 and $o2 both stringify to "string" but they are completely different
objects so. $o1 is deeply equal to "string", "string" is deeply equal to $o2
but $o1 and $o2 are not deeply equal to each other. This is not good.
> 'eq' still tests for string equality, not if an object really is the
> same.
> The latter may be the intent of _deep_check() and is_deeply() and
> friends,
> but using 'eq' I expect to compare stringifications.
>
> As for which method to check, using 'eq' to compare strings seems to ask
> for overload::Method($o, '""').
Nothing in the docs says that is_deeply will use eq. I would guess that the
reason it does is because eq can correctly compare numbers and strings and
will spot that "123" and "123a" are not the same. It is purely an
implementation detail and so could be subject to change.
Like I said, I've asked Michael Schwern for his take.
> The whole point of the module was to provide a way of transparently
> offering
> different methods of comparing a string with a thing (via string, regex,
> coderef) and anyone using 'eq' should never know the difference. If
> standard
> test methods won't work, I'll have to write special versions of
> _deep_check()
> et al, which would rather defeat the purpose of the module - if I know
> that
> I'm dealing with a special case, I don't need an object for that, I can
> just
> test what I'm comparing against.
The special version has been written already. Test::Deep handles everything
you want to do and much more. So instead of you writing a special version of
_deep_check(), I've written it already and it's designed to be special
caseable.
The docs may be a bit difficult to understand, opinions appreciated. Anyway,
here's your eq_hash test
my $hash1 = {
errors => {
attr1 => 'A pure string',
attr2 => '/home/marcel/lib/Foo/Bar.pm',
attr3 => 58,
attr4 => 'No such class',
},
};
my $exp = {
errors => {
attr1 => "A pure string",
attr2 => re(qr#.*/lib/Foo/Bar.pm#),
attr3 => re("/'\d+'/"),
attr4 => "No such class"
}
}
$hash1->{attr5} = 'This should not be here';
cmp_deeply($hash1, $exp, "Hash with extra key");
It's been around for months now, it's stable and it's easy to extend. Please
have a look and see if it does what you need,
F