Re: Getting a / when regex should produce nothing

2010-04-27 Thread Michael Ludwig
Moin André,

Am 26.04.2010 um 21:44 schrieb André Warnier:
 cr...@animalhead.com wrote:
 The retention of values from previous executions applies
 only to global variables.
 
 Ah, yes.
 But that would have triggered another discussion (which it might now 
 still do of course), about what exactly /is/ a global variable, in the 
 context of a mod_perl handler or perl script run under modperl::Registry.

Let's first clarify it for Perl in general, and then for mod_perl.

A global variable in Perl is any variable not declared with my. Which 
includes variables declared with our or use vars (I'll get to these), and 
also variables created by full qualification, as in $Bla::Blub = 1.

A lexical variable in Perl is any variable declared with my, regardless of 
the scope, which may be file-level. Unlike globals, lexical variables aren't 
directly accessible from outside the package.

A global variable declared (or introduced, or admitted) with use vars is in 
scope for the entire package where it is declared. A global variable declared 
with our is in scope only for the lexical scope where it is declared (see 
perldoc -f our).

(There's also local, a misnomer, to temporarily stash away the current value 
of a global variable and shadow it with another value. We can leave it out of 
the picture here.)

Now, how is this different for mod_perl? Well, it isn't, if you think about it, 
or rather it boils down to the difference between a mod_perl handler and your 
typical batch script. Your batch script is invoked, it runs, and ends. Running 
it probably includes some initialization code of yours placed at the file 
level. Next time around, the whole thing start anew. Nothing special here.

A mod_perl handler, as you know, is loaded once, and unless it is reloaded, is 
only acted upon by invocation of its functions, such as handler(). Which means 
that reinitialization doesn't happen automatically, as with your batch script 
running in a new process each time.

So what does this mean for file level lexical variables (my-variables) you have 
defined? Well, they don't get reinitialized (unless you provide code to do so), 
so they start behaving like global variables, retaining state between 
invocations. They are not, however, accessible from outside the current 
package, so they're still lexical variables.

There's one more thing to understand, especially in the context of 
Apache::Registry and Apache2::Registry, and that's lexical my variables 
referenced from nested names subroutines. You do not usually create nested 
named subroutines, but the Registry handler does it for you by wrapping your 
registry script in a handler subroutine in a package made up from the 
filesystem path of rour registry script. So if you define a registry script 
with a subroutine that references a lexical variable from the enclosing scope, 
you'll see the familiar warning message Variable $x will not stay shared.

You can read up about this issue here:

http://perl.apache.org/docs/general/perl_reference/perl_reference.html

Hope this helps :-)

-- 
Michael.Ludwig (#) XING.com



Re: Getting a / when regex should produce nothing

2010-04-27 Thread Torsten Förtsch
On Tuesday 27 April 2010 10:18:17 Michael Ludwig wrote:

 A lexical variable in Perl is any variable declared with my, regardless
  of the scope, which may be file-level. Unlike globals, lexical variables
  aren't directly accessible from outside the package.

Not quite correct. Consider this:

$ perl -Mstrict -le '
  my $x=10;
  our $y=20;
  {
package hugo;

print x=$x;   # references $x outside of package hugo
print y=$y;   # references $main::y
($x,$y)=(1,2);
  }
  print x=$x;
  print y=$y
'
x=10
y=20
x=1
y=2

$x is file-level lexical. It is visible all over the file. The embedded 
package hugo has no influence. Lexical variables are not bound to a package 
but to a lexical scope.

Same with our-variables. Cour declares the visibility of a variable in the 
current lexical scope.

 You can read up about this issue here:
 
 http://perl.apache.org/docs/general/perl_reference/perl_reference.html

Or for German speakers, there was a series of articles about scoping in $foo-
magazin:

  http://foo-magazin.de/

Torsten Förtsch

-- 
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net


Re: Getting a / when regex should produce nothing

2010-04-27 Thread André Warnier

Michael Ludwig wrote:

Moin André,

Am 26.04.2010 um 21:44 schrieb André Warnier:

cr...@animalhead.com wrote:

The retention of values from previous executions applies
only to global variables.

Ah, yes.
But that would have triggered another discussion (which it might now 
still do of course), about what exactly /is/ a global variable, in the 
context of a mod_perl handler or perl script run under modperl::Registry.


Let's first clarify it for Perl in general, and then for mod_perl.

A global variable in Perl is any variable not declared with my. Which includes variables declared with 
our or use vars (I'll get to these), and also variables created by full qualification, as in 
$Bla::Blub = 1.

A lexical variable in Perl is any variable declared with my, regardless of 
the scope, which may be file-level. Unlike globals, lexical variables aren't directly 
accessible from outside the package.

A global variable declared (or introduced, or admitted) with use vars is in scope for the entire 
package where it is declared. A global variable declared with our is in scope only for the 
lexical scope where it is declared (see perldoc -f our).

(There's also local, a misnomer, to temporarily stash away the current value 
of a global variable and shadow it with another value. We can leave it out of the picture 
here.)

Now, how is this different for mod_perl? Well, it isn't, if you think about it, 
or rather it boils down to the difference between a mod_perl handler and your 
typical batch script. Your batch script is invoked, it runs, and ends. Running 
it probably includes some initialization code of yours placed at the file 
level. Next time around, the whole thing start anew. Nothing special here.

A mod_perl handler, as you know, is loaded once, and unless it is reloaded, is 
only acted upon by invocation of its functions, such as handler(). Which means 
that reinitialization doesn't happen automatically, as with your batch script 
running in a new process each time.

So what does this mean for file level lexical variables (my-variables) you have 
defined? Well, they don't get reinitialized (unless you provide code to do so), 
so they start behaving like global variables, retaining state between 
invocations. They are not, however, accessible from outside the current 
package, so they're still lexical variables.

There's one more thing to understand, especially in the context of Apache::Registry and Apache2::Registry, 
and that's lexical my variables referenced from nested names subroutines. You do not usually 
create nested named subroutines, but the Registry handler does it for you by wrapping your registry script in 
a handler subroutine in a package made up from the filesystem path of rour registry script. So if you define 
a registry script with a subroutine that references a lexical variable from the enclosing scope, you'll see 
the familiar warning message Variable $x will not stay shared.

You can read up about this issue here:

http://perl.apache.org/docs/general/perl_reference/perl_reference.html

Hope this helps :-)



Very nice.  And it does help my understanding.
Although the key paragraph here, I would say, is :

So what does this mean for file level lexical variables (my-variables)
you have defined? Well, they don't get reinitialized (unless you provide
code to do so), so they start behaving like global variables, retaining
state between invocations. They are not, however, accessible from
outside the current package, so they're still lexical variables.

Let me give an example of how I understand this, for mod_perl handler 
packages :


# -- start of code --
package My::Something;

my $lexical_mine;

sub access {
my $r = shift;

if (defined($lexical_mine) {
  $r-log_error(in access: value present : $lexical_mine);
  $lexical_mine++;
} else {
  $lexical_mine = 1;
  $r-log_error(in access: initialised to : $lexical_mine);
}
return OK;
}

sub response {
my $r = shift;
if (defined($lexical_mine) {
  $r-log_error(in response: value present : $lexical_mine);
  $lexical_mine++;
} else {
  $lexical_mine = 1;
  $r-log_error(in response: initialised to : $lexical_mine);
}
# .. generate some response for the browser

return OK;
}

sub finalise {
my $r = shift;
my $lexical_mine;
if (defined($lexical_mine) {
  $r-log_error(in finalise: value present : $lexical_mine);
  $lexical_mine++;
} else {
  $lexical_mine = 1;
  $r-log_error(in finalise: initialised to : $lexical_mine);
}
return OK;
}


# -- end of code --

Now if I configure the first of these subs as a PerlAccessHandler and
the second as a PerlResponseHandler, what happens to $lexical_mine ?
It might be lexical, in the sense that there is no way for code in
another file, to access this variable from outside as, for example,
$My::Something::lexical_mine

But for all intents and purposes, this variable is functionally
global, in the sense that throughout the life of the Apache child that
contains this perl interpreter, this variable is shared, not only 

Re: Getting a / when regex should produce nothing

2010-04-27 Thread Perrin Harkins
On Tue, Apr 27, 2010 at 7:16 AM, André Warnier a...@ice-sa.com wrote:
 Now if I configure the first of these subs as a PerlAccessHandler and
 the second as a PerlResponseHandler, what happens to $lexical_mine ?

This is actually import to point out: it makes no difference if you
configure these subs as mod_perl anything.  There is no difference at
all in scoping rules for mod_perl because mod_perl is just the perl
interpreter running inside apache.  The thing that can make it appear
different is the lifecycle of the interpreter, i.e. the fact that it
doesn't exit as soon as your code has run once.  This doesn't change
anything about scoping rules in perl though.

 But for all intents and purposes, this variable is functionally
 global, in the sense that throughout the life of the Apache child that
 contains this perl interpreter, this variable is shared, not only by
 the separate handler subs, but even by subsequent invocations of these
 subs in the course of processing all HTTP requests which happen to be
 processed by this Apache child.(*)

I think it's better to say the variable is persistent rather than
global, and the reason for that is that you're creating a closure.
Again, not a mod_perl thing.  Any time you reference a lexical
variable from outside the sub you're in, it causes a closure.

 On the other hand, if I configure finalise as a PerlSomethingHandler,
 then the $lexical_mine that is defined inside it, does not play along
 with the other one.  It is its own thing, and it will print its own
 incremental sequence 1,1,2,3,4,5
 But it is still global in a sense : while private to the sub
 finalise, it nevertheless is shared between consecutive invocations of
 the same finalise() sub by the same Apache child.

No, this isn't true.  It's not a closure, so it will be undefined
every time you enter the sub.  It will also give you a warning about
reusing the name of a lexical from a larger scope.

 So, back to the basics, my interpretation : by default, consider any
 variable as global/shared and you'll generally stay out of trouble.

Here's another rule you could use: don't reference lexical variables
defined outside of a sub from within that sub.  Either use globals for
things you want shared, or pass in the data you need as parameters.
Then you won't be surprised by closures messing up your ideas about
scoping.

I also suggest that anyone who finds this confusing should have a look
through the information on variable scoping in the perl man pages,
Programming Perl, or perlmonks.org.  It really pays to understand this
stuff.

- Perrin


Re: Getting a / when regex should produce nothing

2010-04-27 Thread craig

On Apr 27, 2010, at 4:16 AM, André Warnier wrote:

So, back to the basics, my interpretation : by default, consider  
any variable as global/shared and you'll generally stay out of  
trouble.



Isn't it true that a variable declared (with my) inside of a
sub (including a handler) starts its existence initialized for
each execution of the sub?  So I consider variables declared
outside of any sub global and get along OK without knowing
what lexical scope means, though I may have to learn someday.

That is all I was trying to say in the post that triggered
this thread's recent display of technical erudition.


(*) which is going to be very confusing in the logfile however, as for
now there is no way to distinguish which child logs a message.
For that, we might want to add ($$) to the log messages.


The 3rd field of Apache log file entries is quite useless, and
I have long used it to include the process ID and keepalive status.
Here's my log file format from httpd.conf:

LogFormat %h %l %P:%{Connection}i%{Connection}o %t \%r\ %s %b \% 
{Referer}i\ \%{User-Agent}i\ keepalive


Best Regards,
cmac



Re: Getting a / when regex should produce nothing

2010-04-27 Thread Michael Ludwig
Torsten Förtsch schrieb am 27.04.2010 um 11:25:33 (+0200):

 On Tuesday 27 April 2010 10:18:17 Michael Ludwig wrote:
 
  A lexical variable in Perl is any variable declared with my,
  regardless of the scope, which may be file-level. Unlike globals,
  lexical variables aren't directly accessible from outside the
  package.
 
 Not quite correct. Consider this:
 
 $ perl -Mstrict -le '
   my $x=10;
   our $y=20;
   {
 package hugo;
 
 print x=$x;   # references $x outside of package hugo
 print y=$y;   # references $main::y

Thanks for catching this. Indeed, lexical variables aren't described
in terms of packages, but in terms of lexical scope.

 $x is file-level lexical. It is visible all over the file. The
 embedded package hugo has no influence. Lexical variables are not
 bound to a package but to a lexical scope.
 
 Same with our-variables. Cour declares the visibility of a variable
 in the current lexical scope.

Variables declared with our are a funny hybrid between global
variables, which are attached to a package, and lexical variables,
which are attached to a scope.

-- 
Michael Ludwig


Re: Getting a / when regex should produce nothing

2010-04-27 Thread Perrin Harkins
On Tue, Apr 27, 2010 at 2:08 PM, Michael Ludwig mil...@gmx.de wrote:
 Variables declared with our are a funny hybrid between global
 variables, which are attached to a package, and lexical variables,
 which are attached to a scope.

They are package variables (usually referred to as globals), which
have a lexically-scoped alias that lets you call them by their short
name.  It's the short name alias that is lexical.

Here's a normal use of a package variable:

package Foo;
use strict;
use warnings;

$Foo::bar = 1;

sub print_it {
print $Foo::bar;
}

And here's the exact same thing, using our to save some typing:

package Foo;
use strict;
use warnings;

our $bar;
$bar = 1;

sub print_it {
print $bar;
}

Aside from the difference in how you refer to the variable, these are identical.

Hope that helps.  If it doesn't, try this:
http://perldoc.perl.org/functions/our.html

- Perrin


Re: Getting a / when regex should produce nothing

2010-04-27 Thread Michael Ludwig
Perrin Harkins schrieb am 27.04.2010 um 14:20:13 (-0400):
 On Tue, Apr 27, 2010 at 2:08 PM, Michael Ludwig mil...@gmx.de wrote:
  Variables declared with our are a funny hybrid between global
  variables, which are attached to a package, and lexical variables,
  which are attached to a scope.
 
 They are package variables (usually referred to as globals), which
 have a lexically-scoped alias that lets you call them by their short
 name.  It's the short name alias that is lexical.

I used to think (and still do so) that non-lexical variables, just
like subroutines, belong to the package they're in and do not need
the package prefix. Using which, however, it is possible to refer
to variables in a package other than the current one, like
$Data::Dumper::Indent = 1 or something similar. But simply writing
$bar in package Foo just refers to $Foo::bar:

  \,,,/
  (o o)
--oOOo-(_)-oOOo--
package Foo;
$bar = 1;
package main;
print bar = $bar;
print Foo::bar = $Foo::bar;
-

$ perl -l /tmp/pkg.pl
bar = 
Foo::bar = 1

It's only the strict pragma that (fortunately) forces you to qualify
your globals. In other words, the alias is not really an alias, but
rather the thing itself, regardless of whether is is excepted from the
strict 'vars' pragma by means of (1) full qualification or (2) use
vars or (3) our.

 Here's a normal use of a package variable:
 
 package Foo;
 use strict;
 use warnings;
 
 $Foo::bar = 1;

I think I've more frequently encountered the form:

use strict; # ban unqualified globals
use vars qw($bar);  # make exceptions
$bar = 1;   # use them

As perldoc -f our informs you, the above has been superseded by our.
However, you still see a lot of use vars for reasons of backward
compatibility.

-- 
Michael Ludwig


Re: Getting a / when regex should produce nothing

2010-04-26 Thread Chris Bennett
I started learning mod_perl versus regular perl for web applications for 
two reasons.
Mod_perl is much faster, but that was only an interest, not quite strong 
enough to push the effort, despite seeing many applications that are 
horribly slow without it.
When someone said that using mod_perl was an easy way to deal with 
having apache chrooted without having to drag all kinds of files inside, 
that made my decision.


I have not regretted it. I have learned many details that I could have 
overlooked with regular perl. Mod_perl is more unforgiving of not 
knowing exactly what my variables are doing and what values they hold


This particular issue has taught me two things.
I am never going to use no warnings 'uninitialized' again. It is too 
dangerous to be overlooking possible problems.
It has also taught me that perl itself may leave values in variables 
such as $1, even after a server stop and start and first running of a 
program. Sounds like an early lesson out of C. Never assume anything is 
in fact defined without defining it yourself.


Nope, not a perl guru, yet. But if you keep on thorough pointing out my 
every error clearly, I guess that will happen sooner! :)


Thanks
Chris Bennett


Re: Getting a / when regex should produce nothing

2010-04-26 Thread André Warnier

Chris Bennett wrote:
...


I have not regretted it. I have learned many details that I could have 
overlooked with regular perl. Mod_perl is more unforgiving of not 
knowing exactly what my variables are doing and what values they hold


Perl and nod_perl are very deterministic, and there is no mystery in 
what they do with variables.  The trick is to understand exactly how 
mod_perl works, and how this plays along with the way Apache (in its 
different MPM variations) works.



This particular issue has taught me two things.
I am never going to use no warnings 'uninitialized' again. It is too 
dangerous to be overlooking possible problems.

I agree.
Maybe even do as Michael said, and make all warnings fatal, if we are 
talking about user/web oriented applications.


It has also taught me that perl itself may leave values in variables 
such as $1, even after a server stop and start and first running of a 
program.

That however, is definitely not the case.
If you stop and start the server, you have a totally new environment, 
and there is nothing left from the previous one.
If you are using a prefork version of the Apache server, then that is 
also true each time an Apache child ends and a new one is started : it 
gets a new perl and a new set of variables.
(but the thing is, you mostly cannot predict when Apache will start a 
new child, nor which child will handle which request).
For other Apache configurations, the situation may be a bit more 
complicated.


The main aspect to understand with mod_perl (as opposed to running a 
perl program without it) :

- when you run a perl script without mod_perl, the sequence is :
  - a new perl interpreter is started, clean
  - your script gets compiled, and gets a brand-new set of variables
  - your script gets run, starting with this new set of variables
  - your script exits
  - perl exits, and returns all its memory to the OS
 .. and the next time you run your script, the same steps happen.

under mod_perl :
  - an Apache child starts, and it gets a new perl
  - your script gets compiled, the first time around. That time, it 
gets a brand-new set of variables.

  - your script gets run, the first time, with these brand-new variables.
  - when the script terminates, whatever is in these variables stays 
there.
  - the perl interpreter inside that same Apache child stays alive, amd 
it remembers the compiled code of your script.


Now is the difference : when a new request comes into Apache, and (as 
may happen) it is sent to the *same* Apache child, it is processed by 
the same perl interpreter.  And that one is not clean : it remembers 
your compiled script, and the state of its variables from the last 
execution.  And that is where it starts from.
The big gain is that perl does not have to compile the script again, it 
can run the compiled code right away.
The big danger is that your variables start with the state in which the 
previous run of the same script in the same Apache child left them.
That can sometimes be put to good use, but it is also deadly if you are 
not very careful.


The above is only a very approximative explanation, and the reality is 
somewhat subtler.  But if you stick to that basic explanation, you will 
avoid much trouble.


The fact that your $1 variable retained a value from an earlier 
comparison however has nothing to do with the above.  That would be true 
even if your script was not running under mod_perl.


 Sounds like an early lesson out of C. Never assume anything is

in fact defined without defining it yourself.

That is a good principle in general (and not only in perl).


A final observation : at the beginning, I think what most perl/web 
programmers find the most interesting aspect of mod_perl is that 
scripts/modules run much faster (because they do not need to be 
re-compiled each time).
But I find that the real benefit is more in terms of how closely it is 
integrated into the Apache insides, and the incredible power it gives 
you to create handlers and filters to let you intervene at just 
about every stage of the processing of a request, and use all the power 
and flexibility of perl (and of the CPAN library) to do all kinds of 
stuff you could not even dream of otherwise.
reading the on-line mod_perl documentation is also a unique way to learn 
how Apache itself works.





Re: Getting a / when regex should produce nothing

2010-04-26 Thread Michael Ludwig
André Warnier schrieb am 26.04.2010 um 10:22:18 (+0200):

 $article_file = $q-param(articlefilename);

 $article_file = $q-param(articlefilename) || '';
 does not add much technically

True, but no benefit either, other than telling the reader that the
empty string is your default value, which would have also been Perl's
default value. It could also be something differing from the Perl
default:

  $article_file = $q-param(articlefilename) || get_dflt_article_name;

 But it makes *explicit* what you are doing, which makes the difference
 to someone maybe not as fluent in perl and who has to look at that
 code in a year's time.

Okay, that's right. On the other hand, PHP works just like Perl without
explicit 'uninitialized' warnings, and I guess this PHP trait is mostly
thought of as a feature. (Which it is.)

 It is on the other hand perfectly ok in my view for a perl guru to
 write perl modules using whatever clever techniques and idioms suit
 him, as long as the module does what it claims to do.  And as long as
 (preferably) any section of such code comes with ample internal
 documentation explaining what it does and what it relies on.

I think that's the important part: document the intent.

-- 
Michael Ludwig


Re: Getting a / when regex should produce nothing

2010-04-26 Thread André Warnier

cr...@animalhead.com wrote:
...

But you left out one important caveat which could scare away
more potential users than it saves.

The retention of values from previous executions applies
only to global variables.


Ah, yes.
But that would have triggered another discussion (which it might now 
still do of course), about what exactly /is/ a global variable, in the 
context of a mod_perl handler or perl script run under modperl::Registry.
I must admit that I am not totally clear on that subject either.  I 
understand the basic idea of scoping, but as to the fine distinctions 
between our and my variables defined/referenced within/without 
various functions defined in the same package, and what mod_perl makes 
of this package when it compiles it, I tend to get a bit confused.  And 
I would not be surprised if the perl documentation to that effect 
confused a relative beginner even more.
So again, to be defensive I find that the safest (if not most 
efficient/elegant) way is to just treat every variable as a potential 
problem, and make sure they are (re-)initialised unless I specifically 
don't want them to be.


This is no critic to the writers of the perl and mod_perl documentation. 
 I am sure that this particular topic is quite hard to get across 
clearly and succintly to perl plodders such as me.
And I find the perl documentation, in general, extremely accessible and 
a treasure-trove of information (and not just about perl).
It's just that on that particular topic I seem to be a bit thick, and 
considering that, I'd rather be safe than sorry.





Re: Getting a / when regex should produce nothing

2010-04-25 Thread Chris Bennett

On 04/24/10 21:38, Chris Bennett wrote:

When I run this first time, with no values from form, I get
$article_file being a / when it should be nothing. I just can't see the
error. I have tried variations with \w and dash at beginning and end,
but no go.

Debug shows blank at A, / at B

#!/usr/bin/perl

$VERSION = 1.0.0;

use warnings;
no warnings 'uninitialized';
use strict;

#use Apache::Constants qw(:common);
use Apache::Request();
#use Apache::Cookie();
use MyPerl::Articulator qw(get_template print_template print_text
submit_changes backup_server see_html template_form load_template);

our $debug = 1;

delete $ENV{PATH};
my $r = Apache-request;
my $q = Apache::Request-new($r, POST_MAX = 100, DISABLE_UPLOADS =
1);
my $site_url = www.example.com;
my $site_directory = /var/www/htdocs/users/example.com;
my $site_name = Example!;
my $secure = 1;
my $article_directory = articles;
undef my $error;
undef my $article_title;
undef my $article_backup_file;
undef my $article_file;
$article_file = $q-param(articlefilename);
if ($debug) { $error .= qq{p$article_file/p};}
$article_file =~ m/^([a-zA-Z0-9_-]*\.html)$/;
$article_file = $1;
if ($debug) { $error .= qq{p$article_file/p};}
$article_backup_file = $article_file;
$article_backup_file =~ s/\.html$/_backup.html/;
undef my $body;

Thanks
Chris Bennett



OK, as per suggestions and adding in another needed part for MultiViews:

my $error = '';
my $article_title ='';
undef my $article_backup_file;
undef my $article_file;
$article_file = $q-param(articlefilename) || '';
if ($debug) { $error .= qq{pA $article_file/p};}
if ($article_file =~ /^([a-zA-Z0-9_-]+\.html.?\w?\w?)$/) {
$article_file = $1;
} else {
$article_file = '';
}
if ($debug) { $error .= qq{pB $article_file/p};}
$article_backup_file = $article_file;
$article_backup_file =~ s/\.html$/_backup.html/;

Is there a better regex for .?\w?\w?

I want a . letter letter not . letter or just two letters etc.

This regex is to prevent read or write access to files up the directory 
tree or non html files. There is also a username password for any write 
access.


undef my $variable is not a common idiom but is seen in Programming Perl 
and other places. Is there any reason I should use my $variable = undef? 
More typing. :)


Why was I getting a / back? Is that an artifact from the perl internals?


Thanks


Re: Getting a / when regex should produce nothing

2010-04-25 Thread Joe Schaefer
- Original Message 

 From: Chris Bennett ch...@bennettconstruction.biz
 To: ch...@bennettconstruction.biz; modperl@perl.apache.org
 Sent: Sun, April 25, 2010 8:17:07 AM
 Subject: Re: Getting a / when regex should produce nothing

 Is there a better regex for .?\w?\w?
 I want a . letter letter not . letter 
 or just two letters etc.

(?:\.\w{2})?

 This regex is to prevent read or write access to 
 files up the directory 
 tree or non html files. There is also a username 
 password for any write 
 access.

 undef my $variable is not a common 
 idiom but is seen in Programming Perl 
 and other places. Is there any reason 
 I should use my $variable = undef? 
 More typing. :)

What's wrong with just typing my $variable;?

 Why was I getting 
 a / back? Is that an artifact
 from the perl internals?

In your previous code you didn't check that the pattern
had matched before using $1.  In the case when your pattern
doesn't match, $1 remains unchanged from whatever last
set it.  There's probably some code earlier on, or internal
to mod-perl, which does a (successful) pattern match that
sets $1 to /.

The lesson here should be to always check the return value
of your regexps for success, especially when you've used 
capture variables in your code like $1-$9.


  


Re: Getting a / when regex should produce nothing

2010-04-25 Thread André Warnier

Chris Bennett wrote:
...

 $article_file = $q-param(articlefilename) || '';

ok, so suppose it is 12345.html.en
...


if ($article_file =~ /^([a-zA-Z0-9_-]+\.html.?\w?\w?)$/) {
$article_file = $1;
} else {
$article_file = '';
}


ok, matches, so it's still 12345.html.en


$article_backup_file = $article_file;


still 12345.html.en


$article_backup_file =~ s/\.html$/_backup.html/;



still 12345.html.en
(because \.html$ did not match)




Re: Getting a / when regex should produce nothing

2010-04-25 Thread Chris Bennett

On 04/25/10 08:57, André Warnier wrote:

Chris Bennett wrote:
...

  $article_file = $q-param(articlefilename) || '';

ok, so suppose it is 12345.html.en
...


if ($article_file =~ /^([a-zA-Z0-9_-]+\.html.?\w?\w?)$/) {
$article_file = $1;
} else {
$article_file = '';
}


ok, matches, so it's still 12345.html.en


$article_backup_file = $article_file;


still 12345.html.en


$article_backup_file =~ s/\.html$/_backup.html/;



still 12345.html.en
(because \.html$ did not match)




I have since changed to:

$article_file = $q-param(articlefilename) || '';
if ($debug) { $error .= qq{pA $article_file/p};}
if ($article_file =~ /^([a-zA-Z0-9_-]+\.html(?:\.\w{2})?)$/) {
$article_file = $1;
} else {
$article_file = '';
}
if ($debug) { $error .= qq{pB $article_file/p};}
$article_backup_file = $article_file;
if ($article_backup_file =~ /\.html(?:\.\w{2})?$/) {
$article_backup_file =~ s/\.html/_backup.html/;
} else {
	$error .= pPlease choose an existing File Name ( like y_9-e.html or 
yyy.html.xx ) or use Fill in Template to create a new file./p;

}

I think this does the trick.
Please feel free to break this! :)


Re: Getting a / when regex should produce nothing

2010-04-25 Thread Michael Ludwig
André Warnier schrieb am 25.04.2010 um 12:44:56 (+0200):

 use warnings;
 That's good. But this :
 
 no warnings 'uninitialized';
 
 is very dubious.

I used to think so, too, but I've recently changed my mind.

 $article_file = $q-param(articlefilename);
 
 will come back undef if :
 - there is no articlefilename input box on the submitted form
 - there is one, but it is not sent by the browser (as some browsers
 may do if the form field has not been filled-in)
 - someone just calls your script by a URL in the location bar, without
 parameters

True, the value will be undef, but so what? Perl treats undef as the
empty string or zero depending on the context, regardless of whether
you've resolved to have yourself harassed with warnings because of
uninitialized values or not; if, however, you *have* done so, then
you'll see those warnings on STDERR and feel that you should fix your
code by doing something like:

  $str = $q-param(articlefilename) || '';
  $num = $bla-calc_blub || 0;

So you're performing manually what Perl does automatically just to get
rid of the warning you've decided to turn on because you thought it was
good, or robust, or solid. If you think about it, you have to admit that
this is not exactly clever.

 if ($debug) { $error .= qq{p$article_file/p};}
 
 This then is dubious too, because you are essentially concatenating a
 string (which may also be undef), with an undef value.

So what? The undef is automatically converted to an empty string. That's
what you want anyway. Let Perl do it for you.

 (And before that, you are passing this undef value to the qq
 function). Who knows what this does ?
 
 Unfortunately, you will never know, because you have disabled warnings
 for that.

There's probably no need to know in this case. If your fix is to convert
undef to an empty string, why not have Perl do it for you?

 Why not do something more solid, like :
 
 remove the no warnings pragma.
 
 $article_file = $q-param(articlefilename) || '';
 (making it equal to an empty string if it is undefined), or more
 explicitly
 $article_file = $q-param(articlefilename);
 $article_file = '' unless defined $article_file;
 
 And the same for any other form parameter you receive.

I've been doing this for ten years now, but I've stopped, because it's
tedious and, I think, pointless. Perl does it for you.

 If you are programming for the web, where you essentially do not know
 which miscreant browser or user is at the other end, you have to
 program defensively.  Suppressing warnings is the wrong way to go.

I wouldn't say so. Either you agree with Perl's automatic conversion of
undef to '' or 0 depending on the context (which apparently you do when
you write || '' or || 0), or you don't agree because you do not want
to tolerate undef at all (because you're counting money, for example).
In the former case, just do as the OP did (no warnings 'uninitialized');
in the latter case consider making your code really robust and the
warning fatal.

For the record, I've changed my mind about this uninitialized business
after reading the perldoc for common::sense by Marc Lehmann:

http://search.cpan.org/~mlehmann/common-sense-3.2/

-- 
Michael Ludwig


Getting a / when regex should produce nothing

2010-04-24 Thread Chris Bennett
When I run this first time, with no values from form, I get 
$article_file being a / when it should be nothing. I just can't see the 
error. I have tried variations with \w and dash at beginning and end, 
but no go.


Debug shows blank at A, / at B

#!/usr/bin/perl

$VERSION = 1.0.0;

use warnings;
no warnings 'uninitialized';
use strict;

#use Apache::Constants qw(:common);
use Apache::Request();
#use Apache::Cookie();
use MyPerl::Articulator qw(get_template print_template print_text 
submit_changes backup_server see_html template_form load_template);


our $debug = 1;

delete $ENV{PATH};
my $r = Apache-request;
my $q = Apache::Request-new($r, POST_MAX = 100, DISABLE_UPLOADS = 1);
my $site_url = www.example.com;
my $site_directory = /var/www/htdocs/users/example.com;
my $site_name = Example!;
my $secure = 1;
my $article_directory = articles;
undef my $error;
undef my $article_title;
undef my $article_backup_file;
undef my $article_file;
$article_file = $q-param(articlefilename);
if ($debug) { $error .= qq{p$article_file/p};}
$article_file =~ m/^([a-zA-Z0-9_-]*\.html)$/;
$article_file = $1;
if ($debug) { $error .= qq{p$article_file/p};}
$article_backup_file = $article_file;
$article_backup_file =~ s/\.html$/_backup.html/;
undef my $body;

Thanks
Chris Bennett

--
A human being should be able to change a diaper, plan an invasion,
butcher a hog, conn a ship, design a building, write a sonnet, balance
accounts, build a wall, set a bone, comfort the dying, take orders,
give orders, cooperate, act alone, solve equations, analyze a new
problem, pitch manure, program a computer, cook a tasty meal, fight
efficiently, die gallantly. Specialization is for insects.
   -- Robert Heinlein


Re: Getting a / when regex should produce nothing

2010-04-24 Thread Chris Bennett

On 04/24/10 21:38, Chris Bennett wrote:

When I run this first time, with no values from form, I get
$article_file being a / when it should be nothing. I just can't see the
error. I have tried variations with \w and dash at beginning and end,
but no go.

Debug shows blank at A, / at B

#!/usr/bin/perl

$VERSION = 1.0.0;

use warnings;
no warnings 'uninitialized';
use strict;

#use Apache::Constants qw(:common);
use Apache::Request();
#use Apache::Cookie();
use MyPerl::Articulator qw(get_template print_template print_text
submit_changes backup_server see_html template_form load_template);

our $debug = 1;

delete $ENV{PATH};
my $r = Apache-request;
my $q = Apache::Request-new($r, POST_MAX = 100, DISABLE_UPLOADS =
1);
my $site_url = www.example.com;
my $site_directory = /var/www/htdocs/users/example.com;
my $site_name = Example!;
my $secure = 1;
my $article_directory = articles;
undef my $error;
undef my $article_title;
undef my $article_backup_file;
undef my $article_file;
$article_file = $q-param(articlefilename);
if ($debug) { $error .= qq{p$article_file/p};}


should be if ($debug) { $error .= qq{pA $article_file/p};}


$article_file =~ m/^([a-zA-Z0-9_-]*\.html)$/;
$article_file = $1;
if ($debug) { $error .= qq{p$article_file/p};}


should be if ($debug) { $error .= qq{pB $article_file/p};}





Re: Getting a / when regex should produce nothing

2010-04-24 Thread craig
See what happens if you replace the 2 lines between the should bes  
with


if ($article_file =~ /^([a-zA-Z0-9_-]*\.html)$/) {$article_file = $1}

I've can't recall seeing 'undef my' before.
my $error = undef; is more typical.

How is this routine executed?  Under ModPerl::Registry?

cmac


On Apr 24, 2010, at 7:47 PM, Chris Bennett wrote:


On 04/24/10 21:38, Chris Bennett wrote:

When I run this first time, with no values from form, I get
$article_file being a / when it should be nothing. I just can't  
see the

error. I have tried variations with \w and dash at beginning and end,
but no go.

Debug shows blank at A, / at B

#!/usr/bin/perl

$VERSION = 1.0.0;

use warnings;
no warnings 'uninitialized';
use strict;

#use Apache::Constants qw(:common);
use Apache::Request();
#use Apache::Cookie();
use MyPerl::Articulator qw(get_template print_template print_text
submit_changes backup_server see_html template_form load_template);

our $debug = 1;

delete $ENV{PATH};
my $r = Apache-request;
my $q = Apache::Request-new($r, POST_MAX = 100,  
DISABLE_UPLOADS =

1);
my $site_url = www.example.com;
my $site_directory = /var/www/htdocs/users/example.com;
my $site_name = Example!;
my $secure = 1;
my $article_directory = articles;
undef my $error;
undef my $article_title;
undef my $article_backup_file;
undef my $article_file;
$article_file = $q-param(articlefilename);
if ($debug) { $error .= qq{p$article_file/p};}


should be if ($debug) { $error .= qq{pA $article_file/p};}


$article_file =~ m/^([a-zA-Z0-9_-]*\.html)$/;
$article_file = $1;
if ($debug) { $error .= qq{p$article_file/p};}


should be if ($debug) { $error .= qq{pB $article_file/p};}