You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Doug MacEachern <do...@covalent.net> on 2000/06/01 20:59:53 UTC

Re: global variables and reparsing question (low priority ;)

forget about mod_perl for a moment.  yes, true, Perl's built-in require
will not reload a module if it's already in %INC.  but that's doesn't mean
a Perl environment cannot un-cache that entry so it will be reloaded.
consider the code below, pretend that loop is a long-lifetime server,
Tk type application, vi or emacs with Perl embedded:

use Module::Reload ();

do {
    Module::Reload->check;
    require Foo;
} while (<STDIN>);

Module::Reload checks the mtime of Foo.pm (and all loaded modules) on
disk, if it has changed since the last time it was require'd, it will be
reloaded.  this is perfectly valid Perl, the language supports this
feature.  i'm quite certain your code be changed to adapt to such an
environment.


Re: global variables and reparsing question (low priority ;)

Posted by Perrin Harkins <pe...@primenet.com>.
On Thu, 1 Jun 2000, Marc Lehmann wrote:
> It's easy, I just have to kick my ass each time I want to use a lexical
> for data abstraction and use a package variable instead, with only the
> exception that I have to be very careful that I never re-use the same
> name. This is quite difficult for code that resides in many files (package
> variables are, of course, global to the whole package not just the file or
> the block), but not unsolvable.

The simplest thing is to just not use PerlFreshRestart or Apache::StatINC
(which works in a similar way).  These are generally a bad idea for
production servers anyway, due to their effect on shared memory, and
mostly exist to ease development, although in your case they had the
opposite effect.  There are several warnings about mysterious problems
caused by PerlFreshRestart in the guide, and my impression is that most
people simply avoid it altogether.

If you don't use these your code should work just fine, lexicals,
accessors, and all.

- Perrin


Re: global variables and reparsing question (low priority ;)

Posted by Marc Lehmann <pc...@goof.com>.
On Thu, Jun 01, 2000 at 11:59:53AM -0700, Doug MacEachern <do...@covalent.net> wrote:
> will not reload a module if it's already in %INC.  but that's doesn't mean
> a Perl environment cannot un-cache that entry so it will be reloaded.
> consider the code below, pretend that loop is a long-lifetime server,

Doing that, however, breaks code that uses documented and recommended
techniques (see perltoot for the best example).

My problem is not that it is possible to actively break code within normal
perl, this is easy in any language.

> Module::Reload checks the mtime of Foo.pm (and all loaded modules) on
> disk, if it has changed since the last time it was require'd, it will be
> reloaded.  this is perfectly valid Perl, the language supports this
> feature.

You miss a very large point: Modules are not just files containing perl
code.  One of the features of modules is that, how often you might use
them, they are only loaded once (unlike "do EXPR", for example).

Sure, you can load modules in different ways, even in ways that break
them, and the code still runs under perl (that is, without syntax error),
but this has not much to do with perl's concept of modules anymore.

> i'm quite certain your code be changed to adapt to such an environment.

It's easy, I just have to kick my ass each time I want to use a lexical
for data abstraction and use a package variable instead, with only the
exception that I have to be very careful that I never re-use the same
name. This is quite difficult for code that resides in many files (package
variables are, of course, global to the whole package not just the file or
the block), but not unsolvable.

You see, my first problem was misunderstanding (or not understanding) what
apache does during the "module initialization phase", and how "reload"
is defined (namely by not deleting the package). I assumed that a "fresh
restart" would imply a fresh perl interpreter, or at least a fresh
package, not just loading the code over the old one, preserving it.

While I am not sure why PerlFreshRestart is implemented in this misleading
manner, I can definitely live with that, as it is an option that can be
turned off, which is much more than one can expect (namely nothing at
all!), and, given that this is not considered a bug but a limitation with
mod_perl (spec. that single option), can be worked around consistently (as
it is relatively minor). The biggest problem with PerlFreshRestart is that
it causes bugs which are very difficult to find and that might only be
found after a lot of debugging, as the problem might be in a third-party
module you have never seen the source code of.

The more important aspects of mod_perl of course work fine, and this is
what counts most. So consider that totally solved to my satisfaction.

(Indirectly) calling my code broken (ah, you probably see where the
problem is, now ;), however, will require some very good arguments from
your side, which you didn't give so far.

Especially I'd like to hear why perltoot (and others) actively encourage
these "broken" programming techniques that enable data hiding and
definitely work with "perl modules": Surely I can load a .pm file using
other methods, like "do", or by nuking the %INC entry, but changing the
behaviour of "use" so drastically changes the notion of "modules" as well.

In my opinion, using a different way of loading modules than the
documented one, a way that breaks modules that work fine under the
documented mechanism, does not magically turn recommended code practises
into broken code practises.

-- 
      -----==-                                             |
      ----==-- _                                           |
      ---==---(_)__  __ ____  __       Marc Lehmann      +--
      --==---/ / _ \/ // /\ \/ /       pcg@opengroup.org |e|
      -=====/_/_//_/\_,_/ /_/\_\       XX11-RIPE         --+
    The choice of a GNU generation                       |
                                                         |