[18672] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 840 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sat May 5 21:10:31 2001

Date: Sat, 5 May 2001 18:10:12 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Message-Id: <989111412-v10-i840@ruby.oce.orst.edu>
Content-Type: text

Perl-Users Digest           Sat, 5 May 2001     Volume: 10 Number: 840

Today's topics:
    Re: Perl and MySQL problem (Garry Williams)
    Re: Printing HTTP headers/body in perl <Juha.Laiho@iki.fi>
    Re: regular expression <goldbb2@earthlink.net>
    Re: removing the \n from the data obtained from a text  <goldbb2@earthlink.net>
    Re: removing the \n from the data obtained from a text  <goldbb2@earthlink.net>
    Re: reverse of perlcc (Clinton A. Pierce)
    Re: reverse of perlcc <bop@mypad.com>
    Re: sub z {return } print ((($x,$y)=z) ? "yes:$x,$y\n"  <rick.delaney@home.com>
    Re: warnings from MIME-Lite <randy@theoryx5.uwinnipeg.ca>
    Re: WTD: PERL SCRIPT writing for small task, payment no <dbmartin5@home.com>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Sun, 06 May 2001 00:15:17 GMT
From: garry@ifr.zvolve.net (Garry Williams)
Subject: Re: Perl and MySQL problem
Message-Id: <slrn9f95sl.mv.garry@zfw.zvolve.net>

On Fri, 04 May 2001 15:33:20 GMT, King Fu <kingfu@blueyonder.co.uk> wrote:

> hi ive got a strange problem i cant seem to work out, im trying to update a
> field for a certain in a mysql database using the insert sql command, most
                                                    ^^^^^^^^^^^^^^^^^^
Well, actually, you are not showing an INSERT.  You are showing an
*UPDATE*.  

> of the time this works fine but on occastion i find that all the field for
> all the records in the table have been updated!!! Im not sure why this is
> occuring, 

The only sensible reason is that the WHERE clause in your UPDATE
statement is including all of the records in the table.  

Others have mentioned that you are probably ending up with a WHERE
clause that is matching everything.  

> its a cgi script so is obvously occuring under certain
> circumstances when a visitor does a certain thing but without knowing what
> they do im kinda screwed!
> heres the snippit of what appears to be the problem code

> $sth=$dbh->prepare("SELECT name from downloads WHERE name LIKE '%$name%';")
>|| die "Prepare failed: $DBI::errstr\n";
> $sth->execute() || die "Coultdnt execute query: $DBI::errstr\n";
> $foundMatch=0;
> $foundMatch=$sth->rows();

This is an unreliable way to know if there are any selected records.
As a matter of fact, the DBI manual page specifically says that the
only way to know how many rows are returned from a SELECT query is to
retrieve them.  It is entirely possible for a driver to return -1 from
$sth->rows() when there are no rows in the SELECTed set.  The manual
page documents this behavior.  (Actually, the DBD::mysql driver seems
to return the correct number of rows for a SELECT in my tests with
very small sets, but the DBI manual page is explicit about not relying
on that behavior.)  

  my ($foundMatch) = $sth->fetchrow_array;

This will set $foundMatch to the value of the name column in the first
selected row from the downloads table.  If no rows match the WHERE
clause, it will be set to undef.  Maybe the paranoid would now check
defined-ness to know if any rows were selected.  

Incidentally, there is another possibility here.  The fetch*() methods
can encounter errors.  If you set RaiseError to true on your call to
connect(), then this code is fine.  If not, you really should check
for an error return from fetchrow_array().  

> #if a match is found increment the number of downloads for the file
> if($foundMatch)
> {
>   $sth=$dbh->prepare("SELECT downloads from downloads WHERE name LIKE
> '%$name%';") || die "Prepare failed: $DBI::errstr\n";

This seems convoluted.  Maybe you wanted to do the select only once
and get both columns in one go.  Why do you select from the same table
twice with the same WHERE clause?  

>   $sth->execute() || die "Coultdnt execute query: $DBI::errstr\n";
>   $downloads=$sth->fetchrow_array();

    ($downloads) = $sth->fetchrow_array();

The fetchrow_array() method returns a list.  Your code obfuscates that
fact.  

>   $downloads++;
>   #save the new downloads var to the database
>   $sth=$dbh->prepare("UPDATE downloads SET downloads=$downloads WHERE name
> LIKE '%$name%';") || die "Prepare failed: $DBI::errstr\n";
>   $sth->execute() || die "Coultdnt execute query: $DBI::errstr\n";
>   &printNewDownloadWindow;
> }

Why are you using LIKE in the WHERE clause?  Are there more than one
rows that you expect to be updated?  What is the key of the downloads
table?  Is it name?  Then use equality in the WHERE clause of the
UPDATE query.  That will make sure you are only updating the row that
you intend.  

I'll have a go at an *untested* alternative based on what I think
you're trying to do: 

  my $sel = $dbh->prepare(qq(
	  SELECT name, downloads
	  FROM   downloads
	  WHERE  name LIKE '%$name%'
	  ));	# RaiseError catches errors

  my $updt = $dbh->prepare(q(
	  UPDATE downloads
	  SET    downloads = ?
	  WHERE  name      = ?
	  ));	# RaiseError catches errors

  $sel->execute;	# RaiseError catches errors

  while ( my ($name, $count) = $sel->fetchrow_array ) {
      $updt->execute(++$count, $name);
  }

This code doesn't use the LIKE predicate; instead it matches an exact
key.  (That will eliminate the problem you describe.)  If your table
does not have unique values for the name column, this won't do what I
think you expect.  

-- 
Garry Williams


------------------------------

Date: 5 May 2001 05:53:12 GMT
From: Juha Laiho <Juha.Laiho@iki.fi>
Subject: Re: Printing HTTP headers/body in perl
Message-Id: <9d04g8$2mp$1@ichaos.ichaos-int>

"Eric" <mail@NOSPAMericmarques.net> said:
>I want to make a perl script
>to show the headers/content the browser sends to the script in the http
>request
>i dont mean to just print the environment variables
>i want to read the exact headers/body everything the browser sends to the
>script

Then you cannot run your script as a CGI, but the script must include the
HTTP server functionality as well. It's the function of the HTTP server to
read the headers and convert some of them to environment variables
according to the CGI cpecification. As someone else mentioned, reading
through the CGI spec might be an enligtening experience.

The request body you do get in the stdin (for some methods such as POST)
even when running as a CGI; the server would have no idea what to do with
that content.

So, was not a perl question. Apologies to the group for taking up the
bandwidth to provide the non-perl answer here.
-- 
Wolf  a.k.a.  Juha Laiho     Espoo, Finland
(GC 3.0) GIT d- s+: a C++ UH++++ UL++++$ P++@ L+++ E(-) W+$@ N++ !K w !O
         !M V PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h--- r+++ y+++
"...cancel my subscription to the resurrection!" (Jim Morrison)


------------------------------

Date: Sat, 05 May 2001 22:57:00 GMT
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: regular expression
Message-Id: <3AF485BF.46D64489@earthlink.net>

Bart Lateur wrote:
> 
> Martin Bower wrote:
> 
> >some words + go on this line        23.57
> >some other rubbish +   N/A
> >
> >$Rate = $_;
> >$Rate =~ s/.*(\d+\.\d+)/$1/g;
> >
> >I'd like to store the either the number or "N/A" in $RATE
> 
> $RATE is not $Rate. Perl is a case sensitive language.
> 
>         ($Rate) = /(\S+)\s*$/;
> or
>         ($Rate) = /(\d+\.?\d*|N\/A)/;

Remember that you can always use m to change the delimiters, so you
don't have to backslash slashes.  The above could be written as:
	($Rate) = m[(\d+\.?\d*|N/A)];
To make it even more legible, add some more whitespace and comments.
	($Rate) = m[(
		-?		# an optional -
		\d+		# required digits
		(\.\d+)?	# an optional decimal portion
		([eE]\d+)?	# an optional exponent
		| N/A		# or the string N/A
	)$]x;

I use [and comment] a more complicated, but hopefully more correct,
regular expression.  The x at the end makes the parser ignore the
whitespace and comments.  Using m[] insdead of // allows me to use / as
a literal inside the expression without needing to escape it.

The $ at the end means that only the number or N/A at the end of the
string is matched, and not any other numbers or N/As elsewhere.

Also, although this was intruduced by Bart Lateur, not me, I feel I
should mention that by assigning to ($Rate), it results in a list
context, so returns all the things captured by ()s from all matches.

With only one capture, this could also have been done
	m[(pattern here)$]; $Rate = $1;
though it is probably silly to do so.

You could also have done:
	$Rate = (split m[(pattern here)])[-2];
But this is even sillier.

And I hope that you already know that $_ is used whenever there is no =~
specifying a string to operate on.

-- 
C Error #009: FATAL! Portable code found


------------------------------

Date: Sat, 05 May 2001 21:35:22 GMT
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: removing the \n from the data obtained from a text area in a form
Message-Id: <3AF4734E.104938F6@earthlink.net>

Anno Siegel wrote:
> 
> According to Walter Hafner  <hafner-usenet@ze.tu-muenchen.de>:
> 
> > Occasionaly I have to process files of unknown origin. I.e., the
> > files were written by my coworkers, some under Windows, some under
> > Unix - no Macs. My scripts have to work on all of them. Since I
> > can't tell the format, I use constructs like
> >
> > while (<>) {
> >       s/\r//;
> >       chomp;
> >       # process one line after the other
> > }
> >
> > to remove all the line delimiters. Is this the most effective way or
> 
> Looks fine to me, except it may destroy literal carriage return
> characters that may be embedded without being part of a newline
> sequence.
> 
> > should I use constructs like
> >
> > while (<>) {
> >       $/ = '\r\n' if /\r\n/;
> 
> You want double quotes: "\r\n".
> 
> >       chomp;
> >       # process one line after the other
> > }
> >
> > Very messy, because of the comparison in every single line. But if I
> > pull the $/ line out of the loop, i loose the first line.
> 
> This approach looks better, not so much for efficiency reasons but
> because it avoids the slight risc above.
> 
> Since you are reading from <>, you should not rely on the file being
> seekable or even to be able to re-open it.  (This would be the
> simplest approach to re-reading the first line.)  So just reorganize
> the read loop to use a buffer:
> 
>     $_ = <>;
>     $/ = "\r\n" if defined $_ and substr( $_, -2) eq "\r\n";
>     while ( defined $_ ) {
>         chomp;
>         # process one line after the other
>         $_ = <>;
>     }

And what happens if he is running the script on win and the file being
processed came from unix?  Then that first <> will end up slurping in
the whole file, unable to find any \r\n!  Also, we usually want *only*
the processing code inside the loop.

$/ = "\n"; $_ = <>;  # explicitly set $/ to unixish
$/ = "\r\n" if( substr( $_, -2 ) eq "\r\n" );
for( ; chomp; $_ = <> ) {
	# process a line
}

Note that I use the return value of chomp, rather than a defined() test.
This means that if the last line of the file doesn't end in a newline,
it doesn't get processed.  This is generally something to worry about,
but if you don't like it, use the following:

$/ = "\n"; $_ = <>;  # explicitly set $/ to unixish
$/ = "\r\n" if( substr( $_, -2 ) eq "\r\n" );
for( chomp; defined; chomp $_ = <> ) {
	# process a line
}

If you know that the script is being executed on unix, then the first
assignment to $/ can be ommited, but the other stuff is needed.

Of course, since this is perl, and there is no One True Way, I offer
another method.

{ local $/ = undef; $_ = <>; }
foreach (split m[\r?\n]) {
	# process a line
}

This has the con of reading in the whole file at once, but the pro of
not needing to chomp and of leaving $/ what it originally was.

-- 
Shift to the left, shift to the right, mask in, mask out, BYTE, BYTE,
BYTE !!!


------------------------------

Date: Sat, 05 May 2001 22:10:26 GMT
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: removing the \n from the data obtained from a text area in a form
Message-Id: <3AF47B82.E641D035@earthlink.net>

Benjamin Goldberg wrote:
[snip]
> Of course, since this is perl, and there is no One True Way, I offer
> another method.
> 
> { local $/ = undef; $_ = <>; }
> foreach (split m[\r?\n]) {
>         # process a line
> }
> 
> This has the con of reading in the whole file at once, but the pro of
> not needing to chomp and of leaving $/ what it originally was.

Oh, and the con of not handling $. for you.

-- 
Shift to the left, shift to the right, mask in, mask out, BYTE, BYTE,
BYTE !!!


------------------------------

Date: Sat, 05 May 2001 20:13:48 GMT
From: clintp@geeksalad.org (Clinton A. Pierce)
Subject: Re: reverse of perlcc
Message-Id: <0aZI6.85356$k04.17268262@news1.rdc1.mi.home.com>

In article <4DII6.3$qY3.3382@news20.bellglobal.com>,
	"flash" <bop@mypad.com> writes:
> i need a way to convert c code to perl, can it be done?

Yes, and for about $40/hour I'll send a programmer over to do it.

-- 
    Clinton A. Pierce              Teach Yourself Perl in 24 Hours  *and*
  clintp@geeksalad.org         Perl Developer's Dictionary -- May 2001
"If you rush a Miracle Man,     for details, see http://geeksalad.org     
	you get rotten Miracles." --Miracle Max, The Princess Bride


------------------------------

Date: Sat, 05 May 2001 20:40:02 GMT
From: "flash" <bop@mypad.com>
Subject: Re: reverse of perlcc
Message-Id: <CyZI6.18148$_f3.379797@news20.bellglobal.com>

I have already started.
and im almost done.

I was just wondering for future.
"Clinton A. Pierce" <clintp@geeksalad.org> wrote in message
news:0aZI6.85356$k04.17268262@news1.rdc1.mi.home.com...
> In article <4DII6.3$qY3.3382@news20.bellglobal.com>,
> "flash" <bop@mypad.com> writes:
> > i need a way to convert c code to perl, can it be done?
>
> Yes, and for about $40/hour I'll send a programmer over to do it.
>
> --
>     Clinton A. Pierce              Teach Yourself Perl in 24 Hours  *and*
>   clintp@geeksalad.org         Perl Developer's Dictionary -- May 2001
> "If you rush a Miracle Man,     for details, see http://geeksalad.org
> you get rotten Miracles." --Miracle Max, The Princess Bride




------------------------------

Date: Sat, 05 May 2001 19:10:25 GMT
From: Rick Delaney <rick.delaney@home.com>
Subject: Re: sub z {return } print ((($x,$y)=z) ? "yes:$x,$y\n" : "no\n")
Message-Id: <3AF45359.97722B4A@home.com>

Anno Siegel wrote:
> 
> According to Ilmari Karonen  <usenet11446@itz.pp.sci.fi>:

> Yes, that's one of the tenets of the Perl Order.  I wonder how slices
> used like
> 
>     $x = @y[ 0 .. 3];
> 
> fit in.  Unless we decide to postulate a list context to the right
> of "=" for the slice all by itself, I wouldn't know how to call the
> right side of the assignment, except a list in scalar context.

Why not "an array slice in scalar context".  It is the operation
(slicing) that is put in context.  There is no need to postulate a list
context for the slice by itself since that presupposes that the
operation will produce a list (which you then want to say is in scalar
context).

The operation will return a scalar since it is in scalar context.  And a
slice in scalar context will return the last element of the slice, _as
if_ it were equivalent to the corresponding comma separated expression. 
In this case that would be

    $x = ($y[0], $y[1], $y[2], $y[3]);

which isn't a list in scalar context either.  Incidentally, the two are
not exactly equivalent.  Can anyone show an example where they exhibit
different semantics?  And no, I'm not offering a prize.

-- 
Rick Delaney
rick.delaney@home.com


------------------------------

Date: 5 May 2001 15:26:12 GMT
From: Randy Kobes <randy@theoryx5.uwinnipeg.ca>
Subject: Re: warnings from MIME-Lite
Message-Id: <9d162k$1ee$1@canopus.cc.umanitoba.ca>

In comp.lang.perl.misc, Mike Solomon <msolomon@3s-technology.com> wrote:
> When I run a script that uses MIME-Lite to send E-mail I get the following
> warnings :

> Use of uninitialized value in substitution (s///) at
>         D:/Perl/site/lib/MIME/Lite.pm line 998 (#1)
[ ... ]
> Use of uninitialized value in scalar assignment at
>         D:/Perl/site/lib/Net/Domain.pm line 193 (#1)
> Use of uninitialized value in pattern match (m//) at
>         D:/Perl/site/lib/Net/Domain.pm line 217 (#1)

> Without disabling diagnostics or editing Lite.pm and Domain.pm, is there any
> way to disable these messages ?

Some modules in the libnet package try to get information
about the user and network you're on through environment
variables if certain functions (eg, getpwuid) aren't available.
Try setting the HOME, NAME, and DOMAIN environment variables.

best regards,
randy kobes


------------------------------

Date: Sat, 05 May 2001 23:05:32 GMT
From: David <dbmartin5@home.com>
Subject: Re: WTD: PERL SCRIPT writing for small task, payment no problem!
Message-Id: <el19ftgd07sl4bfhv7seqcu3s5u66rkm6d@4ax.com>

You may wish to mention if this is DOS, Unix, etc.

If unix either Perl or a shell script will do.

On Wed, 2 May 2001 17:15:29 +0100, "Helen Greenacre"
<helen.greenacre@ntlworld.com> wrote:

>Hi
>
>I do not know Perl myself and need a script writing, payment is no
>problem...see below..
>
>The task
>---------
>A text file is produced from our system, it could contain a number of lines
>(around 10-60) it looks something like this
>
>23456076, ee, 12,12,12, 31/10/2001
>03046789, es, 33,12,12, 12/12/2001
>03446889, es, 33,12,12, 12/12/2001
>06049789, es, 33,12,12, 12/12/2001
>13046789, es, 33,12,12, 12/12/2001
>
>etc etc...
>
>The beginning 8 numbers on each line represent a file which is actually a
>PDF (so, example first line 23456076 is infact 23456076.pdf etc..)
>
>I need a Perl script that looks a the 'input' file and looks at the first 8
>digits of each line, then looks at a mapped drive (one location) to find the
>relevant files (which all end with .pdf), the script would then have to COPY
>(not move) the pdf's into another mapped drive..
>
>A log file must be produced that displays the files that have been found and
>those that have not (ie the ones that have errored or missing)
>
>I have a small program that constantly scans folders for input files and
>then runs a certain command on them, the idea would be that the original
>input text file is dropped into a 'hot' folder, the Perl script then runs
>against this file etc....
>
>If anyone would be interested in writing this script (to run on a Windows NT
>workstation) please E-mail me to discuss timescale/price etc..
>
>Thanks
>
>Helen
>
>
>



------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc.  For subscription or unsubscription requests, send
the single line:

	subscribe perl-users
or:
	unsubscribe perl-users

to almanac@ruby.oce.orst.edu.  

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.

For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V10 Issue 840
**************************************


home help back first fref pref prev next nref lref last post