On 7/5/05, Andrew Pimlott <[EMAIL PROTECTED]> wrote:
> On Tue, Jul 05, 2005 at 01:24:38AM +0100, Fergal Daly wrote:
> > There's an easy way to see what's "accptable" and what's not and what
> > exactly this level equality means. Consider the following code
> > template:
> >
> > #######
> > # lots of stuff doing anything you like including
> > # setting global variables
> >
> > my $value = do {
> > # these can access any globals etc
> >   my $a = one_way();
> >   my $b = another_way();
> >   is_very_deeply($a, $b) || die "they're distinuguishable";
> >
> >   # choose one of $a and $b at random
> >   rand(2) < 1 ? $a : $b;
> > };
> >
> > print test($value);
> > #######
> 
> my $x = [];
> sub one_way = { $x }
> sub another_way = { [] }
> sub test = { $_[0] == $x }
> 
> I don't think this breaks your rules, but see below.

You're right, I messed that up by trying to allow the use globals in
the structure.

If you don't use globals (you can still have lexically scoped globals
in the wherever one_way() and another_way() are defined, as long as
test() has no way of reaching them) then it's true, if you do want to
use globals then you actually have to test

is_very_deeply(
# all the globals that either of them include in their results
# the lists must be identical otherwise the result will obviously
distinguishable
  [$a, \$global1, \$global2, ...],
  [$b, \$global1, \$global2, ...]
);


> > Then test() cannot tell whether it got $a or $b. That is, any attempt
> > by one_way() or another_way() to communicate with test() will be
> > caught by is_very_deeply().
> >
> > In this case it's clear that
> >
> > sub test
> > {
> >   $_[0] == $a
> > }
> >
> > is not acceptable because only one of $a and $b ever makes it back
> > into program flow and at that point it's got a new name.
> 
> I don't understand what you're saying here.  As you've written it, $a in
> test is unrelated to the $a and $b in your do statement above, so your
> test will return false in both cases.  Is that all you meant?

Kind of. The point was that you can't even refer to $a (the one that's
in the do block) or $b in this situation.

Here's another way to see why disallowing sub { $_[0] == $a } is not
an artificial restriction. When you're testing you construct $a and $b
and in this situation you could use $a or $b to try to identify which
one you have but testing is not what you really care about. What
matters is if there will be a difference in behaviour when a client
program uses your library. In this situation you don't have  $a _and_
$b - only one of them gets created because the client program uses
only one of the data constuctors - so sub {$_[0] == $a} either makes
no sense (in that there is no $a) or is always true because $_[0] is
always $a (because there is no $b).

> Anyway, I don't think you're rejecting my test.  If you do reject my
> test, tell me which assumption I violated.

None, I came up with the same example just as I was getting into bed.
I should have thought more about the globals before allowing them,

F

Reply via email to