On 7/1/05, Michael G Schwern <[EMAIL PROTECTED]> wrote: > After talking with Ovid some in the kitchen I'm of the opinion that > is_deeply() is currently doing the right thing and that these tests cannot > go. Largely it comes down to the Principle of Least Surprise.
I cant agree with this analysis. If you go down this route surprise abounds. (From my earlier post) is_deeply($x,$y); #ok $x->[0]{a}=1; $y->[0]{a}=1; is_deeply($x,$y); #Surprise! Thats a MUCH bigger surprise IMO. And a fatal one for anybody really relying on is_deeply. > Here's an example. A user wants to test the results of some function that, > in this situation, includes some duplicated data. So they might construct > their "expected" structure like so to save a little time: > > my %thing = { foo => 42, bar => 23 }; > > my %expect = ( stuff => 23, > wiff => \%thing, > wham => \%thing > ); As I think ive seen you do elsewhere just tell them NOT to do that. What they should do is simple: my %expect = ( stuff => 23, wiff => {%thing}, wham => {%thing} ); IMO this is a perfectly acceptable requirement. > > Internally the code might not reuse the same reference. The user would be > very surprised if the comparison failed. Well i can see two cases for surprise, the majority would be programmers going doh, of course they arent the same, and the minority being the ones pleasently surprised that we had just caught a bug they hadnt noticed before. > In fact, I would even argue that > this violates some of the black boxness of the test. In much the same way > that we don't check to see if a given piece of data is blessed, tied or > overloaded, we wouldn't care if we have a repeating reference or two > different references to equivalent data. But they COMPLETELY change the datastructure. Utterly and totally. The question you have to ask yourself is why should a reference be treated different from any other value? It is a VALUE. IE: why should $x=1;$y=2;$z=3; $a1=[$x,$x]; $a2=[$y,$z]; $a1 and $a2 are different but $x={};$y={};$z={}; $a3=[$x,$x]; $a4=[$y,$z]; $a3 and $a4 are not? Isn't the situation identical? Consider # add one to each of the arrays for my $ar ($a1,$a2,$a3,$a4) { $_=0+$_ @$ar; } so now the refs turn into their addresses and you will consider them different? This just doesnt make sense. > > Furthermore, the current behavior provides the more flexible option. If > a user doesn't care about the particulars of the references in their > structure, is_deeply() works. If they dont care then they should use some other tool beside is_deeply(). maybe a new sub called looks_like() or something, but is_deeply should be reliable and do what its name says. The fact is it wouldnt be too difficult to support both off of the same code base. It would just be a flag into the internal routine. > If they *do* then the user can always run > an addition test. But if we made is_deeply() repeating reference aware then > the user who does not care about that cannot use is_deeply() at all. > > So, I conclude that is_deeply()'s behavior is ok and something like Test::Deep > should be enhanced with an option to deal with this problem. Ok, ill make my last defense. For this decision you gain what? You gain a saving of ONE KEYSTROKE. (instead of being lazy and saying \%obj you say { %obj } ). What do you lose? The ability to use this routine safely at all. The only people that will be able to use this routine wont actually be doing deep comparisons. Not only that you propogate a bad meme, that is_deeply does deep structural comparison when it doesnt. This means that lots of users out there think that if two structures are is_deeply() then they are equivelent, little do they know of course that arent _at_all_. I personally feel that the Test modules have a duty or obligation to not propagate mistaken understandings in the community. is_deeply() should be robust and reliable. It should be a standard bearer for the community. Making is_deeply() behave in such a broken behaviour is just bad for Perl in general. And for such little advantage? IMO if people want a tool like you think is_deeply() should behave then you should provide one. But dont pretend is_deeply() does a deep comparison when it really doesnt. Referential integrity of the structural comparison should be just as important as the value comparision as this data can be vital to complex programming tasks. Im happy to do the work to fix is_deeply() and also to provide looks_like(). I do not think this should be in another module as the amount of code change to what you have is pretty minimal. -- perl -Mre=debug -e "/just|another|perl|hacker/"