54352Re: PATCH porting.pod "First Mystery"
- Sep 5, 2003Stas Bekman <stas@...> writes:
> local is perl4-ism, nowadays it's used only for localizing specialUsing package variables and local() in to do the job of block-scoped
> perl variables, like $|.
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.Only in really obscure circumstances. Of course, if at the same time,
> Agreed, but it's not the proper change, your change can break
you make an unrelated change that breaks the code I can see how you'd
be tempted to blame me. :-)
> Assuming that we had:No, that's not my change, I said to change "my" to "local our". I
> use warnings;
> my $counter = 0;
> print "hit $counter times";
> Your change:
> use warnings;
> local our $counter;
> print "hit $counter times";
didn't say to remove initialization.
> > Anyhow, local() does something quite different. It undefines it uponYes, I know that.
> > 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.
> I don't think it has anything to do with finalization, it just looks"Bluebells are not blue, they are actually pink and just look like
> like it does.
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
> However I'm not against your 'local our' solution, I'm just sayingThe porting guide assumes we start with a working CGI script. If a
> 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.
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 exampleThe example in my modified porting.pod already shows explicit
local our $counter = 0;
> after that suggest that you can say 'local our $foo' to globalize andThat fails to mention the real reason for using local.
> localize it at the same time if you prefer to init those to undef via
> local(). Sounds like a good compromise to me.
> > [ about use vars ]How about we leave the example as I have it now and say:
> The guide is written to reduce the number of questions, not raise
> their number. Solution: mention both (our and use vars)
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
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 realise that the simple file handle example was a poor choice to
> I didn't suggest that particular use
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 beI'm glad we agree on something :-)
> moved to the perl_reference.pod doc...
> To summarize:Since the 'my' that is being replaced by 'local our' also initializes
> - 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.
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
> - for users of perl < 5.6 suggest to use 'use vars' instead of 'our'.Yes, basically.
> - point to perl_reference.pod for other workarounds/solutions.
> Does it sound good?
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
- << Previous post in topic Next post in topic >>