On Thursday 16 March 2006 00:39, Geoffrey Young wrote:
> >>>in order for $o to maintain it's internal state. is that right? if so,
> >>> I don't like that very much.
> >
> > It's not right. You are confusing scalars with references in that
> > example.
>
> ook, my bad - I thought the proposed "solution" was to always dereference
> pnotes behind the scenes, making the additional storage a requirement.
>
> but, just in case I'm not the only one confused, I'd propose a path like
> this...
>
> o create some (many?) additional pnotes tests that exercise the different
> ways we think people will be using pnotes in almost all normal
> circumstances we can think of. digging through CPAN might be a good idea.
>
> o offer that any fix shouldn't break the tests
Here are some tests that cover your concerns so far:
package TestPn::pn;
use strict;
use warnings FATAL => 'all';
use Apache::Test;
use Apache::TestUtil;
use Apache2::RequestUtil;
use Apache2::Const -compile => 'OK';
{
package _O;
sub new {bless {}=>__PACKAGE__}
sub member {$_[0]->{x}=$_[1] if @_>1; $_[0]->{x}}
}
sub handler {
my $r = shift;
Apache::Test::test_pm_refresh();
plan $r, tests => 20;
my $x;
# pnotes as hash ref
# this 1st set of tests are all ok, because $r->pnotes returns a normal
# hash ref
$x=1;
$r->pnotes->{x}=$x;
$x++;
ok t_cmp $r->pnotes('x'), 1, q{hash ref1};
ok t_cmp $r->pnotes->{x}, 1, q{hash ref2};
delete $r->pnotes->{x};
# pnotes method interface
# these two fail
$x=1;
$r->pnotes(x=>$x);
$x++;
ok t_cmp $r->pnotes('x'), 1, q{method1};
ok t_cmp $r->pnotes->{x}, 1, q{method2};
delete $r->pnotes->{x};
# pnotes as hash: storing and retrieving objects
my $o1=_O->new;
$o1->member(1);
my $o2=_O->new;
$o2->member(2);
# check if the objects work properly
ok t_cmp $o1->member, 1, q{o1 setup};
ok t_cmp $o2->member, 2, q{o2 setup};
# these tests succeed. they show normal object behavior.
$r->pnotes->{o}=$o1;
$o1->member(10);
ok t_cmp $r->pnotes('o')->member, 10, q{hash ref obj 1};
ok t_cmp $r->pnotes->{o}->member, 10, q{hash ref obj 2};
$r->pnotes('o')->member(100);
ok t_cmp $r->pnotes('o')->member, 100, q{hash ref obj 3};
ok t_cmp $r->pnotes->{o}->member, 100, q{hash ref obj 4};
# the following two succeed only because the hash ref interface
# was used to assing $r->pnotes->{o}.
$o1=$o2;
ok t_cmp $r->pnotes('o')->member, 100, q{hash ref obj 5};
ok t_cmp $r->pnotes->{o}->member, 100, q{hash ref obj 6};
delete $r->pnotes->{o};
# pnotes method interface: storing and retrieving objects
$o1=_O->new;
$o1->member(1);
$o2=_O->new;
$o2->member(2);
ok t_cmp $o1->member, 1, q{o1 setup};
ok t_cmp $o2->member, 2, q{o2 setup};
$r->pnotes(o=>$o1);
$o1->member(10);
ok t_cmp $r->pnotes('o')->member, 10, q{method obj 1};
ok t_cmp $r->pnotes->{o}->member, 10, q{method obj 2};
$r->pnotes('o')->member(100);
ok t_cmp $r->pnotes('o')->member, 100, q{method obj 3};
ok t_cmp $r->pnotes->{o}->member, 100, q{method obj 4};
# these two fail, because the assignment $o1=$o2 modifies $r->pnotes->{o}.
$o1=$o2;
ok t_cmp $r->pnotes('o')->member, 100, q{method obj 5};
ok t_cmp $r->pnotes->{o}->member, 100, q{method obj 6};
delete $r->pnotes->{o};
Apache2::Const::OK;
}
1;
The patch is IMO really simple:
In xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h and
xs/Apache2/RequestUtil/Apache2__RequestUtil.h
if (val) {
retval = *hv_store(ccfg->pnotes, k, len,
- SvREFCNT_inc(val), 0);
+ newSVsv(val), 0);
}
else if (hv_exists(ccfg->pnotes, k, len)) {
retval = *hv_fetch(ccfg->pnotes, k, len, FALSE);
The attached patch was made a few days ago. It applies to r384596 with the
connection-pnotes patch applied before. All tests succeed.
Torsten
diff -Naur r384596-cnotes/t/modperl/pnotes.t pnotes/t/modperl/pnotes.t
--- r384596-cnotes/t/modperl/pnotes.t 2006-03-10 21:23:28.465092006 +0100
+++ pnotes/t/modperl/pnotes.t 2006-03-10 21:32:55.647505579 +0100
@@ -10,7 +10,7 @@
t_debug("connecting to $url");
-plan tests => (22 * 3);
+plan tests => (24 * 3);
# first with keepalives
Apache::TestRequest::user_agent(reset => 1, keep_alive => 1);
diff -Naur r384596-cnotes/t/response/TestModperl/pnotes.pm pnotes/t/response/TestModperl/pnotes.pm
--- r384596-cnotes/t/response/TestModperl/pnotes.pm 2006-03-10 21:23:28.462092410 +0100
+++ pnotes/t/response/TestModperl/pnotes.pm 2006-03-10 21:33:07.117987774 +0100
@@ -17,8 +17,8 @@
# make it ok to call ok() here while plan()ing elsewhere
Apache::Test::init_test_pm($r);
-$Test::ntest = 1 + (22 * ($r->args - 1));
-$Test::planned = 22;
+$Test::ntest = 1 + (24 * ($r->args - 1));
+$Test::planned = 24;
my $c