Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Preventing changes to a module's variables in mod_perl

Reply
Thread Tools

Preventing changes to a module's variables in mod_perl

 
 
max@maxgraphic.com
Guest
Posts: n/a
 
      09-14-2006
I have a module that exists as a central data store, returning simple
scalars or references to larger structures. All of its data is stored
in a big hash, and I use AUTOLOAD to return the requested value.

The problem is that, with mod_perl, if the script that uses the module
changes the data (which with auto-vivication is pretty easy), the data
is changed for all subsequent scripts using that module run by that
particular apache child, which leads to the usual hair-pulling
intermittent bugs that mod_perl users historically puzzle over.

I've looked at a couple locking options, but the problem is that the
data can be arbitrarily deep references (which seems to rule out
Hash::Util). I might have MyModule->foo->{bar}{$baz}, and if $baz isn't
a valid key, it gets auto-vivified and there goes my weekend.

Is there a way I can prevent these changes from happening? And without
a huge performance penalty?

Thanks.

 
Reply With Quote
 
 
 
 
Ted Zlatanov
Guest
Posts: n/a
 
      09-14-2006
On 14 Sep 2006, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

> I have a module that exists as a central data store, returning simple
> scalars or references to larger structures. All of its data is stored
> in a big hash, and I use AUTOLOAD to return the requested value.
>
> The problem is that, with mod_perl, if the script that uses the module
> changes the data (which with auto-vivication is pretty easy), the data
> is changed for all subsequent scripts using that module run by that
> particular apache child, which leads to the usual hair-pulling
> intermittent bugs that mod_perl users historically puzzle over.
>
> I've looked at a couple locking options, but the problem is that the
> data can be arbitrarily deep references (which seems to rule out
> Hash::Util). I might have MyModule->foo->{bar}{$baz}, and if $baz isn't
> a valid key, it gets auto-vivified and there goes my weekend.


Can you return a tied hash where you control each operation on the
hash (retaining the syntax you have) to the effect you want? There
may even be a CPAN module that does what you want, though I'm not
aware of it.

Ted
 
Reply With Quote
 
 
 
 
Brian McCauley
Guest
Posts: n/a
 
      09-15-2006
(E-Mail Removed) wrote:

> I have a module that exists as a central data store, returning simple
> scalars or references to larger structures. All of its data is stored
> in a big hash, and I use AUTOLOAD to return the requested value.
>
> The problem is that, with mod_perl, if the script that uses the module
> changes the data (which with auto-vivication is pretty easy), the data
> is changed for all subsequent scripts using that module run by that
> particular apache child, which leads to the usual hair-pulling
> intermittent bugs that mod_perl users historically puzzle over.
>
> I've looked at a couple locking options, but the problem is that the
> data can be arbitrarily deep references (which seems to rule out
> Hash::Util).


The Readonly module claims to recursively follow deep structures (by
default).

Is there a reason you can't simply make the central data store readonly?

 
Reply With Quote
 
max@maxgraphic.com
Guest
Posts: n/a
 
      09-15-2006
Brian McCauley wrote:
> (E-Mail Removed) wrote:
>
> > I have a module that exists as a central data store, returning simple
> > scalars or references to larger structures. All of its data is stored
> > in a big hash, and I use AUTOLOAD to return the requested value.
> >
> > The problem is that, with mod_perl, if the script that uses the module
> > changes the data (which with auto-vivication is pretty easy), the data
> > is changed for all subsequent scripts using that module run by that
> > particular apache child, which leads to the usual hair-pulling
> > intermittent bugs that mod_perl users historically puzzle over.
> >
> > I've looked at a couple locking options, but the problem is that the
> > data can be arbitrarily deep references (which seems to rule out
> > Hash::Util).

>
> The Readonly module claims to recursively follow deep structures (by
> default).
>
> Is there a reason you can't simply make the central data store readonly?


Thanks. I had tried using Storable's dclone to return a copy, which
worked but was about a hundred times slower than just returning a
reference. Readonly seems to only be about four times slower.

Is there a way to get Readonly to warn instead of die when a
modification attempt is made?

 
Reply With Quote
 
Brian McCauley
Guest
Posts: n/a
 
      09-15-2006
(E-Mail Removed) wrote:

> Is there a way to get Readonly to warn instead of die when a
> modification attempt is made?


There's no such feature at the moment but it would be no biggie to add
if you wanted to. Just change the croaks() to carps().

 
Reply With Quote
 
max@maxgraphic.com
Guest
Posts: n/a
 
      09-15-2006

Brian McCauley wrote:
> (E-Mail Removed) wrote:
>
> > Is there a way to get Readonly to warn instead of die when a
> > modification attempt is made?

>
> There's no such feature at the moment but it would be no biggie to add
> if you wanted to. Just change the croaks() to carps().


Seemingly better still, Readonly uses its own croak wrapper, so adding

sub Readonly::croak { warn $_[0]; }

to my module seems to do the trick.

Thanks again for your help.

 
Reply With Quote
 
Brian McCauley
Guest
Posts: n/a
 
      09-15-2006

(E-Mail Removed) wrote:
> Brian McCauley wrote:
> > (E-Mail Removed) wrote:
> >
> > > Is there a way to get Readonly to warn instead of die when a
> > > modification attempt is made?

> >
> > There's no such feature at the moment but it would be no biggie to add
> > if you wanted to. Just change the croaks() to carps().

>
> Seemingly better still, Readonly uses its own croak wrapper, so adding
>
> sub Readonly::croak { warn $_[0]; }
>
> to my module seems to do the trick.


You'd probably get more informative errors with

sub Readonly::croak {
require Carp;
goto &Carp::carp;
}

The problem with this approach is it breaks any other uses of Readonly
that are going on in other modules that anyone who happens to use your
module is also using.

 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      09-18-2006
Brian McCauley <(E-Mail Removed)> wrote in comp.lang.perl.misc:
>
> (E-Mail Removed) wrote:
> > Brian McCauley wrote:
> > > (E-Mail Removed) wrote:
> > >
> > > > Is there a way to get Readonly to warn instead of die when a
> > > > modification attempt is made?
> > >
> > > There's no such feature at the moment but it would be no biggie to add
> > > if you wanted to. Just change the croaks() to carps().

> >
> > Seemingly better still, Readonly uses its own croak wrapper, so adding
> >
> > sub Readonly::croak { warn $_[0]; }
> >
> > to my module seems to do the trick.

>
> You'd probably get more informative errors with
>
> sub Readonly::croak {
> require Carp;
> goto &Carp::carp;
> }
>
> The problem with this approach is it breaks any other uses of Readonly
> that are going on in other modules that anyone who happens to use your
> module is also using.


The substitution can be localized to a block or file:

local *Readonly::croak = sub {
require Carp;
goto &Carp::carp;
};

Anno
 
Reply With Quote
 
Brian McCauley
Guest
Posts: n/a
 
      09-19-2006

http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de wrote:
> Brian McCauley <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> >
> > You'd probably get more informative errors with
> >
> > sub Readonly::croak {
> > require Carp;
> > goto &Carp::carp;
> > }
> >
> > The problem with this approach is it breaks any other uses of Readonly
> > that are going on in other modules that anyone who happens to use your
> > module is also using.

>
> The substitution can be localized to a block or file:
>
> local *Readonly::croak = sub {
> require Carp;
> goto &Carp::carp;
> };


No! local() is dynamically scoped not lexical. Changes made with
local() are _not_ localized to a block or file but to a stack frame
(and subframes thereof).

Anyhow, even if it where lexical it would help the OP since he wants to
control the behaviour of complex data structures returned by his
modules when code outwith his control tries to modify them.

 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      09-19-2006
Brian McCauley <(E-Mail Removed)> wrote in comp.lang.perl.misc:
>
> (E-Mail Removed)-berlin.de wrote:
> > Brian McCauley <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> > >
> > > You'd probably get more informative errors with
> > >
> > > sub Readonly::croak {
> > > require Carp;
> > > goto &Carp::carp;
> > > }
> > >
> > > The problem with this approach is it breaks any other uses of Readonly
> > > that are going on in other modules that anyone who happens to use your
> > > module is also using.

> >
> > The substitution can be localized to a block or file:
> >
> > local *Readonly::croak = sub {
> > require Carp;
> > goto &Carp::carp;
> > };

>
> No! local() is dynamically scoped not lexical. Changes made with
> local() are _not_ localized to a block or file but to a stack frame
> (and subframes thereof).


Yes, of course. That means, once control has left the block the change
is reverted. In simple cases that may be good enough.

> Anyhow, even if it where lexical it would help the OP since he wants to
> control the behaviour of complex data structures returned by his
> modules when code outwith his control tries to modify them.


Hmm... tie() comes to mind then.

I admit I've lost context of the thread, so I'm not sure if that big
gun is warranted. Maybe a certain module named Tie::OneOff could be
useful...

Anno
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Put variables into member variables or function variables? tjumail@gmail.com C++ 9 03-23-2008 04:03 PM
preventing session variables from going null javelin ASP General 5 12-19-2006 03:49 PM
mod_perl installed, but mod_perl.so file not created bennett@peacefire.org Perl Misc 2 01-25-2006 10:53 PM
mod_perl and global variables during startup nicc777 Perl Misc 2 07-13-2005 02:18 PM
Global variables in mod_perl Gunnar Hjalmarsson Perl Misc 6 05-18-2004 09:56 AM



Advertisments