I have a CGI-script for creating new users.
You can either upload a CSV file for a batch
of users or fill out a web for for just 1 user.
So I have a ref to array which contains
either lines from the uploaded CSV file or
just 1 line constructed from the web form:
my $input = $fh ? [ <$fh> ] :
# trick: create a line as if a Lotus Notes CSV-file has
been uploaded
[ sprintf '%s;%s;;;%s;XXX;%s;;;XXX;%s-%s;;%s%s.
%s...@mycompany.com;;XXX;;;;%s;',
$QUERY->param('last'),
$QUERY->param('first'),
$QUERY->param('pass'),
$QUERY->param('user'),
$QUERY->param('company'),
$QUERY->param('city'),
($QUERY->param('company') =~ /^mycompany$/i ? '' :
'ext-'),
$QUERY->param('first'),
$QUERY->param('last'),
($QUERY->param('inform') =~ /nobody/i ? '' : $QUERY-
>param('inform')) ];
my $loh = validate_input($input);
My problem above is that [ <$fh> ] seems
to be evaluated in a scalar context and
I get just 1 line instead of all.
Is there a nice way to force list context on it?
Thanks
Alex
Nope. The inside of [ ] is in list context.
> and I get just 1 line instead of all.
Then your problem is somewhere else.
Ben
> So I have a ref to array which contains
> either lines from the uploaded CSV file or
> just 1 line
The 2nd case is not a "line" since it does not have a newline in it...
> constructed from the web form:
>
> my $input = $fh ? [ <$fh> ] :
> $QUERY->param('last'),
> $QUERY->param('first'),
> $QUERY->param('pass'),
> $QUERY->param('user'),
> $QUERY->param('company'),
> $QUERY->param('city'),
If you put the params into a hash then you can use a "hash slice"
to get the values you want in one go:
my %Q = $QUERY->Vars;
sprintf ... , @Q{ qw/ last first pass user company city / };
> ($QUERY->param('company') =~ /^mycompany$/i ? '' :
> 'ext-'),
A test for equality should *look like* a test for equality:
lc($Q{company}) eq 'mycompany' ? '' : 'ext-';
BTW, there are *two* strings that will match /^mycompany$/
(so it isn't really an equality test...).
Do you know what the two possible matching strings are?
> My problem above is that [ <$fh> ] seems
^^^^^
> to be evaluated in a scalar context and
Find out what context it is in for sure rather than guessing:
sub context {
if ( wantarray )
{ warn "list\n" }
else
{ warn "scalar\n" }
}
my $input = $fh ? [ context() ] : ...
That shows that the <$fh> _is_ in list context.
> I get just 1 line instead of all.
>
> Is there a nice way to force list context on it?
There is no way to "force" list context like there is for scalar context.
To get a list context, you use it in a place where a list is expected,
such as inside of an anonymous array constructor.
The source of your problem must be somewhere else...
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
> My problem above is that [ <$fh> ] seems
> to be evaluated in a scalar context and
> I get just 1 line instead of all.
>
perl -e 'open FH,"<wbtest.pl"; $r= FH ? [ <FH> ] : []; print $#
$r,"\n"'
180
works fine
And there are 1024 strings which will match /^mycompany$/i, which will
make it even less of an equality test :-).
hp
>>> ($QUERY->param('company') =~ /^mycompany$/i ? '' : 'ext-'),
>>
>> A test for equality should *look like* a test for equality:
>>
>> lc($Q{company}) eq 'mycompany' ? '' : 'ext-';
>>
>>
>> BTW, there are *two* strings that will match /^mycompany$/
>> (so it isn't really an equality test...).
>
> And there are 1024 strings which will match /^mycompany$/i, which will
> make it even less of an equality test :-).
LOL. At least 1024.
--
Ruud (maybe more for certain locales)
Maybe I haven't had enough coffee today, but I don't know.
Please share.
--
Glenn Jackman
Write a wise saying and your name will live forever. -- Anonymous
> At 2009-02-26 07:45AM, "Tad J McClellan" wrote:
> > BTW, there are *two* strings that will match /^mycompany$/
> > (so it isn't really an equality test...).
> >
> > Do you know what the two possible matching strings are?
>
> Maybe I haven't had enough coffee today, but I don't know.
> Please share.
Perhaps "mycompany" and "mycompany\n" (on certain platforms).
--
Jim Gibson
-----------------------
#!/usr/bin/perl
use warnings;
use strict;
$_ = "mycompany\n";
print "matched\n" if /^mycompany$/;
$_ = "mycompany";
print "matched\n" if /^mycompany$/;
-----------------------
The original problem was in fact
not the list/scalar context,
but that my regex didn't match because of \x0d
(uploaded Lotus Notes CSV file in DOS format,
but the script itself runs on Linux)
On what platforms is that not true?
I thought that perl's IO layer normalized line endings, so that that
should be true on ALL platforms.
IO is irrelevant here. If you have a Perl string containing
"mycompany\n" it will match /^mycompany$/, regardless of how it ended up
with those contents.
Of course, if you read a line from an ordinary text file on Win32 with a
binmoded filehandle, the string returned will be "mycompany\r\n" and
will not match, but that's a completely different question :).
Ben
<snip>
>>> Perhaps "mycompany" and "mycompany\n" (on certain platforms).
>>
>> On what platforms is that not true?
>>
>> I thought that perl's IO layer normalized line endings, so that that
>> should be true on ALL platforms.
>
> IO is irrelevant here. If you have a Perl string containing
> "mycompany\n" it will match /^mycompany$/, regardless of how it ended up
> with those contents.
>
> Of course, if you read a line from an ordinary text file on Win32 with a
> binmoded filehandle, the string returned will be "mycompany\r\n" and
> will not match,
You don't need binmode() for that to be true.
$ cat -vE w32.txt
mycompany^M$
$ cat test.pl
open my $fh, '<', 'w32.txt' or die $!;
print <$fh> =~ /^mycompany$/ ? "Match\n" : "No match\n";
$ perl test.pl
No match
$
To make it *not* be true, i.e. to make the string match, you can binmode
the filehandle with the :crlf layer.
$ cat test.pl
open my $fh, '<', 'w32.txt' or die $!;
binmode $fh, ':crlf';
print <$fh> =~ /^mycompany$/ ? "Match\n" : "No match\n";
$ perl test.pl
Match
$
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
Given that most Win32 machines don't have cat(1), and that the usual
prompt on Win32 isn't '$', I am going to presume that you are not,
in fact, running this on Win32.
On Win32, unless you've set the PERLIO environment variable, the default
filehandle layers are ":unix:crlf".
Ben
MinGW and Cygwin, no matter how they perturb the environment, run
under Windows. ActiveState Perl does not, I believe, depend on
anything else, and therefore could be run equally well from cmd or a
shell.
As a practical matter, I run enough scripts on Windows (whether
under bash or cmd) and have hit the problem enough that I do
chomp;
s/\r+$//;
as a matter of rote, or instead use \s if I want to strip all trailing
whitespace whatsoever.
--
Tim McDaniel, tm...@panix.com
> As a practical matter, I run enough scripts on Windows (whether
> under bash or cmd) and have hit the problem enough that I do
> chomp;
> s/\r+$//;
> as a matter of rote, or instead use \s if I want to strip all trailing
> whitespace whatsoever.
Why not just
s/[\r\n]+$//;
in one operation and skip the chomp?
--
Jim Gibson
Well, obviously I misunderstood your statement. Thanks for the
clarification.
> On Win32, unless you've set the PERLIO environment variable, the default
> filehandle layers are ":unix:crlf".
Hmm.. I had no idea. Seems not even to be disabled by
binmode $fh, ':raw';
:(
Sorry, I was being snarky :).
> > On Win32, unless you've set the PERLIO environment variable, the default
> > filehandle layers are ":unix:crlf".
>
> Hmm.. I had no idea.
It's been the case since long before PerlIO existed. Turning off the
default "\r\n"->"\n" conversion on Win32 is, in fact, the reason
'binmode' existed in the first place.
> Seems not even to be disabled by
>
> binmode $fh, ':raw';
Have you tried it, or are you getting this from the docs? I don't have a
Win32 machine to hand, but AIUI either
binmode $fh;
or
binmode $fh, ":raw";
ought to switch the :crlf layer into a mode where it no longer does
"\r\n"->"\n" translation. I don't believe the layer actually goes away,
but it becomes exactly equivalent to a :perlio layer. Is this not
correct?
Ben
I'm afraid that I'm guilty of a great deal of confusion, which explains
my remarks above. Please disregard them.
I thought that \n means \015\012 on Windows. Now - after having re-read
your comments, re-read the "Newlines" section in "perldoc perlport", and
played around some more - I'm slowly realizing that it means \012 just
as on *nix, and that the \015\012 newline is only used on *saved* text
files.
Suddenly everything you said in this thread makes a lot of sense, also
to me. ;-) Thanks for the lesson!
> ... either
>
> binmode $fh;
>
> or
>
> binmode $fh, ":raw";
>
> ought to switch the :crlf layer into a mode where it no longer does
> "\r\n"->"\n" translation. I don't believe the layer actually goes away,
> but it becomes exactly equivalent to a :perlio layer. Is this not
> correct?
Probably. This is the test I did:
C:\home>type test.pl
open $fh, '<', 'w32.txt' or die $!;
print 'No binmode() : ',
<$fh> =~ /^mycompany$/ ? "Match\n" : "No match\n";
open $fh, '<', 'w32.txt' or die $!;
binmode $fh;
print 'binmode() without layer : ',
<$fh> =~ /^mycompany$/ ? "Match\n" : "No match\n";
open $fh, '<', 'w32.txt' or die $!;
binmode $fh, ':raw';
print 'binmode() with :raw : ',
<$fh> =~ /^mycompany$/ ? "Match\n" : "No match\n";
open $fh, '<', 'w32.txt' or die $!;
binmode $fh, ':crlf';
print 'binmode() with :crlf : ',
<$fh> =~ /^mycompany$/ ? "Match\n" : "No match\n";
C:\home>test.pl
No binmode() : Match
binmode() without layer : No match
binmode() with :raw : No match
binmode() with :crlf : Match
C:\home>
The result is the same as before, but suddenly it's in accordance with
my expectations. :)
Second thought. Please read this extract from "perldoc perlport":
"Perl uses \n to represent the "logical" newline, where what is logical
may depend on the platform in use. In MacPerl, \n always means \015. In
DOSish perls, \n usually means \012, but when accessing a file in "text"
mode, STDIO translates it to (or from) \015\012, depending on whether
you're reading or writing."
Doesn't it say that STDIO changes the meaning of \n on Windows? But that
is not correct, is it? Or am I still missing something?
I thought it meant that it changes it so reading \015\012 would
translate it to \n, and writing it would change it from \n to \015\012.
It's been a _long time_ since I've used Windows. Maybe run a couple of
quick tests to verify and see exactly what it's doing (to avoid any
confusion), and then you'll know.
--
Tim Greer, CEO/Founder/CTO, BurlyHost.com, Inc.
Shared Hosting, Reseller Hosting, Dedicated & Semi-Dedicated servers
and Custom Hosting. 24/7 support, 30 day guarantee, secure servers.
Industry's most experienced staff! -- Web Hosting With Muscle!
That's apparently what's happening. I'm just questioning the possible
lack of clarity in that para.
> It's been a _long time_ since I've used Windows. Maybe run a couple of
> quick tests to verify and see exactly what it's doing (to avoid any
> confusion), and then you'll know.
I did that already. :)
> Tim Greer wrote:
>> Gunnar Hjalmarsson wrote:
>>> Gunnar Hjalmarsson wrote:
>>>> I thought that \n means \015\012 on Windows. Now - after having
>>>> re-read your comments, re-read the "Newlines" section in "perldoc
>>>> perlport", and played around some more - I'm slowly realizing that
>>>> it means \012 just as on *nix, and that the \015\012 newline is
>>>> only used on *saved* text files.
>>>
>>> Second thought. Please read this extract from "perldoc perlport":
>>>
>>> "Perl uses \n to represent the "logical" newline, where what is
>>> logical may depend on the platform in use. In MacPerl, \n always
>>> means \015. In DOSish perls, \n usually means \012, but when
>>> accessing a file in "text" mode, STDIO translates it to (or from)
>>> \015\012, depending on whether you're reading or writing."
>>>
>>> Doesn't it say that STDIO changes the meaning of \n on Windows? But
>>> that is not correct, is it? Or am I still missing something?
>>
>> I thought it meant that it changes it so reading \015\012 would
>> translate it to \n, and writing it would change it from \n to
>> \015\012.
>
> That's apparently what's happening. I'm just questioning the possible
> lack of clarity in that para.
>
Well, now you have me wondering, too. :-)
>Gunnar Hjalmarsson wrote:
>
>> Gunnar Hjalmarsson wrote:
>>> I thought that \n means \015\012 on Windows. Now - after having
>>> re-read your comments, re-read the "Newlines" section in "perldoc
>>> perlport", and played around some more - I'm slowly realizing that it
>>> means \012 just as on *nix, and that the \015\012 newline is only
>>> used on *saved* text files.
>>
>> Second thought. Please read this extract from "perldoc perlport":
>>
>> "Perl uses \n to represent the "logical" newline, where what is
>> logical may depend on the platform in use. In MacPerl, \n always means
>> \015. In DOSish perls, \n usually means \012, but when accessing a
>> file in "text" mode, STDIO translates it to (or from) \015\012,
>> depending on whether you're reading or writing."
>>
>> Doesn't it say that STDIO changes the meaning of \n on Windows? But
>> that is not correct, is it? Or am I still missing something?
>>
>
>I thought it meant that it changes it so reading \015\012 would
>translate it to \n, and writing it would change it from \n to \015\012.
>It's been a _long time_ since I've used Windows. Maybe run a couple of
>quick tests to verify and see exactly what it's doing (to avoid any
>confusion), and then you'll know.
Why don't you create a binary file in windows and insert 10 or 13 on a few
lines (but not both), then the pair in a few (reverse a few too), then
check the results.
Or, dial up Wally and ask him.
-sln
"Hey Wally, whats in that 'if()' statement?".
-sln
Who are you talking to? Who's using Windows? Who's creating a binary
file and needs to do that test? Were you replying to Gunnar?
> "Hey Wally, whats in that 'if()' statement?".
> -sln
You remind me of Xah Lee. You aren't really him, are you?
It's a little unclear, and of course the reference to STDIO is
incorrect. What it means is
In DOSish perls, "\n" means "\012", but when accessing a file by
default a :crlf layer is pushed which will result in "\015\012"
appearing in the file.
Ben
That sounds much better to me. I sent a bug report:
http://rt.perl.org/rt3/Public/Bug/Display.html?id=63620
(noted that the oldest open docs ticket is 8 years old...)
That would assume that $/ contains only carriage returns and ASCII
newlines (that is, not considering the "\n" special casing that gets
done when doing I/O on non-binary files). However, in practice for
me, $/ DOES contain only CR and NL.
--
Tim McDaniel, tm...@panix.com
What "\n" special casing?
http://groups.google.com/group/comp.lang.perl.misc/msg/932b35d8434e2f11