Loading ...
Sorry, an error occurred while loading the content.

PATCH porting.pod "First Mystery"

Expand Messages
  • nobull@cpan.org
    ... Patch for The First Mystery section of the mod_perl porting guide as per my conversation with Stas at YAPC::Europe::2003. Takes out the suggestion of
    Message 1 of 20 , Aug 22, 2003
    • 0 Attachment
      In private mail Stas Bekman <stas@...> writes:

      > oops, that should be the modperl list... at modperl-docs we discuss
      > mostly site/docs techical issues and there are very few people on this
      > list to get enough exposure for this kind of feedback request.

      Patch for "The First Mystery" section of the mod_perl porting guide as
      per my conversation with Stas at YAPC::Europe::2003.

      Takes out the suggestion of creating a Perl4-style library in the same
      directory as a means to port CGI scripts.

      Replaces it with something simpler and more reliable.

      I've also changed "If you put your code into a library or module..."
      to "If you put all your code into modules..." because if you put your
      code into a Perl4-style library and then require it in more than one
      registry script terrible things happen. I don't think this is the
      place to explain this so I think the guide should just say "modules"
      and leave it at that.

      Probably the library problem should be explained elsewhere in the
      guide.

      Once this one is sorted out, a patch for perl_reference.pod will follow.

      --- porting.pod.orig Thu Aug 14 18:02:27 2003
      +++ porting.pod Fri Aug 15 13:37:33 2003
      @@ -228,44 +228,42 @@

      It's important to understand that the I<inner subroutine> effect
      happens only with code that C<Apache::Registry> wraps with a
      -declaration of the C<handler> subroutine. If you put your code into a
      -library or module, which the main script require()'s or use()'s, this
      -effect doesn't occur.
      +declaration of the C<handler> subroutine. If you put all your code
      +into modules, which the main script use()s, this effect doesn't occur.

      -For example if we move the code from the script into the subroutine
      -I<run>, place the subroutines into the I<mylib.pl> file, save it in
      -the same directory as the script itself and require() it, there will
      -be no problem at all. (Don't forget the C<1;> at the end of the
      -library or the require() might fail.)
      +Do not use simple Perl4-style libraries located in the same directory
      +as the script. This technique was recommended by a previous version
      +of this guide but is seriously flawed. Subroutines in such libraries
      +will only be available to the first script in any given interpreter
      +thread to require() a library of any given name. This can lead to
      +strange sporadic failures. It also won't work at all under mod_perl2
      +because the current working directory is not the directory containing
      +the script.
      +
      +The easiest and the fastest way to solve the nested subroutines
      +problem is to change C<my> to C<local> C<our> for all variables for
      +which you get the warning. The C<handler> subroutines are never
      +called re-entrantly and each resides in a package to itself. Most of
      +the usual disadvantates of package scoped variables are, therefore,
      +not a concern.

      - mylib.pl:
      - ---------
      - my $counter;
      - sub run{
      - print "Content-type: text/plain\r\n\r\n";
      - $counter = 0;
      - for (1..5) {
      - increment_counter();
      - }
      + counter.pl:
      + ----------
      + #!/usr/bin/perl -w
      + use strict;
      +
      + print "Content-type: text/plain\r\n\r\n";
      +
      + local our $counter = 0;
      +
      + for (1..5) {
      + increment_counter();
      }
      +
      sub increment_counter{
      $counter++;
      print "Counter is equal to $counter !\r\n";
      }
      - 1;
      -
      - counter.pl:
      - ----------
      - use strict;
      - require "./mylib.pl";
      - run();
      -
      -This solution provides the easiest and the fastest way to solve the
      -nested subroutines problem, since all you have to do is to move the
      -code into a separate file, by first wrapping the initial code into
      -some function that you later will call from the script and keeping the
      -lexically scoped variables that could cause the problem out of this
      -function.

      But as a general rule of thumb, unless the script is very short, I
      tend to write all the code in external libraries, and to have only a


      --
      Reporting bugs: http://perl.apache.org/bugs/
      Mail list info: http://perl.apache.org/maillist/modperl.html
    • Stas Bekman
      ... ... [...] ... local our? That should be either local or our, but not both. Do I miss something? The rest looks good, but that s not the simplest solution
      Message 2 of 20 , Aug 29, 2003
      • 0 Attachment
        nobull@... wrote:
        > In private mail Stas Bekman <stas@...> writes:
        >
        >
        >>oops, that should be the modperl list... at modperl-docs we discuss
        >>mostly site/docs techical issues and there are very few people on this
        >>list to get enough exposure for this kind of feedback request.
        >
        >
        > Patch for "The First Mystery" section of the mod_perl porting guide as
        > per my conversation with Stas at YAPC::Europe::2003.
        >
        > Takes out the suggestion of creating a Perl4-style library in the same
        > directory as a means to port CGI scripts.
        >
        > Replaces it with something simpler and more reliable.

        Nice, but:

        > +The easiest and the fastest way to solve the nested subroutines
        > +problem is to change C<my> to C<local> C<our> for all variables for
        > +which you get the warning. The C<handler> subroutines are never
        ...
        [...]
        > + local our $counter = 0;

        local our? That should be either local or our, but not both. Do I miss something?

        The rest looks good, but that's not the simplest solution as you have to
        modify the variables. Granted, the original "simplest" solution has its troubles.

        > I've also changed "If you put your code into a library or module..."
        > to "If you put all your code into modules..." because if you put your
        > code into a Perl4-style library and then require it in more than one
        > registry script terrible things happen. I don't think this is the
        > place to explain this so I think the guide should just say "modules"
        > and leave it at that.
        >
        > Probably the library problem should be explained elsewhere in the
        > guide.
        >
        > Once this one is sorted out, a patch for perl_reference.pod will follow.

        Sure, sounds good to me.

        __________________________________________________________________
        Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
        http://stason.org/ mod_perl Guide ---> http://perl.apache.org
        mailto:stas@... http://use.perl.org http://apacheweek.com
        http://modperlbook.org http://apache.org http://ticketmaster.com



        --
        Reporting bugs: http://perl.apache.org/bugs/
        Mail list info: http://perl.apache.org/maillist/modperl.html
      • Brian McCauley
        ... No. ... Yes. (I tried to explain this in Paris but I was in danger of causing you to miss lunch completely). local() and our() do two quite separate and
        Message 3 of 20 , Sep 1 1:29 AM
        • 0 Attachment
          Stas Bekman <stas@...> writes:

          > nobull@... wrote:
          > > In private mail Stas Bekman <stas@...> writes:
          > >
          > >>oops, that should be the modperl list... at modperl-docs we discuss
          > >>mostly site/docs techical issues and there are very few people on this
          > >>list to get enough exposure for this kind of feedback request.
          > > Patch for "The First Mystery" section of the mod_perl porting guide
          > > as
          > > per my conversation with Stas at YAPC::Europe::2003.
          > > Takes out the suggestion of creating a Perl4-style library in the
          > > same
          > > directory as a means to port CGI scripts.
          > > Replaces it with something simpler and more reliable.
          >
          > Nice, but:
          >
          > > +The easiest and the fastest way to solve the nested subroutines
          > > +problem is to change C<my> to C<local> C<our> for all variables for
          > > +which you get the warning. The C<handler> subroutines are never
          > ...
          > [...]
          > > + local our $counter = 0;
          >
          > local our? That should be either local or our, but not both.

          No.

          > Do I miss something?

          Yes. (I tried to explain this in Paris but I was in danger of causing
          you to miss lunch completely).

          local() and our() do two quite separate and complementary things.

          our() (in effect) declares a lexically scoped alias for a package
          variable.

          local() restores the old value of a package variable (usually undef)
          at the end of the current lexical scope.

          The two combined therefore give a package variable two of the most
          useful properties of a lexical one. Of course a real lexical variable
          doesn't really become undefined when it does out of scope - it really
          becomes anonymous, and iff there are no remaining (unweakened)
          references it then gets GCed. But for file-scoped lexicals in the
          main script file the difference is usually not that important. Both
          effectively get killed at the point where global destruction would
          have taken place.

          > The rest looks good, but that's not the simplest solution as you have
          > to modify the variables.

          Is there a simpler one? For a typical script with say half a dozen
          variables the "would not remain shared" the "local our" solution
          requires a dozen keystokes on each of half a dozen lines.

          > Granted, the original "simplest" solution has its troubles.

          The original "simplest" solution involved finding (and subsequently
          maintaining) a globally unique filename then splitting the program in
          to two parts. Thereafer you have to maintain two files even on CGI
          servers. I would contend that this "simple solution" is not simple.
          If you are going to all that troble you may as well to the extra
          804.65m and produce a proper mod_perl handler and a small wrapper to
          make it work also in a CGI environment. Also, as of mod_perl2, the
          "simple solution" is not even, as it stands, a solution as it relied
          on the script being in the CWD.


          --
          Reporting bugs: http://perl.apache.org/bugs/
          Mail list info: http://perl.apache.org/maillist/modperl.html
        • Stas Bekman
          Brian McCauley wrote: [...] ... In effect you use local() to undef the variable, instead of explicitly initializing it. Why not doing this explictly? so
          Message 4 of 20 , Sep 2 11:17 AM
          • 0 Attachment
            Brian McCauley wrote:
            [...]
            >>Nice, but:
            >>
            >> > +The easiest and the fastest way to solve the nested subroutines
            >> > +problem is to change C<my> to C<local> C<our> for all variables for
            >> > +which you get the warning. The C<handler> subroutines are never
            >>...
            >>[...]
            >> > + local our $counter = 0;
            >>
            >>local our? That should be either local or our, but not both.
            >
            >
            > No.
            >
            >
            >>Do I miss something?
            >
            >
            > Yes. (I tried to explain this in Paris but I was in danger of causing
            > you to miss lunch completely).
            >
            > local() and our() do two quite separate and complementary things.
            >
            > our() (in effect) declares a lexically scoped alias for a package
            > variable.
            >
            > local() restores the old value of a package variable (usually undef)
            > at the end of the current lexical scope.

            In effect you use local() to undef the variable, instead of explicitly
            initializing it. Why not doing this explictly?

            so instead of replacing:

            my $counter;

            with:

            local our $counter;

            it's probably better to say:

            our $counter = 0;

            or if you insist on using both:

            our $counter;
            local $counter; # undef $counter

            later on I show why this is better for user's understanding.

            > The two combined therefore give a package variable two of the most
            > useful properties of a lexical one. Of course a real lexical variable
            > doesn't really become undefined when it does out of scope - it really
            > becomes anonymous, and iff there are no remaining (unweakened)
            > references it then gets GCed. But for file-scoped lexicals in the
            > main script file the difference is usually not that important. Both
            > effectively get killed at the point where global destruction would
            > have taken place.
            >
            >
            >>The rest looks good, but that's not the simplest solution as you have
            >>to modify the variables.
            >
            >
            > Is there a simpler one? For a typical script with say half a dozen
            > variables the "would not remain shared" the "local our" solution
            > requires a dozen keystokes on each of half a dozen lines.

            Don't forget that our() is not available before perl 5.6. So we can't quite
            eliminate the previous solution unless you suggest to go with a
            back-compatible version:

            use vars qw($counter);
            local $counter;

            and of course the proper solution is:

            use vars qw($counter);
            $counter = 0; # or undef

            which is documented in the perl reference section.

            >>Granted, the original "simplest" solution has its troubles.
            >
            >
            > The original "simplest" solution involved finding (and subsequently
            > maintaining) a globally unique filename then splitting the program in
            > to two parts. Thereafer you have to maintain two files even on CGI
            > servers. I would contend that this "simple solution" is not simple.
            > If you are going to all that troble you may as well to the extra
            > 804.65m and produce a proper mod_perl handler and a small wrapper to
            > make it work also in a CGI environment. Also, as of mod_perl2, the
            > "simple solution" is not even, as it stands, a solution as it relied
            > on the script being in the CWD.

            Remember, we are talking about mp1 guide patching. Not everything that applies
            to mp1 applies to mp2. e.g., mp2 requires 5.6+, so we indeed can rely on using
            our() there. And I hope that the problem with CWD will be resolved once Arthur
            will fix that.

            If you think that using globals + their initialization is a better solution,
            which will work well in mp1 and mp2, we can replace the lib.pl solution with
            it, but should add it to the perl reference section.

            __________________________________________________________________
            Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
            http://stason.org/ mod_perl Guide ---> http://perl.apache.org
            mailto:stas@... http://use.perl.org http://apacheweek.com
            http://modperlbook.org http://apache.org http://ticketmaster.com



            --
            Reporting bugs: http://perl.apache.org/bugs/
            Mail list info: http://perl.apache.org/maillist/modperl.html
          • Brian McCauley
            ... Firstly it s conceptually neater to use local. I want to think of the variable as local rather than as a global variable that needs to be explicitly
            Message 5 of 20 , Sep 3 10:12 AM
            • 0 Attachment
              Stas Bekman <stas@...> writes:

              > Brian McCauley wrote:
              > [...]
              > >>Nice, but:
              > >>
              > >> > +The easiest and the fastest way to solve the nested subroutines
              > >> > +problem is to change C<my> to C<local> C<our> for all variables for
              > >> > +which you get the warning. The C<handler> subroutines are never
              > >>...
              > >>[...]
              > >> > + local our $counter = 0;
              > >>
              > >>local our? That should be either local or our, but not both.
              > > No.
              > >
              > >>Do I miss something?
              > > Yes. (I tried to explain this in Paris but I was in danger of
              > > causing
              > > you to miss lunch completely).
              > > local() and our() do two quite separate and complementary things.
              > > our() (in effect) declares a lexically scoped alias for a package
              > > variable.
              > > local() restores the old value of a package variable (usually undef)
              > > at the end of the current lexical scope.
              >
              > In effect you use local() to undef the variable, instead of explicitly
              > initializing it. Why not doing this explictly?

              Firstly it's conceptually neater to use local. I want to think of the
              variable as local rather than as a global variable that needs to be
              explicitly reset.

              Secongly it's a smaller change.

              Thirdly you can never be sure the undef would be reached. (I realise
              after reading the rest of your mail that that statement will not make
              any sense to you because you've misunderstood what local does and
              hense where the undef would need to go).

              > so instead of replacing:
              >
              > my $counter;
              >
              > with:
              >
              > local our $counter;
              >
              > it's probably better to say:
              >
              > our $counter = 0;

              Surely you meant:

              undef our $counter;

              Or

              our $counter = undef.

              In this case $counter is treated a a number so it's OK to use 0 but
              the aim of the game is to come up with a drop-in replacement for all
              lexically scoped variables that suffer "will not remain shared".

              Anyhow, local() does something quite different. It undefines it upon
              exit of the current scope. Obviously _most_ of the time it matters
              little if the variable is undef on exiting the scope or re-entering it
              next time. But why bother storing up troubles. Better to do the
              right thing from the outset.

              > or if you insist on using both:
              >
              > our $counter;
              > local $counter; # undef $counter

              Why split them? Doesn't aid readability. Is a pain if the original
              my() was inside an expression.

              The comment is confusing. It implies that local performs
              initialization. It doesn't. It performs finalization.

              The comment should read:

              local $counter; # Automatically undef $counter when script terminates

              > later on I show why this is better for user's understanding.

              Really?

              > > The two combined therefore give a package variable two of the most
              > > useful properties of a lexical one. Of course a real lexical variable
              > > doesn't really become undefined when it does out of scope - it really
              > > becomes anonymous, and iff there are no remaining (unweakened)
              > > references it then gets GCed. But for file-scoped lexicals in the
              > > main script file the difference is usually not that important. Both
              > > effectively get killed at the point where global destruction would
              > > have taken place.
              > >
              > >>The rest looks good, but that's not the simplest solution as you have
              > >>to modify the variables.
              > > Is there a simpler one? For a typical script with say half a dozen
              > > variables the "would not remain shared" the "local our" solution
              > > requires a dozen keystokes on each of half a dozen lines.
              >
              > Don't forget that our() is not available before perl 5.6. So we can't
              > quite eliminate the previous solution unless you suggest to go with a
              > back-compatible version:
              >
              > use vars qw($counter);
              > local $counter;

              I thought enough time has gone by that 5.6 can be considered the norm
              and the tiny fraction of people doing on-going work on legacy pre-5.6
              system should be expected to be familar with the work-rounds required.
              On that basis I concuded that the work-rounds needed to get arround
              the lack of our() in 5.5 are outside the scope of the the porting
              document and belonged in the perl_reference. In my (as yet
              incomplete) revision of the perl_reference document I include mention
              of 'use vars'. If you think this should be in porting I'm not going
              to argue.

              > and of course the proper solution is:
              >
              > use vars qw($counter);
              > $counter = 0; # or undef

              No, the proper solution is:

              local our $counter;

              IMNSHO "use vars" is not the proper solution, it is a backward
              compatability work-round for people still using old versions of Perl
              that prevent them using the proper solution.

              Initialization is not the proper solution. In some cases, like the
              case of the simple counter you can get away with using initialization.
              But the proper solution is finalization (using local). To see why
              consider a CGI script that contains, at file scope:

              open my $file, '>', $outfile or die "$outfile: $!";

              What happens if you change that to:

              use vars qw($file);
              $file = undef;
              open $file, '>', $outfile or die $!;

              Well firstly it looks way ugly :-) ! Much more importantly it doesn't
              close the file when the script terminates.

              open local our $file, '>', $outfile or die $!;

              This is a much smaller change to the original script. It looks much
              cleaner. And most importantly it actually works.

              > >>Granted, the original "simplest" solution has its troubles.
              > > The original "simplest" solution involved finding (and subsequently
              > > maintaining) a globally unique filename then splitting the program in
              > > to two parts. Thereafer you have to maintain two files even on CGI
              > > servers. I would contend that this "simple solution" is not simple.
              > > If you are going to all that troble you may as well to the extra
              > > 804.65m and produce a proper mod_perl handler and a small wrapper to
              > > make it work also in a CGI environment. Also, as of mod_perl2, the
              > > "simple solution" is not even, as it stands, a solution as it relied
              > > on the script being in the CWD.
              >
              > Remember, we are talking about mp1 guide patching. Not everything that
              > applies to mp1 applies to mp2.

              OK, please forget I ever mentioned mp2.

              > [...] I hope that the problem with CWD will be resolved [...]

              The problem with CWD is not that simple.

              The trouble with advising people to create Perl4-style library in the
              same diectory as the script is that it is not intuatively obvious that
              the leafname of that library needs to unique for each ported CGI
              script. That's not just unique within the directory. It's not even
              just unique accross the whole server. It needs to be unique across all
              servers on which the script may ever be installed!

              This namespace problem is not new to Perl programmers. It is, indeed,
              exactly the same problem as the naming of modules. So why not spend
              the extra minuite or so of effort to make a proper Perl5-style library
              (i.e. a module using Exporter) instead and reduce two problems to one.

              Furthermore consider an inexperienced Perl programmer who rips the
              guts out of a GCI script into a Perl4-style library. There's a strong
              chance that he'll then think "hey, I've got this library now, let's
              use it in another CGI script too". This, of course, will produce a
              script that works under CGI but fails sporadically under mod_perl.

              I'm not inventing these problems. I've dealt with the fallout from
              the current porting guide in comp.lang.perl.* a few times.

              Far better not to expose people to the Perl4-style library solution at
              all (except perhaps to warn them against it).

              In the post-patch version of 'porting' I give them a simple choice:

              First choice - move the guts of your CGI into modules. (This is in
              fact 95% of the way to porting your script to a native mod_perl
              hander).

              Second choice - leave the script 99.9% untouched but use localised
              package variables for any variables that are, in the design of the
              script, already global.

              > If you think that using globals + their initialization is a better
              > solution,

              No, initialization is not a good solution. Finalisation is what is
              wanted.

              The use of term "global" to refer to Perl's package variables is
              misleading.

              From the point of view of program design file-scoped lexicals are
              global variables. By suggesting the use of package variables I'm not
              suggesting that anyone start using the programming technique of global
              variables in place of something else. What we are dealing with here
              is the situation where one has a CGI script that already has a design
              that uses global variables. These global variables happen to be
              implemented as file-scoped lexicals.

              To port this script to run as a mod_perl registry script the
              _simplest_ change is just to choose to implement these variables as
              localised package variables instead.

              > [...] we can replace the lib.pl solution with it,

              Good.

              > but should add it to the perl reference section.

              I can't work out what "it" referrs to above. Both solutions should
              appear in the perl reference section. The lib.pl solution should not
              appear in porting, and even if it did then it defintely should not be
              described by saying: "This solution provides the easiest and the
              fastest way to solve the nested subroutines problem, since all you
              have to do is to move the code into a separate file,..." because
              that's simply untrue (on two counts).

              "Move the code into a separate file" is not "all you have to do".
              Before you can do that you have to choose a globally unique filename
              for your file. And remember I mean _globally_ unique - it must not
              clash with one used in any other registry script on any server where
              the script will ever be installed.

              Even if "move the code into a separate file" _was_ all you had to do
              that would still be a couple of orders of magnitude more effort than
              the "local our" solution thus it would still not be "the easiest and
              the fastest way".


              --
              Reporting bugs: http://perl.apache.org/bugs/
              Mail list info: http://perl.apache.org/maillist/modperl.html
            • Stas Bekman
              [...] ... local is perl4-ism, nowadays it s used only for localizing special perl variables, like $|. ... Agreed, but it s not the proper change, your change
              Message 6 of 20 , Sep 3 6:24 PM
              • 0 Attachment
                [...]
                >>In effect you use local() to undef the variable, instead of explicitly
                >>initializing it. Why not doing this explictly?
                >
                >
                > Firstly it's conceptually neater to use local. I want to think of the
                > variable as local rather than as a global variable that needs to be
                > explicitly reset.

                local is perl4-ism, nowadays it's used only for localizing special perl
                variables, like $|.

                > Secongly it's a smaller change.

                Agreed, but it's not the proper change, your change can break code. Assuming
                that we had:

                use warnings;
                my $counter = 0;
                print "hit $counter times";

                Your change:

                use warnings;
                local our $counter;
                print "hit $counter times";

                will generate a warning: Use of uninitialized value in concatenation (.) or
                string at ...

                We have to teach users to initialize globals, not localize them. See more below.

                > Thirdly you can never be sure the undef would be reached.

                And nobody wants it to be reached. The problem is at the beginning of the
                subsequent request, not at the end of the first request. See more below.

                >>so instead of replacing:
                >>
                >>my $counter;
                >>
                >>with:
                >>
                >>local our $counter;
                >>
                >>it's probably better to say:
                >>
                >>our $counter = 0;
                >
                >
                > Surely you meant:
                >
                > undef our $counter;
                >
                > Or
                >
                > our $counter = undef.

                No I meant = 0, because that's what the original example does. We try to solve
                the problem with:

                my $counter = 0;

                therefore:

                our $counter = 0;

                does the trick. if you replace

                my $counter = 0;

                with

                local our $counter;

                you lose the initialization. This won't work under 'use warnings', which is
                not clear from the example, but perhaps it should be fixed to do that.

                > In this case $counter is treated a a number so it's OK to use 0 but
                > the aim of the game is to come up with a drop-in replacement for all
                > lexically scoped variables that suffer "will not remain shared".
                >
                > Anyhow, local() does something quite different. It undefines it upon
                > exit of the current scope. Obviously _most_ of the time it matters
                > little if the variable is undef on exiting the scope or re-entering it
                > next time. But why bother storing up troubles. Better to do the
                > right thing from the outset.

                I beg your pardon, how did you come up to this conclusion. Point me to the
                documentation or the source code where this is done. On the exit of the scope
                local() restores the previous value if any, and if none was assigned in first
                place (which implies undef) it's reset to undef. I don't think it has anything
                to do with finalization, it just looks like it does.

                Your code:

                local our $counter;

                is essentially:

                our $counter; # undef
                { local $counter; # new undef unrelated to the previous one
                $counter = 0; # you missed this, but it's unrelated
                }
                # $counter == the very first undef here, because it was undef before local was
                called.

                And just to prove you that you aren't so correct with this finalization idea,
                run the following code:

                perl-5.8.1 -lwe 'our $x = 5; { local $x = 6 } print $x'

                it prints '5', not undef. so it's *restored* to its previous value not reset
                to undef. now this:

                perl-5.8.1 -lwe 'our $x; { local $x = 6 } print $x'

                will indeed restore $x to undef, because that's how it was before local...

                However I'm not against your 'local our' solution, I'm just saying that it's
                less obvious than an explicit initialization, even though it requires more
                modification. Not-very advanced users will just get confused by this solution.
                Normally variables need to be initialized before they are used, so they will
                have to init them in any case and undef is not what they want.

                For example we can provide an explicit initialization example and after that
                suggest that you can say 'local our $foo' to globalize and localize it at the
                same time if you prefer to init those to undef via local(). Sounds like a good
                compromise to me.

                > I thought enough time has gone by that 5.6 can be considered the norm
                > and the tiny fraction of people doing on-going work on legacy pre-5.6
                > system should be expected to be familar with the work-rounds required.
                > On that basis I concuded that the work-rounds needed to get arround
                > the lack of our() in 5.5 are outside the scope of the the porting
                > document and belonged in the perl_reference. In my (as yet
                > incomplete) revision of the perl_reference document I include mention
                > of 'use vars'. If you think this should be in porting I'm not going
                > to argue.

                That's what I suggested, just wasn't clear about it. It should be moved out of
                porting.pod into perl_reference.pod.

                > IMNSHO "use vars" is not the proper solution, it is a backward
                > compatability work-round for people still using old versions of Perl
                > that prevent them using the proper solution.

                Well, what users that do happen to use perl < 5.6 should do? The guide is
                written to reduce the number of questions, not raise their number. Solution:
                mention both (our and use vars)

                > Initialization is not the proper solution. In some cases, like the
                > case of the simple counter you can get away with using initialization.
                > But the proper solution is finalization (using local). To see why
                > consider a CGI script that contains, at file scope:
                >
                > open my $file, '>', $outfile or die "$outfile: $!";
                >
                > What happens if you change that to:
                >
                > use vars qw($file);
                > $file = undef;
                > open $file, '>', $outfile or die $!;
                >
                > Well firstly it looks way ugly :-) !

                Secondly, it doesn't work under perl < 5.6, so the point is moot if it's made
                clear ;)

                > Much more importantly it doesn't
                > close the file when the script terminates.

                I didn't suggest that particular use, however the suggestion in the guide is
                global and implies that it should work. All I can say here is that closing the
                file explicitly is a good practice, but otherwise you are right.

                > open local our $file, '>', $outfile or die $!;
                >
                > This is a much smaller change to the original script. It looks much
                > cleaner. And most importantly it actually works.

                so does:

                open our $file, '>', $outfile or die $!;

                no? and it works because you don't need to initialize $file

                > The problem with CWD is not that simple.
                >
                > The trouble with advising people to create Perl4-style library in the

                [...]

                But I have already agreed that perl4-style libs solution should be moved to
                the perl_reference.pod doc... I agree with your arguments.

                To summarize:

                - move the perl4 lib solution to the perl_reference.pod
                - suggest replacing my() with our() to avoid the closure, however this change
                requires that the variables will be initialized before used in most cases
                (example of 'open our $foo' which doesn't need to be initialized). you can
                initialize variables by an explicit assignment of the value, or using the
                'local our' trick, which will initialize the variable to under, which is
                probably not what you want.
                - for users of perl < 5.6 suggest to use 'use vars' instead of 'our'.
                - point to perl_reference.pod for other workarounds/solutions.

                Does it sound good?

                __________________________________________________________________
                Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
                http://stason.org/ mod_perl Guide ---> http://perl.apache.org
                mailto:stas@... http://use.perl.org http://apacheweek.com
                http://modperlbook.org http://apache.org http://ticketmaster.com



                --
                Reporting bugs: http://perl.apache.org/bugs/
                Mail list info: http://perl.apache.org/maillist/modperl.html
              • Perrin Harkins
                ... I agree, using local, and especially local our is pretty strange. It may work, but I wouldn t want to encourage people to do that in their code. ... May
                Message 7 of 20 , Sep 3 7:09 PM
                • 0 Attachment
                  On Wed, 2003-09-03 at 21:24, Stas Bekman wrote:
                  > [...]
                  > >>In effect you use local() to undef the variable, instead of explicitly
                  > >>initializing it. Why not doing this explictly?
                  > >
                  > >
                  > > Firstly it's conceptually neater to use local. I want to think of the
                  > > variable as local rather than as a global variable that needs to be
                  > > explicitly reset.
                  >
                  > local is perl4-ism, nowadays it's used only for localizing special perl
                  > variables, like $|.

                  I agree, using local, and especially "local our" is pretty strange. It
                  may work, but I wouldn't want to encourage people to do that in their
                  code.

                  > To summarize:
                  >
                  > - move the perl4 lib solution to the perl_reference.pod
                  > - suggest replacing my() with our() to avoid the closure, however this change
                  > requires that the variables will be initialized before used in most cases
                  > (example of 'open our $foo' which doesn't need to be initialized). you can
                  > initialize variables by an explicit assignment of the value, or using the
                  > 'local our' trick, which will initialize the variable to under, which is
                  > probably not what you want.
                  > - for users of perl < 5.6 suggest to use 'use vars' instead of 'our'.
                  > - point to perl_reference.pod for other workarounds/solutions.

                  May I also suggest telling users to pass arguments explicitly to subs,
                  instead of doing it implicitly? Nearly all of the Registry-related bugs
                  I see stem from people doing this:

                  my $cgi = CGI->new();

                  foo()

                  sub foo {
                  $cgi->param(whatever)...
                  }

                  They accidentally create a closure this way and then wonder why their
                  form values never change. Passing $cgi to foo() fixes the problem.

                  - Perrin



                  --
                  Reporting bugs: http://perl.apache.org/bugs/
                  Mail list info: http://perl.apache.org/maillist/modperl.html
                • Stas Bekman
                  ... We have that already covered in perl_reference.pod, example multirun3.pl. Originally all the workarounds were in the porting.pod but then there were too
                  Message 8 of 20 , Sep 3 8:15 PM
                  • 0 Attachment
                    Perrin Harkins wrote:

                    >>To summarize:
                    >>
                    >>- move the perl4 lib solution to the perl_reference.pod
                    >>- suggest replacing my() with our() to avoid the closure, however this change
                    >>requires that the variables will be initialized before used in most cases
                    >>(example of 'open our $foo' which doesn't need to be initialized). you can
                    >>initialize variables by an explicit assignment of the value, or using the
                    >>'local our' trick, which will initialize the variable to under, which is
                    >>probably not what you want.
                    >>- for users of perl < 5.6 suggest to use 'use vars' instead of 'our'.
                    >>- point to perl_reference.pod for other workarounds/solutions.
                    >
                    >
                    > May I also suggest telling users to pass arguments explicitly to subs,
                    > instead of doing it implicitly? Nearly all of the Registry-related bugs
                    > I see stem from people doing this:
                    >
                    > my $cgi = CGI->new();
                    >
                    > foo()
                    >
                    > sub foo {
                    > $cgi->param(whatever)...
                    > }
                    >
                    > They accidentally create a closure this way and then wonder why their
                    > form values never change. Passing $cgi to foo() fixes the problem.

                    We have that already covered in perl_reference.pod, example multirun3.pl.
                    Originally all the workarounds were in the porting.pod but then there were too
                    many of them. so I thought to give just one solution and a pointer to a
                    document/section with the rest of the solutions. If you think it's worth
                    mentioning it in porting.pod in addition to the current place, feel free to
                    adjust it. Your above example prabably more familiar to cgi script writers,
                    than an abstract $counter exapmle.

                    Thanks!

                    __________________________________________________________________
                    Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
                    http://stason.org/ mod_perl Guide ---> http://perl.apache.org
                    mailto:stas@... http://use.perl.org http://apacheweek.com
                    http://modperlbook.org http://apache.org http://ticketmaster.com



                    --
                    Reporting bugs: http://perl.apache.org/bugs/
                    Mail list info: http://perl.apache.org/maillist/modperl.html
                  • Brian McCauley
                    ... Using package variables and local() in to do the job of block-scoped lexicals is a Perl4-ism. On the other hand, when using global variables (in which I
                    Message 9 of 20 , Sep 5 4:58 AM
                    • 0 Attachment
                      Stas Bekman <stas@...> writes:

                      > local is perl4-ism, nowadays it's used only for localizing special
                      > perl variables, like $|.

                      Using package variables and local() in to do the job of block-scoped
                      lexicals is a Perl4-ism.

                      On the other hand, when using global variables (in which I include
                      Perl's package variables and Perl's file-scoped lexicals) something
                      with the semantics of local() is useful. It is, therefore, annoying
                      that local cannot be used on lexical variables and even LW has said
                      that this restriction is artifical and wrong.

                      I agree that as a programming technique global variables are vulgar.
                      However the "First Mystery" is all about porting CGI scripts that are
                      already using global variables (implemented using file-scoped
                      lexicals). It is the use of global variables in the first place that
                      is vulgar, using local() does not make the code any more vulgar.

                      > > Secongly it's a smaller change.
                      >
                      > Agreed, but it's not the proper change, your change can break
                      > code.

                      Only in really obscure circumstances. Of course, if at the same time,
                      you make an unrelated change that breaks the code I can see how you'd
                      be tempted to blame me. :-)

                      > Assuming that we had:
                      >
                      > use warnings;
                      > my $counter = 0;
                      > print "hit $counter times";
                      >
                      > Your change:
                      >
                      > use warnings;
                      > local our $counter;
                      > print "hit $counter times";

                      No, that's not my change, I said to change "my" to "local our". I
                      didn't say to remove initialization.

                      > > Anyhow, local() does something quite different. It undefines it upon
                      > > exit of the current scope.
                      >
                      > On the exit of the scope local() restores the previous value if any,
                      > and if none was assigned in first place (which implies undef) it's
                      > reset to undef.

                      Yes, I know that.

                      > I don't think it has anything to do with finalization, it just looks
                      > like it does.

                      "Bluebells are not blue, they are actually pink and just look like
                      they are blue" :-)

                      I use the term 'finalization' to (amongst other things) refer to
                      declaring an action that is to take place when a given scope is
                      removed from the execution stack. This is what 'local' does.
                      The word, however, is not important as I don't propose to use it in
                      the guide.

                      > However I'm not against your 'local our' solution, I'm just saying
                      > that it's less obvious than an explicit initialization, even though it
                      > requires more modification. Not-very advanced users will just get
                      > confused by this solution. Normally variables need to be initialized
                      > before they are used, so they will have to init them in any case and
                      > undef is not what they want.

                      The porting guide assumes we start with a working CGI script. If a
                      variable needs to be initialized to a value other than undef then a
                      working script must already do so.

                      > For example we can provide an explicit initialization example

                      The example in my modified porting.pod already shows explicit
                      initialization:

                      local our $counter = 0;

                      > after that suggest that you can say 'local our $foo' to globalize and
                      > localize it at the same time if you prefer to init those to undef via
                      > local(). Sounds like a good compromise to me.

                      That fails to mention the real reason for using local.

                      > > [ about use vars ]
                      > The guide is written to reduce the number of questions, not raise
                      > their number. Solution: mention both (our and use vars)

                      How about we leave the example as I have it now and say:

                      In this simple example, 'local' is redundant because $counter is
                      explicitly initialized and never holds a reference. For variables
                      that hold references (especially to objects interfacing to entities
                      outside Perl) 'local' ensures timely destruction. For variables
                      lacking explicit initialization 'local' also initializes them to
                      undefined.

                      The 'our' function appeared in 5.6, for backward compatability:

                      use vars qw( $counter );
                      $counter = 0;

                      We could also go on to talk about the option of explicitly
                      initializing variables with undef() to save the minute overhead of
                      using local() but I think that's unwarranted in porting.pod. Perhaps
                      it should be covered in perl_reference.pod.

                      > > [ file handle example ]
                      >
                      > I didn't suggest that particular use

                      I realise that the simple file handle example was a poor choice to
                      illustrate my point. Here's a better example that could form the
                      basis of a more verbose explation in perl_reference.pod.

                      Suppose you have:

                      my $thing = Thing->new;

                      Now suppose that Thing objects involve lots of resources (shared
                      memory segments, temporary files, large Perl data structures,
                      network connections various database/NNTP/SNPP/whatever servers
                      and so on) and/or suppose that Thing objects perform some sort of
                      output buffering and then flush it in Thing::DESTROY.

                      If I change that to:

                      our $thing = Thing->new;

                      Then all of these resources are held until the script is next run
                      or until the interpreter thread is killed.

                      If I change it to:

                      local our $thing = Thing->new;

                      It does the right thing.

                      You might think you could simply undef($thing) at the end of the
                      script but you'd have to ensure all exection paths, including
                      abnormal termination, pass through the undef statement.

                      > But I have already agreed that perl4-style libs solution should be
                      > moved to the perl_reference.pod doc...

                      I'm glad we agree on something :-)

                      > To summarize:
                      >
                      > - move the perl4 lib solution to the perl_reference.pod
                      > - suggest replacing my() with our() to avoid the closure, however this
                      > change requires that the variables will be initialized before used in
                      > most cases (example of 'open our $foo' which doesn't need to be
                      > initialized). you can initialize variables by an explicit assignment
                      > of the value, or using the 'local our' trick, which will initialize
                      > the variable to under, which is probably not what you want.

                      Since the 'my' that is being replaced by 'local our' also initializes
                      variables to undef I don't think we need to labour the point. As I
                      said above, we should assume a working CGI script as the starting
                      point.

                      > - for users of perl < 5.6 suggest to use 'use vars' instead of 'our'.
                      > - point to perl_reference.pod for other workarounds/solutions.
                      >
                      > Does it sound good?

                      Yes, basically.

                      Revised patch to follow at some point this weekend.


                      --
                      Reporting bugs: http://perl.apache.org/bugs/
                      Mail list info: http://perl.apache.org/maillist/modperl.html
                    • Stas Bekman
                      Brian McCauley wrote: [...] OK, your last post s examples were more to the point of wanting to destroy objects at the end of the request, and hence here is a
                      Message 10 of 20 , Sep 5 10:29 AM
                      • 0 Attachment
                        Brian McCauley wrote:
                        [...]
                        OK, your last post's examples were more to the point of wanting to destroy
                        objects at the end of the request, and hence here is a new summary:

                        - move the perl4 lib solution to the perl_reference.pod
                        - suggest turning a lexical variable declared with my() into a global variable
                        declared with our() to avoid the closure, with the following "but"s:

                        o if with my() it wasn't crucial to initialize the variables
                        (since my() initialized them to 'undef'), now all variables declared with
                        our() must be explicitly initialized.

                        s/my $counter = 0/our $counter = 0/;

                        [Brian: notice that I prefer *not* to suggest using local() to init vars, and
                        rather have users do that explicitly, which is a good practice]

                        o since the initialization of global variables happens at the beginning of
                        the request, if a variable which contains an object:

                        my $query = CGI->new;

                        is made global:

                        our $query = CGI->new;

                        it won't be destroyed untill the next request. If you wish to make sure
                        that it's destroyed at the end of the request, you must local()'ize the
                        variable:

                        local our $query = CGI->new;

                        - users of perl < 5.6 have to use 'use vars' instead of 'our'. So the above
                        examples become:

                        use vars qw($counter);
                        $counter = 0;

                        and:

                        use vars qw($query);
                        local $query = CGI->new;

                        - point to perl_reference.pod for other workarounds/solutions.

                        Please let me know if I have missed something from your last posts suggestions.

                        __________________________________________________________________
                        Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
                        http://stason.org/ mod_perl Guide ---> http://perl.apache.org
                        mailto:stas@... http://use.perl.org http://apacheweek.com
                        http://modperlbook.org http://apache.org http://ticketmaster.com



                        --
                        Reporting bugs: http://perl.apache.org/bugs/
                        Mail list info: http://perl.apache.org/maillist/modperl.html
                      • Brian McCauley
                        ... Will do when I get round to that bit. I still think a mention of it is needed in porting.pod to warn people away from it. If you disagree simply delete
                        Message 11 of 20 , Oct 10, 2003
                        • 0 Attachment
                          Stas Bekman <stas@...> writes:

                          > - move the perl4 lib solution to the perl_reference.pod

                          Will do when I get round to that bit. I still think a mention of it
                          is needed in porting.pod to warn people away from it. If you disagree
                          simply delete the offending paragraph.

                          > - suggest turning a lexical variable declared with my() into a global
                          > variable declared with our() to avoid the closure, with the following
                          > "but"s:
                          >
                          > o if with my() it wasn't crucial to initialize the variables
                          > (since my() initialized them to 'undef'), now all variables declared with
                          > our() must be explicitly initialized.

                          > [Brian: notice that I prefer *not* to suggest using local() to init
                          > vars, and rather have users do that explicitly, which is a good
                          > practice]

                          Well I disagree with you about it being good a practice. I personally
                          consider it good practice to work in a way that minimises the number
                          of things you have to do explicitly (with the exception of
                          declarations). I can't see why you think relying on the fact that
                          local() will initialize variables to undef is any worse than relying
                          on the fact that my() will.

                          But this is your document so I shall go along with your preferences.

                          I've tried to keep it brief by moving some of the points (in
                          particular 'use vars') into comments inside the code examples where
                          they can be expressed more concisely.

                          --- porting.pod.orig Fri Oct 10 18:58:48 2003
                          +++ porting.pod Fri Oct 10 18:42:27 2003
                          @@ -88,7 +88,7 @@

                          print "Content-type: text/plain\r\n\r\n";

                          - my $counter = 0;
                          + my $counter = 0; # Explicit initialization technically redundant

                          for (1..5) {
                          increment_counter();
                          @@ -195,8 +195,8 @@

                          print "Content-type: text/plain\r\n\r\n";

                          - my $counter = 0;
                          -
                          + my $counter = 0; # Explicit initialization technically redundant
                          +
                          for (1..5) {
                          increment_counter();
                          }
                          @@ -228,51 +228,66 @@

                          It's important to understand that the I<inner subroutine> effect
                          happens only with code that C<Apache::Registry> wraps with a
                          -declaration of the C<handler> subroutine. If you put your code into a
                          -library or module, which the main script require()'s or use()'s, this
                          -effect doesn't occur.
                          -
                          -For example if we move the code from the script into the subroutine
                          -I<run>, place the subroutines into the I<mylib.pl> file, save it in
                          -the same directory as the script itself and require() it, there will
                          -be no problem at all. (Don't forget the C<1;> at the end of the
                          -library or the require() might fail.)
                          -
                          - mylib.pl:
                          - ---------
                          - my $counter;
                          - sub run{
                          - print "Content-type: text/plain\r\n\r\n";
                          - $counter = 0;
                          - for (1..5) {
                          - increment_counter();
                          - }
                          +declaration of the C<handler> subroutine. If you put all your code
                          +into modules, which the main script C<use()>s, this effect doesn't
                          +occur.
                          +
                          +Do not use Perl4-style libraries. Subroutines in such libraries will
                          +only be available to the first script in any given interpreter thread
                          +to C<require()> a library of any given name. This can lead to
                          +confusing sporadic failures.
                          +
                          +The easiest and the fastest way to solve the nested subroutines
                          +problem is to switch from lexical scope to package scope for all
                          +variables for which you get the warning. The C<handler> subroutines
                          +are never called re-entrantly and each resides in a package to itself.
                          +Most of the usual disadvantates of package scoped variables are,
                          +therefore, not a concern. Note, however, that whereas explicit
                          +initialization is often redundant for lexical variables it is usually
                          +not redundant for these package variables as they are reused in
                          +subsequent executions of the handler.
                          +
                          + counter.pl:
                          + ----------
                          + #!/usr/bin/perl -w
                          + use strict;
                          +
                          + print "Content-type: text/plain\r\n\r\n";
                          +
                          + # In Perl <5.6 our() did not exist, so:
                          + # use vars qw($counter);
                          + our $counter = 0; # Explicit initialization now necessary
                          +
                          + for (1..5) {
                          + increment_counter();
                          }
                          +
                          sub increment_counter{
                          $counter++;
                          print "Counter is equal to $counter !\r\n";
                          }
                          - 1;
                          -
                          - counter.pl:
                          - ----------
                          - use strict;
                          - require "./mylib.pl";
                          - run();

                          -This solution provides the easiest and the fastest way to solve the
                          -nested subroutines problem, since all you have to do is to move the
                          -code into a separate file, by first wrapping the initial code into
                          -some function that you later will call from the script and keeping the
                          -lexically scoped variables that could cause the problem out of this
                          -function.
                          -
                          -But as a general rule of thumb, unless the script is very short, I
                          -tend to write all the code in external libraries, and to have only a
                          -few lines in the main script. Generally the main script simply calls
                          -the main function of my library. Usually I call it C<init()> or
                          -C<run()>. I don't worry about nested subroutine effects anymore
                          -(unless I create them myself :).
                          +If the shared variable contains a reference it my hold onto lots of
                          +unecessary memory (or worse) if the reference is left to hang about
                          +until the next call to the same handler. For such variables you
                          +should use C<local> so that the value is removed when the C<handler>
                          +subroutine exits.
                          +
                          + my $query = CGI->new;
                          +
                          +becomes:
                          +
                          + local our $query = CGI->new;
                          +
                          +As side effect, if you use C<local> you no longer need to add explicit
                          +initialization of variables to undef.
                          +
                          +All this is very interesting but as a general rule of thumb, unless
                          +the script is very short, I tend to write all the code in external
                          +libraries, and to have only a few lines in the main script. Generally
                          +the main script simply calls the main function of my library. Usually
                          +I call it C<init()> or C<run()>. I don't worry about nested
                          +subroutine effects anymore (unless I create them myself :).

                          The section 'L<Remedies for Inner
                          Subroutines|general::perl_reference::perl_reference/Remedies_for_Inner_Subroutines>' discusses

                          --
                          \\ ( )
                          . _\\__[oo
                          .__/ \\ /\@
                          . l___\\
                          # ll l\\
                          ###LL LL\\
                        • Stas Bekman
                          ... I m not disagreeing with you on this. But I will wait for your second patch and commit both at once otherwise one of the solutions gets temporary lost...
                          Message 12 of 20 , Oct 14, 2003
                          • 0 Attachment
                            Brian McCauley wrote:
                            > Stas Bekman <stas@...> writes:
                            >
                            >
                            >>- move the perl4 lib solution to the perl_reference.pod
                            >
                            >
                            > Will do when I get round to that bit. I still think a mention of it
                            > is needed in porting.pod to warn people away from it. If you disagree
                            > simply delete the offending paragraph.

                            I'm not disagreeing with you on this. But I will wait for your second patch
                            and commit both at once otherwise one of the solutions gets temporary lost...

                            >>- suggest turning a lexical variable declared with my() into a global
                            >>variable declared with our() to avoid the closure, with the following
                            >>"but"s:
                            >>
                            >> o if with my() it wasn't crucial to initialize the variables
                            >> (since my() initialized them to 'undef'), now all variables declared with
                            >> our() must be explicitly initialized.
                            >
                            >
                            >>[Brian: notice that I prefer *not* to suggest using local() to init
                            >>vars, and rather have users do that explicitly, which is a good
                            >>practice]
                            >
                            >
                            > Well I disagree with you about it being good a practice. I personally
                            > consider it good practice to work in a way that minimises the number
                            > of things you have to do explicitly (with the exception of
                            > declarations). I can't see why you think relying on the fact that
                            > local() will initialize variables to undef is any worse than relying
                            > on the fact that my() will.
                            >
                            > But this is your document so I shall go along with your preferences.

                            It's not really mine, I just happen to maintain it. From the previous
                            discussion it seems that those who cared agreed that it's better to explicitly
                            declare vars. Granted 'local our' works, but for (most?) users this point will
                            be lost, as they will just copy-n-paste examples without understanding why is
                            it so. Power users can figure it out on their own, and I wasn't against
                            mentioning it at the end after explaining the longer (more explicit?)
                            solution. I think that makes it a happy compromise, no?

                            > I've tried to keep it brief by moving some of the points (in
                            > particular 'use vars') into comments inside the code examples where
                            > they can be expressed more concisely.

                            Frankly, I can't understand why do you try to undermine the importance of
                            always initializing variables. Please remember that this docs is used as a
                            reference by users of varying expertise in Perl. Unless you are an advanced
                            user and know what you are doing, it's a goodness to always initialize
                            variables before you use them.

                            > +The easiest and the fastest way to solve the nested subroutines
                            > +problem is to switch from lexical scope to package scope for all
                            > +variables for which you get the warning. The C<handler> subroutines

                            Would it be better to say:

                            The easiest and the fastest way to solve the nested subroutines
                            problem is to switch every lexically scoped variable you get the warning for
                            to a global package variable.

                            or something like that? package scope is lexical scope too.

                            > +are never called re-entrantly and each resides in a package to itself.
                            > +Most of the usual disadvantates of package scoped variables are,
                            > +therefore, not a concern. Note, however, that whereas explicit
                            > +initialization is often redundant for lexical variables it is usually
                            > +not redundant for these package variables as they are reused in
                            > +subsequent executions of the handler.

                            may I suggest the following wording:

                            Note, however, that whereas explicit
                            initialization is not always necessary for lexical variables it is usually
                            not redundant for these global package variables as they persist in
                            subsequent executions of the handler and unlike lexical variables, don't get
                            automatically destroyed at the end of each handler.

                            > +If the shared variable contains a reference it my hold onto lots of

                            shared variable? Can we stick to lexical vs. global, and not confuse user even
                            further? shared variables are special with ithreads and allow sharing data
                            across threads.

                            also s/my/may/

                            The rest looks good. Thanks Brian.

                            __________________________________________________________________
                            Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
                            http://stason.org/ mod_perl Guide ---> http://perl.apache.org
                            mailto:stas@... http://use.perl.org http://apacheweek.com
                            http://modperlbook.org http://apache.org http://ticketmaster.com
                          • Brian McCauley
                            ... Yep, OK. ... I assume that was a typo :-) s/declare/initialize/. ... Hey, I ve conceded. You can stop trying to beat me into submission now. ... I
                            Message 13 of 20 , Oct 15, 2003
                            • 0 Attachment
                              Stas Bekman <stas@...> writes:

                              > Brian McCauley wrote:
                              > > Stas Bekman <stas@...> writes:
                              > >
                              > >>- move the perl4 lib solution to the perl_reference.pod
                              > > Will do when I get round to that bit. I still think a mention of it
                              > > is needed in porting.pod to warn people away from it. If you disagree
                              > > simply delete the offending paragraph.
                              >
                              > I'm not disagreeing with you on this. But I will wait for your second
                              > patch and commit both at once otherwise one of the solutions gets
                              > temporary lost...

                              Yep, OK.

                              > > [...] this is your document so I shall go along with your preferences.
                              >
                              > It's not really mine, I just happen to maintain it. From the previous
                              > discussion it seems that those who cared agreed that it's better to
                              > explicitly declare vars.

                              I assume that was a typo :-) s/declare/initialize/.

                              > Granted 'local our' works, but for (most?) users this point will be
                              > lost, as they will just copy-n-paste examples without understanding
                              > why is it so.

                              Hey, I've conceded. You can stop trying to beat me into submission now.

                              > Power users can figure it out on their own, and I wasn't against
                              > mentioning it at the end after explaining the longer (more
                              > explicit?) solution. I think that makes it a happy compromise, no?

                              I believe that is the compromise embodied in my previous attempt.

                              > > I've tried to keep it brief by moving some of the points (in
                              > > particular 'use vars') into comments inside the code examples where
                              > > they can be expressed more concisely.
                              >
                              > Frankly, I can't understand why do you try to undermine the importance
                              > of always initializing variables.

                              I don't. On the contrary I explain the importance in the narrative
                              and also re-enforce the importance in comments in the example code. I
                              have, at your suggestion, pushed into an afterthought any mention of
                              the fact that if you need to use local() anyhow you can get away
                              without explicit initialization of package variables.

                              Since it appears you _are_ against mentioning it even at the end I'll
                              remove it completely from porting.pod. I don't care, I'm not on a
                              crusade here.

                              > Unless you are an advanced user and know what you are doing, it's a
                              > goodness to always initialize variables before you use them.

                              Of course I agree that initializing variables before you use them is
                              good. It's just that I think that implicit initialization using my()
                              or (if you can't use my(), local()) is better than explicit
                              initialization using undef(). IMNSHO, whenever one sees an explicit
                              ``$var = undef'' or ``undef($var)'' an alarm bell should ring and ones
                              first thought should be "is there a missing/misplaced my()/local()?".

                              BUT....

                              I can't see why we are still arguing about this. I've worded the
                              document _as_if_ I agreed with you that explicit initialization was a
                              "good thing" per se. The fact that we disagree is, therefore, surely,
                              irrelevant.

                              > > +The easiest and the fastest way to solve the nested subroutines
                              > > +problem is to switch from lexical scope to package scope for all
                              > > +variables for which you get the warning. The C<handler> subroutines
                              >
                              > Would it be better to say:
                              >
                              > The easiest and the fastest way to solve the nested subroutines
                              > problem is to switch every lexically scoped variable you get the
                              > warning for to a global package variable.

                              Yes, that does read more easily. But the dangling "for" now grates.
                              Particularly the juxtaposition "for to". So I'd keep the "for which"
                              even if some people consider such strict English grammar to be
                              affected.

                              I would drop the word "global" since global has many different
                              meanings. By one definition of "global", the orginal file-scoped
                              lexical variable was global. By another definition of "global",
                              package variables (other than ones like %INC) are not global.

                              The use of the phrase "global variable" in Perl documentation as a
                              synonym for "package variable" is AFAIK deprocated.

                              Some people use the phase "global package variable" (or "global global
                              variable" (sic)) to refer to a variable like %INC.

                              I've even seen examples where people use the phrase "global variable"
                              to mean "package variable in package main".

                              > or something like that?

                              OK:

                              The easiest and the fastest way to solve the nested subroutines
                              problem is to switch every lexically scoped variable for which you
                              get the warning to a package variable.

                              > package scope is lexical scope too.

                              Er, now I'm really confused. The our() function declares a lexically
                              scoped alias for a package variable - but this is getting far too subtle.

                              > > +are never called re-entrantly and each resides in a package to itself.
                              > > +Most of the usual disadvantates of package scoped variables are,
                              > > +therefore, not a concern. Note, however, that whereas explicit
                              > > +initialization is often redundant for lexical variables it is usually
                              > > +not redundant for these package variables as they are reused in
                              > > +su bsequent executions of the handler.
                              >
                              > may I suggest the following wording:
                              >
                              > Note, however, that whereas explicit
                              > initialization is not always necessary for lexical variables it is usually
                              > not redundant for these global package variables as they persist in
                              > subsequent executions of the handler and unlike lexical variables,
                              > don't get automatically destroyed at the end of each handler.

                              Again I dislike the word "global" for reasons already stated.

                              I think it would read better if we use consistant terminology. EITHER
                              "not necessary" v "necessary" OR "redundant" v "not redundant" but NOT
                              "not necessary" v "not redundant".

                              I agree that your wording from "as they persist..." is clearer.

                              > > +If the shared variable contains a reference it my hold onto lots of
                              >
                              > shared variable? Can we stick to lexical vs. global, and not confuse
                              > user even further?

                              Er, lexical v _package_

                              > shared variables are special with ithreads and allow sharing data
                              > across threads.

                              Yes we should loose the word "shared". I had overlooked its special
                              meaning. No need for any adjective here, "the variable" will do just
                              fine.

                              > also s/my/may/

                              Oops :-)

                              --- porting.pod.orig Fri Oct 10 18:58:48 2003
                              +++ porting.pod Wed Oct 15 18:50:23 2003
                              @@ -88,7 +88,7 @@

                              print "Content-type: text/plain\r\n\r\n";

                              - my $counter = 0;
                              + my $counter = 0; # Explicit initialization technically redundant

                              for (1..5) {
                              increment_counter();
                              @@ -195,8 +195,8 @@

                              print "Content-type: text/plain\r\n\r\n";

                              - my $counter = 0;
                              -
                              + my $counter = 0; # Explicit initialization technically redundant
                              +
                              for (1..5) {
                              increment_counter();
                              }
                              @@ -228,51 +228,65 @@

                              It's important to understand that the I<inner subroutine> effect
                              happens only with code that C<Apache::Registry> wraps with a
                              -declaration of the C<handler> subroutine. If you put your code into a
                              -library or module, which the main script require()'s or use()'s, this
                              -effect doesn't occur.
                              -
                              -For example if we move the code from the script into the subroutine
                              -I<run>, place the subroutines into the I<mylib.pl> file, save it in
                              -the same directory as the script itself and require() it, there will
                              -be no problem at all. (Don't forget the C<1;> at the end of the
                              -library or the require() might fail.)
                              -
                              - mylib.pl:
                              - ---------
                              - my $counter;
                              - sub run{
                              - print "Content-type: text/plain\r\n\r\n";
                              - $counter = 0;
                              - for (1..5) {
                              - increment_counter();
                              - }
                              +declaration of the C<handler> subroutine. If you put all your code
                              +into modules, which the main script C<use()>s, this effect doesn't
                              +occur.
                              +
                              +Do not use Perl4-style libraries. Subroutines in such libraries will
                              +only be available to the first script in any given interpreter thread
                              +to C<require()> a library of any given name. This can lead to
                              +confusing sporadic failures.
                              +
                              +The easiest and the fastest way to solve the nested subroutines
                              +problem is to switch every lexically scoped variable for which you get
                              +the warning to a package variable. The C<handler> subroutines are
                              +never called re-entrantly and each resides in a package to itself.
                              +Most of the usual disadvantates of package scoped variables are,
                              +therefore, not a concern. Note, however, that whereas explicit
                              +initialization is not always necessary for lexical variables it is
                              +usually necessary for these package variables as they persist in
                              +subsequent executions of the handler and unlike lexical variables,
                              +don't get automatically destroyed at the end of each handler.
                              +
                              +
                              + counter.pl:
                              + ----------
                              + #!/usr/bin/perl -w
                              + use strict;
                              +
                              + print "Content-type: text/plain\r\n\r\n";
                              +
                              + # In Perl <5.6 our() did not exist, so:
                              + # use vars qw($counter);
                              + our $counter = 0; # Explicit initialization now necessary
                              +
                              + for (1..5) {
                              + increment_counter();
                              }
                              +
                              sub increment_counter{
                              $counter++;
                              print "Counter is equal to $counter !\r\n";
                              }
                              - 1;
                              -
                              - counter.pl:
                              - ----------
                              - use strict;
                              - require "./mylib.pl";
                              - run();

                              -This solution provides the easiest and the fastest way to solve the
                              -nested subroutines problem, since all you have to do is to move the
                              -code into a separate file, by first wrapping the initial code into
                              -some function that you later will call from the script and keeping the
                              -lexically scoped variables that could cause the problem out of this
                              -function.
                              -
                              -But as a general rule of thumb, unless the script is very short, I
                              -tend to write all the code in external libraries, and to have only a
                              -few lines in the main script. Generally the main script simply calls
                              -the main function of my library. Usually I call it C<init()> or
                              -C<run()>. I don't worry about nested subroutine effects anymore
                              -(unless I create them myself :).
                              +If the variable contains a reference it may hold onto lots of
                              +unecessary memory (or worse) if the reference is left to hang about
                              +until the next call to the same handler. For such variables you
                              +should use C<local> so that the value is removed when the C<handler>
                              +subroutine exits.
                              +
                              + my $query = CGI->new;
                              +
                              +becomes:
                              +
                              + local our $query = CGI->new;
                              +
                              +All this is very interesting but as a general rule of thumb, unless
                              +the script is very short, I tend to write all the code in external
                              +libraries, and to have only a few lines in the main script. Generally
                              +the main script simply calls the main function of my library. Usually
                              +I call it C<init()> or C<run()>. I don't worry about nested
                              +subroutine effects anymore (unless I create them myself :).

                              The section 'L<Remedies for Inner
                              Subroutines|general::perl_reference::perl_reference/Remedies_for_Inner_Subroutines>' discusses
                            • Stas Bekman
                              ... [...] ... Yes, thank you! ... When did I say that initializing to undef is good thing? I was talking about initializing variables to the types there are
                              Message 14 of 20 , Oct 15, 2003
                              • 0 Attachment
                                Brian McCauley wrote:
                                > Stas Bekman <stas@...> writes:
                                [...]
                                >>>[...] this is your document so I shall go along with your preferences.
                                >>
                                >>It's not really mine, I just happen to maintain it. From the previous
                                >>discussion it seems that those who cared agreed that it's better to
                                >>explicitly declare vars.
                                >
                                >
                                > I assume that was a typo :-) s/declare/initialize/.

                                Yes, thank you!

                                >>>I've tried to keep it brief by moving some of the points (in
                                >>>particular 'use vars') into comments inside the code examples where
                                >>>they can be expressed more concisely.
                                >>
                                >>Frankly, I can't understand why do you try to undermine the importance
                                >>of always initializing variables.
                                >
                                >
                                > I don't. On the contrary I explain the importance in the narrative
                                > and also re-enforce the importance in comments in the example code. I
                                > have, at your suggestion, pushed into an afterthought any mention of
                                > the fact that if you need to use local() anyhow you can get away
                                > without explicit initialization of package variables.
                                >
                                > Since it appears you _are_ against mentioning it even at the end I'll
                                > remove it completely from porting.pod. I don't care, I'm not on a
                                > crusade here.
                                >
                                >
                                >>Unless you are an advanced user and know what you are doing, it's a
                                >>goodness to always initialize variables before you use them.
                                >
                                >
                                > Of course I agree that initializing variables before you use them is
                                > good. It's just that I think that implicit initialization using my()
                                > or (if you can't use my(), local()) is better than explicit
                                > initialization using undef(). IMNSHO, whenever one sees an explicit
                                > ``$var = undef'' or ``undef($var)'' an alarm bell should ring and ones
                                > first thought should be "is there a missing/misplaced my()/local()?".

                                When did I say that initializing to undef is good thing? I was talking about
                                initializing variables to the types there are going to use, e.g.:

                                my $counter = 0; # numbers
                                my $string = ''; # strings

                                > BUT....
                                >
                                > I can't see why we are still arguing about this. I've worded the
                                > document _as_if_ I agreed with you that explicit initialization was a
                                > "good thing" per se. The fact that we disagree is, therefore, surely,
                                > irrelevant.

                                Most likely we both try to say the same thing, but misunderstanding each other...

                                >>>+The easiest and the fastest way to solve the nested subroutines
                                >>>+problem is to switch from lexical scope to package scope for all
                                >>>+variables for which you get the warning. The C<handler> subroutines
                                >>
                                >>Would it be better to say:
                                >>
                                >>The easiest and the fastest way to solve the nested subroutines
                                >>problem is to switch every lexically scoped variable you get the
                                >>warning for to a global package variable.
                                >
                                >
                                > Yes, that does read more easily. But the dangling "for" now grates.
                                > Particularly the juxtaposition "for to". So I'd keep the "for which"
                                > even if some people consider such strict English grammar to be
                                > affected.

                                I guess it reads better if using commas:

                                The easiest and the fastest way to solve the nested subroutines
                                problem is to switch every lexically scoped variable, you get the
                                warning for, to a global package variable.


                                > I would drop the word "global" since global has many different
                                > meanings. By one definition of "global", the orginal file-scoped
                                > lexical variable was global. By another definition of "global",
                                > package variables (other than ones like %INC) are not global.
                                >
                                > The use of the phrase "global variable" in Perl documentation as a
                                > synonym for "package variable" is AFAIK deprocated.
                                >
                                > Some people use the phase "global package variable" (or "global global
                                > variable" (sic)) to refer to a variable like %INC.
                                >
                                > I've even seen examples where people use the phrase "global variable"
                                > to mean "package variable in package main".

                                Well, the problem I have with this approach is the following: I think of
                                lexical variables as non-accessible from outside the scope thy exist in. This
                                is incorrect for variables declared with 'our' and 'use vars', since those
                                variables are accessible outside the file/package they were defined in. Which
                                makes them non-lexical. No?

                                >>or something like that?
                                >
                                >
                                > OK:
                                >
                                > The easiest and the fastest way to solve the nested subroutines
                                > problem is to switch every lexically scoped variable for which you
                                > get the warning to a package variable.

                                sounds good.

                                >>package scope is lexical scope too.
                                >
                                >
                                > Er, now I'm really confused. The our() function declares a lexically
                                > scoped alias for a package variable - but this is getting far too subtle.

                                See my comment above.

                                >>>+are never called re-entrantly and each resides in a package to itself.
                                >>>+Most of the usual disadvantates of package scoped variables are,
                                >>>+therefore, not a concern. Note, however, that whereas explicit
                                >>>+initialization is often redundant for lexical variables it is usually
                                >>>+not redundant for these package variables as they are reused in
                                >>>+su bsequent executions of the handler.
                                >>
                                >>may I suggest the following wording:
                                >>
                                >>Note, however, that whereas explicit
                                >>initialization is not always necessary for lexical variables it is usually
                                >>not redundant for these global package variables as they persist in
                                >>subsequent executions of the handler and unlike lexical variables,
                                >>don't get automatically destroyed at the end of each handler.
                                >
                                >
                                > Again I dislike the word "global" for reasons already stated.
                                >
                                > I think it would read better if we use consistant terminology. EITHER
                                > "not necessary" v "necessary" OR "redundant" v "not redundant" but NOT
                                > "not necessary" v "not redundant".

                                Agreed.

                                >>>+If the shared variable contains a reference it my hold onto lots of
                                >>
                                >>shared variable? Can we stick to lexical vs. global, and not confuse
                                >>user even further?
                                >
                                >
                                > Er, lexical v _package_

                                OK

                                __________________________________________________________________
                                Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
                                http://stason.org/ mod_perl Guide ---> http://perl.apache.org
                                mailto:stas@... http://use.perl.org http://apacheweek.com
                                http://modperlbook.org http://apache.org http://ticketmaster.com
                              • Stas Bekman
                                Following our discussion of what kind our -declared vars are, it s interesting that today on p5p there is this thread where all kind of /(package|file) scope
                                Message 15 of 20 , Oct 20, 2003
                                • 0 Attachment
                                  Following our discussion of what kind 'our'-declared vars are, it's
                                  interesting that today on p5p there is this thread where all kind of
                                  /(package|file) scope (lexical)? variable/ are discussed.

                                  http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-10/msg00912.html

                                  __________________________________________________________________
                                  Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
                                  http://stason.org/ mod_perl Guide ---> http://perl.apache.org
                                  mailto:stas@... http://use.perl.org http://apacheweek.com
                                  http://modperlbook.org http://apache.org http://ticketmaster.com
                                • Brian McCauley
                                  ... OK, I still find the strict English grammar easier to read in this instance, but I ll go with your form. ... I m sorry I have no idea where that came form.
                                  Message 16 of 20 , Oct 24, 2003
                                  • 0 Attachment
                                    Stas Bekman <stas@...> writes:

                                    > > ... I'd keep the "for which"
                                    > > even if some people consider such strict English grammar to be
                                    > > affected.
                                    >
                                    > I guess it reads better if using commas:
                                    >
                                    > The easiest and the fastest way to solve the nested subroutines
                                    > problem is to switch every lexically scoped variable, you get the
                                    > warning for, to a global package variable.

                                    OK, I still find the strict English grammar easier to read in this
                                    instance, but I'll go with your form.

                                    > > I would drop the word "global" since global has many different
                                    > > meanings.
                                    >
                                    > Well, the problem I have with this approach is the following: I think
                                    > of lexical variables as non-accessible from outside the scope thy
                                    > exist in. This is incorrect for variables declared with 'our' and 'use
                                    > vars', since those variables are accessible outside the file/package
                                    > they were defined in. Which makes them non-lexical. No?

                                    I'm sorry I have no idea where that came form. I said: Let's not use
                                    the term 'global' to describe a Perl package because it has many
                                    meanings to different people. You come back with a discussion of the
                                    meaning of lexical scope.

                                    > >>package scope is lexical scope too.
                                    > >
                                    > > Er, now I'm really confused.
                                    >
                                    > See my comment above.

                                    That would be the comment above where you said "package scope is a
                                    non-lexical scope" (i.e. the exact opposite)?

                                    Anyhow - none of that matters now.

                                    > BTW, let's finish off that porting mystery issue when you get a
                                    > chance... it's been dragging for too long ;) partially because of me ;)

                                    I think porting.pod is done. Now I have to attack perl_reference.pod,
                                    and I assume from what you said before you don't want to release the
                                    one without the other.

                                    --- porting.pod.orig Fri Oct 10 18:58:48 2003
                                    +++ porting.pod Fri Oct 24 13:46:50 2003
                                    @@ -88,7 +88,7 @@

                                    print "Content-type: text/plain\r\n\r\n";

                                    - my $counter = 0;
                                    + my $counter = 0; # Explicit initialization technically redundant

                                    for (1..5) {
                                    increment_counter();
                                    @@ -195,8 +195,8 @@

                                    print "Content-type: text/plain\r\n\r\n";

                                    - my $counter = 0;
                                    -
                                    + my $counter = 0; # Explicit initialization technically redundant
                                    +
                                    for (1..5) {
                                    increment_counter();
                                    }
                                    @@ -228,51 +228,65 @@

                                    It's important to understand that the I<inner subroutine> effect
                                    happens only with code that C<Apache::Registry> wraps with a
                                    -declaration of the C<handler> subroutine. If you put your code into a
                                    -library or module, which the main script require()'s or use()'s, this
                                    -effect doesn't occur.
                                    -
                                    -For example if we move the code from the script into the subroutine
                                    -I<run>, place the subroutines into the I<mylib.pl> file, save it in
                                    -the same directory as the script itself and require() it, there will
                                    -be no problem at all. (Don't forget the C<1;> at the end of the
                                    -library or the require() might fail.)
                                    -
                                    - mylib.pl:
                                    - ---------
                                    - my $counter;
                                    - sub run{
                                    - print "Content-type: text/plain\r\n\r\n";
                                    - $counter = 0;
                                    - for (1..5) {
                                    - increment_counter();
                                    - }
                                    +declaration of the C<handler> subroutine. If you put all your code
                                    +into modules, which the main script C<use()>s, this effect doesn't
                                    +occur.
                                    +
                                    +Do not use Perl4-style libraries. Subroutines in such libraries will
                                    +only be available to the first script in any given interpreter thread
                                    +to C<require()> a library of any given name. This can lead to
                                    +confusing sporadic failures.
                                    +
                                    +The easiest and the fastest way to solve the nested subroutines
                                    +problem is to switch every lexically scoped variable, you get the
                                    +warning for, to a package variable. The C<handler> subroutines are
                                    +never called re-entrantly and each resides in a package to itself.
                                    +Most of the usual disadvantates of package scoped variables are,
                                    +therefore, not a concern. Note, however, that whereas explicit
                                    +initialization is not always necessary for lexical variables it is
                                    +usually necessary for these package variables as they persist in
                                    +subsequent executions of the handler and unlike lexical variables,
                                    +don't get automatically destroyed at the end of each handler.
                                    +
                                    +
                                    + counter.pl:
                                    + ----------
                                    + #!/usr/bin/perl -w
                                    + use strict;
                                    +
                                    + print "Content-type: text/plain\r\n\r\n";
                                    +
                                    + # In Perl <5.6 our() did not exist, so:
                                    + # use vars qw($counter);
                                    + our $counter = 0; # Explicit initialization now necessary
                                    +
                                    + for (1..5) {
                                    + increment_counter();
                                    }
                                    +
                                    sub increment_counter{
                                    $counter++;
                                    print "Counter is equal to $counter !\r\n";
                                    }
                                    - 1;
                                    -
                                    - counter.pl:
                                    - ----------
                                    - use strict;
                                    - require "./mylib.pl";
                                    - run();

                                    -This solution provides the easiest and the fastest way to solve the
                                    -nested subroutines problem, since all you have to do is to move the
                                    -code into a separate file, by first wrapping the initial code into
                                    -some function that you later will call from the script and keeping the
                                    -lexically scoped variables that could cause the problem out of this
                                    -function.
                                    -
                                    -But as a general rule of thumb, unless the script is very short, I
                                    -tend to write all the code in external libraries, and to have only a
                                    -few lines in the main script. Generally the main script simply calls
                                    -the main function of my library. Usually I call it C<init()> or
                                    -C<run()>. I don't worry about nested subroutine effects anymore
                                    -(unless I create them myself :).
                                    +If the variable contains a reference it may hold onto lots of
                                    +unecessary memory (or worse) if the reference is left to hang about
                                    +until the next call to the same handler. For such variables you
                                    +should use C<local> so that the value is removed when the C<handler>
                                    +subroutine exits.
                                    +
                                    + my $query = CGI->new;
                                    +
                                    +becomes:
                                    +
                                    + local our $query = CGI->new;
                                    +
                                    +All this is very interesting but as a general rule of thumb, unless
                                    +the script is very short, I tend to write all the code in external
                                    +libraries, and to have only a few lines in the main script. Generally
                                    +the main script simply calls the main function of my library. Usually
                                    +I call it C<init()> or C<run()>. I don't worry about nested
                                    +subroutine effects anymore (unless I create them myself :).

                                    The section 'L<Remedies for Inner
                                    Subroutines|general::perl_reference::perl_reference/Remedies_for_Inner_Subroutines>' discusses
                                  • Jacob Fugal
                                    (sorry Brian, this was supposed to go to the list... is there any plan to fix the reply-to header on this list?) ... I know, as a newbie to the list, I
                                    Message 17 of 20 , Oct 24, 2003
                                    • 0 Attachment
                                      (sorry Brian, this was supposed to go to the list... is there any plan
                                      to fix the reply-to header on this list?)

                                      Brian McCauley wrote:
                                      > Stas Bekman <stas@...> writes:
                                      >>> ... I'd keep the "for which"
                                      >>>even if some people consider such strict English grammar to be
                                      >>>affected.
                                      >>
                                      >>I guess it reads better if using commas:
                                      >>
                                      >>The easiest and the fastest way to solve the nested subroutines
                                      >>problem is to switch every lexically scoped variable, you get the
                                      >>warning for, to a global package variable.
                                      >
                                      >
                                      > OK, I still find the strict English grammar easier to read in this
                                      > instance, but I'll go with your form.

                                      I know, as a newbie to the list, I probably won't have much sway in
                                      this, but I have to agree with Brian. I read the version above -- the
                                      one with commas -- and it just isn't working for me. My brain just won't
                                      parse that as correct English (or even Englilsh). If I remember my
                                      grammar correctly, you only use commas to set of a descriptive phrase
                                      when it's a noun clause (such as "my friend's cousin", "the big red one
                                      over there", etc.). Prepositional phrases should flow inline with the
                                      noun being described. That's why there're no commas. It becomes, "every
                                      lexically scoped variable you get the error for," if you're not going to
                                      mind the misuse of the preposition. I'd be fine with that under most
                                      circumstances, but the following context makes it weird, which was
                                      probably Brian's original point. Switching to correct use of the
                                      preposition, "for which", fixes that. "...switch every lexically scoped
                                      variable for which you get the warning to a..."

                                      It's not affected -- it's correct. We American's sometimes think of
                                      correct grammar as affected (myself included), but sometimes it's
                                      correct anyways and it actually makes things easier to understand.

                                      Ok, enough of my english rant, flame on :)

                                      Jacob Fugal
                                    • Geoffrey Young
                                      ... welcome. in general, this list is very welcoming to newbies. so, please don t take what I m about to say as being directed toward you... [ elements of
                                      Message 18 of 20 , Oct 24, 2003
                                      • 0 Attachment
                                        > I know, as a newbie to the list,

                                        welcome.

                                        in general, this list is very welcoming to newbies. so, please don't take
                                        what I'm about to say as being directed toward you...

                                        ['elements of style' excerpts snipped]

                                        you know, if y'all spent less time squibbling over minor grammatical points,
                                        and instead channeled all this free energy and tuits into augmenting the
                                        docs with new material, everyone would be better off.

                                        --Geoff
                                      • Jacob Fugal
                                        ... Thanks. ... Agreed :) Unfortunately, I m rather a beginner with modperl -- hence my subscription to this list -- and don t feel comfortable submitting
                                        Message 19 of 20 , Oct 24, 2003
                                        • 0 Attachment
                                          Geoffrey Young wrote:
                                          >
                                          >> I know, as a newbie to the list,
                                          >
                                          >
                                          > welcome.

                                          Thanks.

                                          > in general, this list is very welcoming to newbies. so, please don't
                                          > take what I'm about to say as being directed toward you...
                                          >
                                          > ['elements of style' excerpts snipped]
                                          >
                                          > you know, if y'all spent less time squibbling over minor grammatical
                                          > points, and instead channeled all this free energy and tuits into
                                          > augmenting the docs with new material, everyone would be better off.

                                          Agreed :) Unfortunately, I'm rather a beginner with modperl -- hence my
                                          subscription to this list -- and don't feel comfortable submitting
                                          documentation yet. But hopefully I can and will soon.

                                          Jacob
                                        • Stas Bekman
                                          ... All I wanted to say is that my wording reads better if using commas. I didn t imply that it was better than yours, when using commas. Your wording was just
                                          Message 20 of 20 , Oct 24, 2003
                                          • 0 Attachment
                                            Brian McCauley wrote:
                                            > Stas Bekman <stas@...> writes:
                                            >
                                            >
                                            >>> ... I'd keep the "for which"
                                            >>>even if some people consider such strict English grammar to be
                                            >>>affected.
                                            >>
                                            >>I guess it reads better if using commas:
                                            >>
                                            >>The easiest and the fastest way to solve the nested subroutines
                                            >>problem is to switch every lexically scoped variable, you get the
                                            >>warning for, to a global package variable.
                                            >
                                            >
                                            > OK, I still find the strict English grammar easier to read in this
                                            > instance, but I'll go with your form.

                                            All I wanted to say is that my wording reads better if using commas. I didn't
                                            imply that it was better than yours, when using commas. Your wording was just
                                            fine (and certainly better then mine ;)

                                            [...]

                                            Agreed with the rest of remaining comments to the ongoing comments ;)

                                            > I think porting.pod is done.

                                            Indeed.

                                            > Now I have to attack perl_reference.pod,
                                            > and I assume from what you said before you don't want to release the
                                            > one without the other.

                                            Yes. Let's commit them together. Unless you think that it'll take a long time
                                            before you will come up with perl_reference.pod patches, in which I can I
                                            guess we can commit this one right now.

                                            Thanks Brian!

                                            __________________________________________________________________
                                            Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
                                            http://stason.org/ mod_perl Guide ---> http://perl.apache.org
                                            mailto:stas@... http://use.perl.org http://apacheweek.com
                                            http://modperlbook.org http://apache.org http://ticketmaster.com
                                          Your message has been successfully submitted and would be delivered to recipients shortly.