List Info

Thread: $r->pnotes stores aliases not copies so is subject to action at a distanc




$r->pnotes stores aliases not copies so is subject to action at a distanc
user name
2007-11-06 10:47:46
so, I've been thinking a bit about this and I think I recall
the
original reasoning way back when...

  my $obj = $class->new();
  $r->pnotes(OBJ => $obj);

I am almost certain that this was the original use case for
pnotes as I
dig into my mind and recall the time on the list where folks
were like
"wow!  we can pass a perl scalar around the
request."  what this, um,
feature allows users to do is alter the underlying object
without
re-storing it along the way:

  $obj->update_user();
  # next guy to pull it from pnotes gets the current state

over the years I think we will find that people do that kind
of thing
_all the time_ with pnotes.

anyway, I'm not arguing here, but I was trying to figure out
why it was
done this way in the first place - doug didn't just do stuff
at random,
but tended to add features that were dwimmy for the
use-cases of the
dot-com era 

--Geoff

-------- Original Message --------
Subject: [rt.cpan.org #30061] $r->pnotes stores aliases
not copies so is
subject to action at a distance
Date: Tue, 06 Nov 2007 11:31:51 -0500
From: Tim_Bunce via RT <bug-mod_perlrt.cpan.org>
Reply-To: bug-mod_perlrt.cpan.org
To: undisclosed-recipients:;
References: <RT-Ticket-30061rt.cpan.org>


       Queue: mod_perl
 Ticket <URL: http:
//rt.cpan.org/Ticket/Display.html?id=30061 >

I've just been bitten by this bug again!

What's wrong with this code:

sub foo {
    my ($r, $status, $why) = _;
    $r->pnotes('foo', ($why) ? "$status:$why" :
$status);
    return;
}

Nothing, except it doesn't work as expected due to this
pnotes bug: If
the same code is
called in a sub-request then the pnote of $r->prev is
magically updated
at a distance to the
same value!

Try explain why that is to anyone not deeply familar with
perl internals!

The fix is to avoid pnotes taking a ref to the invisible
op_targ
embededed in the code by
passing a simple lexical variable as the actual argument.
That can be
done in-line like this:

sub mark_as_internally_redirected {
    my ($r, $status, $why) = _;
    $r->pnotes('foo', my $tmp = (($why) ?
"$status:$why" : $status));
    return;
}

At the very least the docs need a big warning that the
second argument
to the pnotes
method should only be a simple lexical variable.

------------------------------------------------------------
---------
To unsubscribe, e-mail: dev-unsubscribeperl.apache.org
For additional commands, e-mail: dev-helpperl.apache.org


Re: $r->pnotes stores aliases not copies so is subject to action at a dis
user name
2007-11-06 10:56:44

Geoffrey Young wrote:
> so, I've been thinking a bit about this and I think I
recall the
> original reasoning way back when...
> 
>   my $obj = $class->new();
>   $r->pnotes(OBJ => $obj);
> 
> I am almost certain that this was the original use case
for pnotes as I
> dig into my mind and recall the time on the list where
folks were like
> "wow!  we can pass a perl scalar around the
request."  what this, um,
> feature allows users to do is alter the underlying
object without
> re-storing it along the way:
> 
>   $obj->update_user();
>   # next guy to pull it from pnotes gets the current
state

actually, that will happen anyway I guess... it's a feature
of
references that will make that work regardless of whether we
copy or
alias the scalar in pnotes.

so nevermind... my brane is starting to dissolve of late...

--Geoff

------------------------------------------------------------
---------
To unsubscribe, e-mail: dev-unsubscribeperl.apache.org
For additional commands, e-mail: dev-helpperl.apache.org


[1-2]

about | contact  Other archives ( Real Estate discussion Medical topics )