[19397] in Perl-Users-Digest
Perl-Users Digest, Issue: 1592 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Aug 22 21:10:31 2001
Date: Wed, 22 Aug 2001 18:10:14 -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: <998529014-v10-i1592@ruby.oce.orst.edu>
Content-Type: text
Perl-Users Digest Wed, 22 Aug 2001 Volume: 10 Number: 1592
Today's topics:
New to group - I'll start with a question <diablo@prometheus.humsoc.utas.edu.au>
Re: New to group - I'll start with a question (Eric Bohlman)
Re: New to group - I'll start with a question (Tad McClellan)
Re: New to group - I'll start with a question (Malcolm Dew-Jones)
Re: New to group - I'll start with a question <matthew.garrish@sympatico.ca>
Re: New to group - I'll start with a question <diablo@prometheus.humsoc.utas.edu.au>
Re: New to group - I'll start with a question <samneric@tigerriverOMIT-THIS.com>
Re: New to group - I'll start with a question <ronh@iainc.com>
Re: Openning a file (Tad McClellan)
Re: Openning a file <krahnj@acm.org>
Re: Openning a file (Tad McClellan)
Re: perl4 bashing (was Re: syntax & compilation errors) <skj@iobox.fi>
Re: redirect stderr for sub-routine <just@usenet.please>
Re: repeating substituation (Ian Boreham)
Re: Txt file contents, numbers and commas <goldbb2@earthlink.net>
Re: Way to do database read to disk instead of memory? <goldbb2@earthlink.net>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Thu, 23 Aug 2001 09:41:43 +1000
From: "Mr Q. Z. Diablo" <diablo@prometheus.humsoc.utas.edu.au>
Subject: New to group - I'll start with a question
Message-Id: <diablo-0A94F7.09414323082001@newsroom.utas.edu.au>
Hi all,
Here's an interesting one that appears in the perlop man page and may
well be explained in the perlre man page but I couldn't find it at first
glance.
An expression like:
($fred,$mary,$bill) = $names =~ /^(a.*)(m.*)(w.*)$/
will assign "alfred" to $fred, "mary" to $mary and "william" to $bill if
$names = "alfredmarywilliam".
That is, if the results of a matching operator are placed in an array,
the array will be ($1, $2, $3, ...).
Any clues as to _why_ this is the case. Very handy it is but it seems
inconsistent with the rest of the way that Perl works (to me, anyway).
Thanks in advance,
Mr Q. Z. D.
----
Drinker, systems administrator, wannabe writer, musician and all-round bastard.
"If chance supplied a loaf of white bread,
Two casks of wine and a leg of mutton,
In the corner of a garden with a tulip-cheeked girl
There'd be enjoyment no Sultan could outdo." - Omar Khayyam.
------------------------------
Date: 23 Aug 2001 00:03:01 GMT
From: ebohlman@omsdev.com (Eric Bohlman)
Subject: Re: New to group - I'll start with a question
Message-Id: <9m1h7l$e4r$1@bob.news.rcn.net>
Mr Q. Z. Diablo <diablo@prometheus.humsoc.utas.edu.au> wrote:
> Here's an interesting one that appears in the perlop man page and may
> well be explained in the perlre man page but I couldn't find it at first
> glance.
> An expression like:
> ($fred,$mary,$bill) = $names =~ /^(a.*)(m.*)(w.*)$/
> will assign "alfred" to $fred, "mary" to $mary and "william" to $bill if
> $names = "alfredmarywilliam".
> That is, if the results of a matching operator are placed in an array,
> the array will be ($1, $2, $3, ...).
> Any clues as to _why_ this is the case. Very handy it is but it seems
> inconsistent with the rest of the way that Perl works (to me, anyway).
It's the difference between list context and scalar context. In list
context, a match will return a list of everything that was captured by
parentheses. Whenever you have an assignment and the *left side* of the
assignment is enclosed in parentheses, the stuff on the *right side* of
the assignment is evaluated in list context. Note carefully that
parentheses around the *right side* of an assignment do *not* force list
context; this is a common misconception. The context of an assignment is
determined by the nature of the thingy ("thingy" is a technical term in
Perl) getting assigned to.
------------------------------
Date: Wed, 22 Aug 2001 19:13:48 -0400
From: tadmc@augustmail.com (Tad McClellan)
Subject: Re: New to group - I'll start with a question
Message-Id: <slrn9o8f5c.4nd.tadmc@tadmc26.august.net>
Mr Q. Z. Diablo <diablo@prometheus.humsoc.utas.edu.au> wrote:
> Subject: New to group - I'll start with a question
Please put the subject of your article in the Subject of your article.
>Here's an interesting one that appears in the perlop man page and may
>well be explained in the perlre man page but I couldn't find it at first
>glance.
It is explained in the perlop man page:
"If the C</g> option is not used, C<m//> in list context returns a
list consisting of the subexpressions matched by the parentheses in the
pattern, i.e., (C<$1>, C<$2>, C<$3>...)."
>An expression like:
>
>($fred,$mary,$bill) = $names =~ /^(a.*)(m.*)(w.*)$/
>
>will assign "alfred" to $fred, "mary" to $mary and "william" to $bill if
>$names = "alfredmarywilliam".
>Any clues as to _why_ this is the case.
Because it is very handy.
>Very handy it is but it seems
Oh, you already knew that.
>inconsistent with the rest of the way that Perl works (to me, anyway).
Well we can't read your mind, so we can address that part.
Got an example of what you mean by that?
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
------------------------------
Date: 22 Aug 2001 17:13:37 -0800
From: yf110@vtn1.victoria.tc.ca (Malcolm Dew-Jones)
Subject: Re: New to group - I'll start with a question
Message-Id: <3b844ab1@news.victoria.tc.ca>
Mr Q. Z. Diablo (diablo@prometheus.humsoc.utas.edu.au) wrote:
: Hi all,
: Here's an interesting one that appears in the perlop man page and may
: well be explained in the perlre man page but I couldn't find it at first
: glance.
: An expression like:
: ($fred,$mary,$bill) = $names =~ /^(a.*)(m.*)(w.*)$/
: will assign "alfred" to $fred, "mary" to $mary and "william" to $bill if
: $names = "alfredmarywilliam".
: That is, if the results of a matching operator are placed in an array,
: the array will be ($1, $2, $3, ...).
: Any clues as to _why_ this is the case. Very handy it is but it seems
: inconsistent with the rest of the way that Perl works (to me, anyway).
_why_ - It's designed that way. I don't understand how this is
"inconsistent with the rest of the way that Perl works".
You want to assign values to a bunch of variables. Since the m// operator
has identified a bunch of substrings, it makes sense to assign that bunch
of substrings to the bunch of variables.
This is very consistent with the way perl works.
On the left you have a list of things. This makes the expression have a
list context. When used in a list context, perl expressions have a habit
of returning lists of values.
--
Want to access the command line of your CGI account? Need to debug your
installed CGI scripts? Transfer and edit files right from your browser?
What you need is "ispy.cgi" - visit http://nisoftware.com/ispy.cgi
------------------------------
Date: Wed, 22 Aug 2001 20:13:38 -0400
From: "Matt Garrish" <matthew.garrish@sympatico.ca>
Subject: Re: New to group - I'll start with a question
Message-Id: <9WXg7.40242$wZ3.3086597@news20.bellglobal.com>
"Mr Q. Z. Diablo" <diablo@prometheus.humsoc.utas.edu.au> wrote in message
news:diablo-0A94F7.09414323082001@newsroom.utas.edu.au...
> Any clues as to _why_ this is the case. Very handy it is but it seems
> inconsistent with the rest of the way that Perl works (to me, anyway).
i like the yoda-speak! this little sketch, help you it will. but then again
maybe it won't... depends on what you think the inconsistency is?
($fred,$mary,$bill) = $names =~ /^(a.*)(m.*)(w.*)$/
($fred,$mary,$bill) = ('alfredmarywilliam' =~ /^(a.*)(m.*)(w.*)$/)
($fred,$mary,$bill) = (alfred),(mary),(william)
$fred = alfred
$mary = mary
$bill = william
------------------------------
Date: Thu, 23 Aug 2001 10:50:08 +1000
From: "Mr Q. Z. Diablo" <diablo@prometheus.humsoc.utas.edu.au>
Subject: Re: New to group - I'll start with a question
Message-Id: <diablo-BC694D.10500823082001@newsroom.utas.edu.au>
In article <slrn9o8f5c.4nd.tadmc@tadmc26.august.net>,
tadmc@augustmail.com wrote:
> Mr Q. Z. Diablo <diablo@prometheus.humsoc.utas.edu.au> wrote:
>
> > Subject: New to group - I'll start with a question
>
>
> Please put the subject of your article in the Subject of your article.
>
>
> >Here's an interesting one that appears in the perlop man page and may
> >well be explained in the perlre man page but I couldn't find it at first
> >glance.
>
>
> It is explained in the perlop man page:
>
> "If the C</g> option is not used, C<m//> in list context returns a
> list consisting of the subexpressions matched by the parentheses in
> the
> pattern, i.e., (C<$1>, C<$2>, C<$3>...)."
>
>
> >An expression like:
> >
> >($fred,$mary,$bill) = $names =~ /^(a.*)(m.*)(w.*)$/
> >
> >will assign "alfred" to $fred, "mary" to $mary and "william" to $bill if
> >$names = "alfredmarywilliam".
>
>
> >Any clues as to _why_ this is the case.
>
>
> Because it is very handy.
>
>
> >Very handy it is but it seems
>
>
> Oh, you already knew that.
>
>
> >inconsistent with the rest of the way that Perl works (to me, anyway).
>
>
> Well we can't read your mind, so we can address that part.
>
> Got an example of what you mean by that?
I suppose what I mean is "why is the array on the left stuffed with $1,
$2, $3, etc. or is it just an arbitrary piece of functionality included
because it is useful. Is 'it is useful' the rationale behind this piece
of syntax?"
Mr Q. Z. D.
----
Drinker, systems administrator, wannabe writer, musician and all-round bastard.
"If chance supplied a loaf of white bread,
Two casks of wine and a leg of mutton,
In the corner of a garden with a tulip-cheeked girl
There'd be enjoyment no Sultan could outdo." - Omar Khayyam.
------------------------------
Date: Wed, 22 Aug 2001 20:58:29 -0400
From: Samneric <samneric@tigerriverOMIT-THIS.com>
Subject: Re: New to group - I'll start with a question
Message-Id: <MPG.15ee1f45c365d632989691@news.onemain.com>
Mr Q. Z. Diablo wrote:
> Here's an interesting one that appears in the perlop man page and may
> well be explained in the perlre man page but I couldn't find it at first
> glance.
[snip]
The perl docs should not be used as a source of "interesting" questions.
They should be used as a source of answers.
That "may well" involve more than a "first glance".
------------------------------
Date: Thu, 23 Aug 2001 01:04:59 GMT
From: "Ron Hartikka" <ronh@iainc.com>
Subject: Re: New to group - I'll start with a question
Message-Id: <%EYg7.76$qw2.1557@typhoon.mw.mediaone.net>
Maybe you need to read about context in perldata.
Anyway, in perlop it says:
If the /g option is not used, m// in a list context returns a list
consisting of the subexpressions
matched by the parentheses in the pattern, i.e., ($1, $2, $3...).
*end quote*
Maybe a little easier to see in this version...
$_= "alfredmarywilliam";
($fred,$mary,$bill) = /^(a.*)(m.*)(w.*)$/;
print join " ",($fred,$mary,$bill) ; # prints: alfred mary william
... Here, m// is bound, by default, to $_ instead of being bound to $names
by =~ as in your example.
And, here m// is clearly in a list context.
You are asking for a list, perl is returning a list.
I imagine Larry Wall thinking: "Hmmm... What shall I have m// return in a
list context? Well, what lists are there?"
Any help?
"Mr Q. Z. Diablo" <diablo@prometheus.humsoc.utas.edu.au> wrote in message
news:diablo-0A94F7.09414323082001@newsroom.utas.edu.au...
> Hi all,
>
> Here's an interesting one that appears in the perlop man page and may
> well be explained in the perlre man page but I couldn't find it at first
> glance.
>
> An expression like:
>
> ($fred,$mary,$bill) = $names =~ /^(a.*)(m.*)(w.*)$/
>
> will assign "alfred" to $fred, "mary" to $mary and "william" to $bill if
> $names = "alfredmarywilliam".
>
> That is, if the results of a matching operator are placed in an array,
> the array will be ($1, $2, $3, ...).
>
> Any clues as to _why_ this is the case. Very handy it is but it seems
> inconsistent with the rest of the way that Perl works (to me, anyway).
>
> Thanks in advance,
>
> Mr Q. Z. D.
> ----
> Drinker, systems administrator, wannabe writer, musician and all-round
bastard.
> "If chance supplied a loaf of white bread,
> Two casks of wine and a leg of mutton,
> In the corner of a garden with a tulip-cheeked girl
> There'd be enjoyment no Sultan could outdo." - Omar Khayyam.
------------------------------
Date: Wed, 22 Aug 2001 17:47:15 -0400
From: tadmc@augustmail.com (Tad McClellan)
Subject: Re: Openning a file
Message-Id: <slrn9o8a33.4du.tadmc@tadmc26.august.net>
SpeedCancer <gmandesigns@hotmail.com> wrote:
>Is it possible to open and close a file in a sub routine?
Yes.
>Im using this code but it does'nt seem to work
^^^^^^^^^^^^^^^^^^^^
What _does_ it do?
What do you want it to do instead?
Do you have warnings enabled?
>&openfile (ARGUMENTLIST)
^^^^^^^^^^^^
You should quote your strings.
>sub openfile
> use strict;
Syntax error. This is not even real code, is it?
> my $filename = ("file.txt");
> open FILEHANDLE, "<$filename" or die "Could not open file: $!\n";
^^^^^^^^^^
^^^^^^^^^^
> my @text = <FH>;
^^
^^
One of these is not like the other, one of these things just
isn't the same...
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
------------------------------
Date: Wed, 22 Aug 2001 22:54:47 GMT
From: "John W. Krahn" <krahnj@acm.org>
Subject: Re: Openning a file
Message-Id: <3B843899.D03D5821@acm.org>
Tassilo von Parseval wrote:
>
> SpeedCancer wrote:
>
> > my $filename = ("file.txt");
>
> This is dangerous. On the left, you have scalar context and on the right
> a one-element list.
> Interestingly enough, Perl does in fact store the string in the
> variable. I would have expected that it assigned 1 to $filename. Perhaps
> one of DWIMings.
You don't have a list on the right hand side, it is just a string
literal in parentheses. Parentheses do not a list make and are also used
to disambiguate associativity and precedence.
> However: my $filename = 'file.txt';
> Single quotes will do since you do not interpolate anything inside the
> string.
>
> > open FILEHANDLE, "<$filename" or die "Could not open file: $!\n";
^^^^^^^^^^
> > my @text = <FH>;
^^
Two different file handles. No wonder it doesn't work.
>
> close FILEHANDLE; # when it is no longer needed.
John
--
use Perl;
program
fulfillment
------------------------------
Date: Wed, 22 Aug 2001 18:45:09 -0400
From: tadmc@augustmail.com (Tad McClellan)
Subject: Re: Openning a file
Message-Id: <slrn9o8dfl.4ij.tadmc@tadmc26.august.net>
Tassilo von Parseval <Tassilo.Parseval@post.rwth-aachen.de> wrote:
>SpeedCancer wrote:
>> my $filename = ("file.txt");
>
>This is dangerous. On the left, you have scalar context and on the right
>a one-element list.
This cannot be true, as there is no such thing as a list in
scalar context.
The RHS above is _not_ a list.
Even if it was:
my $filename = ("file.txt", 'otherfile.txt');
it _still_ wouldn't be a list, it would be a comma operator. So
it would behave as described in perlop when in scalar context,
and $filename would get otherfile.txt.
Let's try an experiment and see what context it is in:
------------------------------
#!/usr/bin/perl -w
use strict;
my $filename = ( context() );
#my $filename = context();
print "$filename\n";
sub context { return wantarray ? 'list' : 'scalar' }
------------------------------
Prints "scalar" with or without parenthesis.
>Interestingly enough, Perl does in fact store the string in the
>variable. I would have expected that it assigned 1 to $filename.
No, that is what _arrays_ do in scalar context. There are
no arrays in the above. This is one of the places where the
distinction does matter:
Perl FAQ, part 4:
"What is the difference between a list and an array?"
>Perhaps
>one of DWIMings.
Just a scalar on the left and a scalar on the right. Nothing
earth-shattering going on there.
>However: my $filename = 'file.txt';
>Single quotes will do since you do not interpolate anything inside the
>string.
That is good advice.
> close FILEHANDLE; # when it is no longer needed.
So is that.
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
------------------------------
Date: Thu, 23 Aug 2001 02:52:57 +0300
From: Sami Jarvinen <skj@iobox.fi>
Subject: Re: perl4 bashing (was Re: syntax & compilation errors)
Message-Id: <MPG.15ee63da16f74c459896a6@news.yhteys.mtv3.fi>
Anno Siegel <anno4000@lublin.zrz.tu-berlin.de> wrote
>>> tadmc@augustmail.com (Tad McClellan) wrote in message
>>>> You are using a dead, flea-bitten camel carcass perl.
> Call me a pedant, but I can never read that quip without noting that
> no self-respecting flea would be seen *near* a dead camel, not to
> mention bite it.
Call me a pedant, but I doubt that the concept of self-respect means
anything to a flea.
------------------------------
Date: Wed, 22 Aug 2001 15:40:53 -0700
From: "Um... Oh" <just@usenet.please>
Subject: Re: redirect stderr for sub-routine
Message-Id: <3b8418cb_1@binarykiller.newsgroups.com>
"Tassilo von Parseval" <Tassilo.Parseval@post.rwth-aachen.de> wrote in
message news:3B8429E1.1040501@post.rwth-aachen.de...
> Um... Oh wrote:
>
> What is <$fh> exactly?
It's supposed to be reading from a file handle.
> Anyway, I don't really have an idea what you
> want.
I'm trying to capture the output of a sub-
routine which I haven't written.
For example:
do_the_magic_redirecting_thing;
call_ftp_routine_i_didn't_write;
if (there was an error) {
print_what_the_ftp_routine_wrote_to_stderr;
}
print STDERR "Other things I need STDERR for\n";
This part works for me:
> open STDERR, ">err.log"
> or die "Error: Could not redirect stderr: $!";
But after:
> close STDERR;
I can't write to STDERR anymore.
I want to restore STDERR so I can use it elsewhere. How do I do that?
Thanks.
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
Check out our new Unlimited Server. No Download or Time Limits!
-----== Over 80,000 Newsgroups - 19 Different Servers! ==-----
------------------------------
Date: 22 Aug 2001 17:39:17 -0700
From: ianb@ot.com.au (Ian Boreham)
Subject: Re: repeating substituation
Message-Id: <f02c4576.0108221639.132113fe@posting.google.com>
Richard Chamberlain <richard@sunsetandlabrea.com> wrote in message news:<fKRc7.23444$e%3.2547952@news2-win.server.ntlworld.com>...
> Hi,
>
> I'm using the following code:
>
> $sectionHTML=~s/'/\\'/g;
> $sectionHTML=~s/ffffff/000000/g;
> $sectionHTML=~s/\"Times\"/\"Verdana\"/g;
>
> so I'm replacing ' with \', ffffff with 000000 and "Times" with "Verdana"
> in a big document.
Are you doing it line-by-line, or have you slurped the entire document
into one string? Will you only be trying to match plain strings, or
more complex patterns also (I guess not, based on your example)?
> I'm sure there is probably a much better way of doing that.
>
> Any pointers?
It depends what you mean by better. Are you looking for a fast
solution? A maintainable one? A prettier one? A cleverer one?
Unfortunately, answering these sorts of questions usually involves
knowing more about the data and the context. Since you mention a large
document, I will assume that speed is your main criterion. I will also
assume that the strings to be matched are relatively sparse. I will
also assume that there are no issues like "Times" appearing in the
text as well as the mark-up (in which case, you are going to need to
use a proper parser, and not just blindly substitute using s///.
(But even using a parser, how would you cope with something along the
lines of (ignoring my incorrect syntax and the awful quoting):
<style font="Times">"Times" are printed below in "Times"; "distances"
in "Courier"</style>
)?
Processing a large file is generally more efficient line-by-line, if
the data allows it.
If the match strings are relatively sparse, you can get good
efficiency gains using a single (merged) regex (similar to that
recommended by another poster), but with a lookahead assertion using a
character class based on the first characters of the pattern string
set.
# Untested
s/(?=[Tf])(Times|ffffff)/$replacement{$1}/
The lookahead assertion will fail at almost every position, allowing
the regex engine to step to the next position without getting into the
slower "|" alternation at all. You will get through the string in one
pass, relatively quickly.
If matching substrings are relatively dense, gains will be smaller (or
perhaps even negative, since successful matches bear the extra cost of
the lookahead).
If the pattern strings are not known ahead of time, you would have to
construct your lookahead character class first from the first
characters of the strings, as well as the alternation sequence (whose
elements should be quoted properly for use in a regex, in case they
contain characters that would be misinterpreted as regex
metacharacters).
If you allow the specification of more complex patterns, you probably
can't generate a character class for the lookahead.
For almost everything you need to know about regexes, see Jeffrey
Friedl's "Mastering Regular Expressions". Although it doesn't cover
many of the new features of Perl regexes, it is still required
reading.
Regards,
Ian
------------------------------
Date: Wed, 22 Aug 2001 18:19:03 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: Txt file contents, numbers and commas
Message-Id: <3B842FD7.7CA45A4C@earthlink.net>
PaAnWa wrote:
>
> I would like to be able to read a txt file containing a number and
> display the number with proper comma formatting. For example, if the
> file contains the number 2345, I would like "2,345" displayed;
> similarly, if the file contains the number 345987, I would like
> "345,987" displayed.
>
> Here is the code I am currently using:
>
> #!/usr/bin/perl
#!/usr/bin/perl -wT
use strict;
> use CGI qw(:standard);
>
> $file=param('file')
You need a ; on the end of this expression. Also, what happens if $file
is something you don't want anyone on the web to read/edit?
my ($countername) = param('file') =~ m[^([-a-zA-Z0-9._])\z];
This prevents $file from having any unsafe characters, and untaints it.
As a result, it can only be a single path component, and will not have
any shell metacharacters.
if( !length($countername) or $countername =~ /^\.\.?$/ ) {
print header( -status => "403 Invalid parameter" );
print begin_html( "Invalid parameter" );
print h1( "Invalid characters in 'file' parameter" );
print end_html;
exit;
}
my $file = "/home/httpd/misc/counter/" . $countername;
You can use any path you want, but regardless of where it is, having a
special directory *just* for counters is a good idea, since it prevents
bugs or security holes in the counter program corrupting other data, and
it prevents other programs from accidentally corrupting the counters.
> ######################################################################
> # Read the current file #
> ######################################################################
>
> open(COUNT,$file);
> $total=<COUNT>;
> close(COUNT);
Always, yes, *always*, check the return value of open. Also, you've got
a race condition -- if two browsers access the counter at the same time,
then you can end up with funky data in the file... the counter could be
encremented once from two accesses, or even end up being zeroed. To
avoid race conditions, you need to flock.
unless( open( COUNT, "<+", $file ) ) {
print header( -status => "403 Invalid parameter" );
print begin_html( "Invalid parameter" );
print h1( "Couldn't open $file: <XMP>$!</XMP>" );
print end_html;
exit;
}
eval {
require Fcntl qw(:flock);
unless( flock(COUNT, LOCK_EX) ) {
print header( -status => "503 Service Unavailable" );
print begin_html("Error locking counter file");
print h1( "Unable to flock $file: <XMP>$!</XMP>" );
print end_html;
exit;
}
};
my $total = <COUNT>;
Note that I do not close COUNT here, but keep it open [and keep the lock
around]
> ######################################################################
> # Update the count file #
> ######################################################################
>
> $total++; # Add 1 to the number
> open(COUNT,">$file");
> print COUNT $total; # Replace old count with new count
> close(COUNT);
Since COUNT is still open, I don't have to re-open it, merely seek to
the beginning.
unless( seek( COUNT, 0, 0 ) ) {
print header( -status => "500 Internal Error" );
print begin_html("Unable to seek() on filehandle");
print h1("Couldn't seek to beginning of $file: <XMP>$!</XMP>");
print end_html;
exit;
}
print COUNT, ++$total, "\n";
# if not for the fact that the file monotonically increases in length,
# I would need to also a truncate here.
unless( close(COUNT) ) {
print header( -status => "500 Internal Error" );
print begin_html("Error closing filehandle");
print h1("Error when closing $file: <XMP>$!</XMP>");
print end_html;
exit;
}
>
> ######################################################################
> # Print Section #
> ######################################################################
>
> print header;
>
> print $total;
The default mimetype of header is text/html, so you should be printing
out html... or else you should be changing the mimetype.
So either:
print header, begin_html, $total, end_html;
or
print header("text/plain"), $total;
Hmm, I forgot... you wanted to commafy $total, didn't you?
ok:
1 while $total =~ s/(?<=\d+)(\d\d\d)/,$1/g;
or:
$total =~ s/(?<=\d)(\d\d\d)(?=(?:\d\d\d)*$)/,$1/g;
or:
$total = reverse $total;
$total =~ s/(\d\d\d)(?=\d)/$1,/g;
$total = reverse $total;
Note that the last one is the fastest. Maybe a future perl will have a
/r flag for s/// which will have the effect of the two reverse()s here.
>
> exit;
--
I'm not a programmer but I play one on TV...
------------------------------
Date: Wed, 22 Aug 2001 21:10:31 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: Way to do database read to disk instead of memory?
Message-Id: <3B845807.6E4A027@earthlink.net>
Jane B. wrote:
>
> Question:
>
> If I run a 'select' statement from Perl that retrieves thousands of
> rows into an array, that data is stored in memory (correct?).
Correct. This is a good reason why *not* to use the fetchall_ methods.
> Is there a variable that can be set to tell Perl to store that data
> temporarily on disk?
This is a case of an XY problem: "An XY problem is where someone asks
how to do X because he thinks it will help to accomplish Y. Knowing
what Y is will often help people give better advice." You want to avoid
having all the results of the select in memory. Incorrect solution:
fetch them all and write them to disk then read them from disk one at a
time. Correct solution: fetch and deal with one record at a time
(using one of the fetchrow_* methods) inside a loop, letting each record
go out of memory when you're done with it.
> I need to query two tables, save the data into two arrays and then
> process the data. This is the only way to get the output that I need.
No, it's not. Instead of doing two queries, one on each table, do a
single query on a JOIN of the tables [JOIN is in all caps here because I
mean it as the SQL keyword]. Whether it's a left or right join, and
whether it's an inner or outer join, depends on what you're doing.
> However I know that I'm going to have memory problems if all the data
> is saved to memory. The database in Informix. I'm running Perl on a
> Unix platform.
If you absolutely MUST save two huge arrays, then do it as this:
use POSIX qw(tmpnam);
use BerkeleyDB;
use Storable;
my (@array1, @array2)
my @biguns = \(@array1, @array2);
for my $num ( 0 .. 1 ) {
my $tmpname = tmpnam;
local *array = $buguns[$num];
my $db = tie @array, "BerkeleyDB",
-Flags, DB_CREATE,
-Filename, $tmpname;
eval qq[END { unlink "$tmpname" }];
$db->filter_store_value( sub { $_ = freeze $_ } );
$db->filter_fetch_value( sub { $_ = thaw $_ } );
my $tablename = "table" . (1+$num);
my $sth = $dbi->prepare( qq[ SELECT * from $table ] );
$sth->execute;
while( my $row = $sth->fetchrow_arrayref )
push @array, $row;
}
}
# do stuff with @array1, @array2
--
I'm not a programmer but I play one on TV...
------------------------------
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 1592
***************************************