[19458] in Perl-Users-Digest
Perl-Users Digest, Issue: 1653 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Aug 30 06:05:31 2001
Date: Thu, 30 Aug 2001 03:05:10 -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: <999165910-v10-i1653@ruby.oce.orst.edu>
Content-Type: text
Perl-Users Digest Thu, 30 Aug 2001 Volume: 10 Number: 1653
Today's topics:
Re: a perl module dedicated to lists ? (Logan Shaw)
Re: A Question about reference lifetimes <goldbb2@earthlink.net>
ANNOUNCE: Champaign-Urbana Perl Mongers meeting Tue Sep (Daniel S. Lewart)
Re: Basic question about "closedir" <goldbb2@earthlink.net>
bus error - perl on solaris (static)
Re: Calling sub funcs with scalar variables? (Yves Orton)
Converting Perl to C <oleg_b@newmail.ru>
Re: Difference between .pl, .cgi, and .pm File Extensio (Villy Kruse)
Re: Difference between .pl, .cgi, and .pm File Extensio (Anno Siegel)
Re: File handle persistance across fork() ? <goldbb2@earthlink.net>
Re: GetOpt::Long error <goldbb2@earthlink.net>
Re: GetOpt::Long error (Rafael Garcia-Suarez)
Re: Help!:compile perl in win98? <kalinabears@hdc.com.au>
Re: how2make @MYARGV from my "cmd-line"? (Might have ST <brentdax1@earthlink.net>
Re: Is element in array <goldbb2@earthlink.net>
Re: Is element in array (Yves Orton)
Re: Matching "bar" not preceded by "foo" nobull@mail.com
Re: MultiThread with fork? <goldbb2@earthlink.net>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: 30 Aug 2001 00:15:38 -0500
From: logan@cs.utexas.edu (Logan Shaw)
Subject: Re: a perl module dedicated to lists ?
Message-Id: <9mki5q$nqq$1@charity.cs.utexas.edu>
In article <B7B25E36-3863D@193.248.252.79>,
Francis Derive <Francis.Derive@wanadoo.fr> wrote:
>
>sub member {
> my ($item, $ref_liste) = @_;
> local @liste = @$ref_liste;
>
> if (@liste == ()) {
> 0;
> }else {
> my $car = shift @liste;
> if ($item eq $car) {
> unshift @liste, ($item) ;
> @liste;
> }else{
> Listes::member($item, \@liste); #Listes, my Lists Perl package
> }
> }
>}
You've used "local". I'm pretty sure you don't want to do that, since
that does dynamic scoping instead of lexical scoping (as with "my").
That is probably the source of your bug, although I haven't looked at
it carefully enough to know for sure.
Also, your expression "@liste == ()" may not do what you think it
does. It converts both lists to scalar values. When a list is
converted to a scalar, the scalar value is the length of the list. So
your expression is comparing the length of @liste to the length of an
empty list. In fact, "@liste == ()" is equivalent to "not @liste" or
"@liste == 0".
A shorter recursive version:
sub member
{
my ($item, @list) = @_;
return 0 if not @list;
return 1 if $list[0] eq $item;
return member ($item, @list[1..$#list]);
}
Notice how I have assigned the list "@_" to the list "($item, @list)".
The left side consists of a scalar and a list. The result is that the
first element of the list on the right side is assigned to the scalar,
and the remaining ones are assigned to the list.
If you don't like return()ing from the middle of a function, you can
write a more functional version:
sub member
{
my ($item, @list) = @_;
@list
? $list[0] eq $item
? 1
: member ($item, @list[1..$#list])
: 0;
}
That copies the list like crazy, which is of course inefficient. If
you can accept passing a list ref as an argument, you can make it much
more efficient since shift() is O(1):
sub member
{
my ($item, $listref) = @_;
@$listref
? $item eq shift @$listref
? 1
: member ($item, $listref)
: 0;
}
I admit, it's kind of ugly to shift the array while testing its first
element!
Personally, I would solve this problem iteratively:
sub member
{
my ($item, @list) = @_;
foreach my $i (@list)
{
return 1 if $i eq $item;
}
return 0;
}
>However, is it possible to go further in life without using recursion ?
Rest assured, you definitely can use recursion in Perl. Just avoid
"local" unless you are absolutely sure that you need it.
>For example, an element of the list could be a list itself - making it a
>tree -where I would want to search for the $item again.
That's easy enough to solve. Just do this:
sub recursive_member
{
my ($item, @list) = @_;
foreach my $i (@list)
{
# is the element a reference to another list?
if (ref($i) eq 'ARRAY')
{
return 1 if recursive_member ($item, @$i);
}
else
{
return 1 if $i eq $item;
}
}
return 0;
}
A (more efficient) version that uses a list references instead of
lists:
sub recursive_member
{
my ($item, $listref) = @_;
foreach my $i (@$listref)
{
# is the element another list reference?
if (ref($i) eq 'ARRAY')
{
return 1 if recursive_member ($item, $i);
}
else
{
return 1 if $i eq $item;
}
}
}
Hope that helps.
- Logan
--
"Our grandkids love that we get Roadrunner and digital cable."
(Advertisement for Time Warner cable TV and internet access, July 2001)
------------------------------
Date: Thu, 30 Aug 2001 01:58:14 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: A Question about reference lifetimes
Message-Id: <3B8DD5F6.651B2C41@earthlink.net>
Stan Brown wrote:
>
> I'm going to need to spawn a child task with FileHandle->open, and
> have it do a lengthy DBI query (thus allowing perlTK to continue
> updating the screen).
>
> Beacause of the ammount of data potentialy returned by this select, I
> need to use one of the DBI calls that returns a refernce to the
> returned data.
>
> The child task will exit at the end of the select, but I need to be
> able to access the data untill the parent exits.
>
> Will this be OK? I'm concrend about cleanup on the exit of the child
> destroying the refeenced data.
>
> If this is a problem, is there some way to work around this?
The only problem I see here is that you apparently think that you can
have the child store the results of the fetch in a variable, and have
the parent read that variable. Unfortunatly for you, processes are
generally not threads, and this doesn't work. You need to find a way to
send the data from the child to the parent. The parent ends up with a
copy of it, and so it doesn't matter what happens to the child's data
after the parent gets it.
I've written a module specifically for creating a child process, having
that child do a DBI query, and send the data back to the parent. If you
like, I could send it to you.
I should point out though, it doesn't work quite yet, and I haven't been
able to figure out why not.
When it does work though, you should be able to do:
my $daemon = DBI::Daemon->new;
$daemon->connect("dbi:dbtype:dbname", $user, $pass);
$daemon->prepare("select field,field from table");
$daemon->execute();
my $fd = $daemon->getfd();
$tk_main_window->filevent( $fd, "readable", sub {
my $onerow = $daemon->fetch();
if( !$onerow ) {
print "Done with fetching\n";
$tk_main_window->filevent( $fd, "readable", "" );
return;
}
print "Got row [@$onerow]\n";
} );
--
"I think not," said Descartes, and promptly disappeared.
------------------------------
Date: Thu, 30 Aug 2001 04:03:18 GMT
From: d-lewart@uiuc.edu (Daniel S. Lewart)
Subject: ANNOUNCE: Champaign-Urbana Perl Mongers meeting Tue Sep 4
Message-Id: <aWij7.3196$oG.31479@vixen.cso.uiuc.edu>
Our September meeting will be:
Tue Sep 4 18:00 CDT 2001
Papa Del's
206 E Green St
Champaign, IL
Bob Price has much to tell about his recent travels to San Diego to
attend the O'Reilly Open Source Convention / Perl Conference 5!
We will be in the non-smoking area.
Benevolently,
Daniel Lewart
http://cmi.pm.org/
------------------------------
Date: Thu, 30 Aug 2001 05:43:14 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: Basic question about "closedir"
Message-Id: <3B8E0AB2.261CC646@earthlink.net>
Eli Bendersky wrote:
>
> > Ideally you will have done
> >
> > opendir(INX, 'some dir') || die("Can't opendir(some dir): $!");
> >
> > Hence by the time you hit closedir, you _know_ opendir worked...
> >
> > So a simple closedir(INX) is all that is needed.
>
> Yeah, I realize that... but still I have a situation where
> I don't really know if the directory was opened (because
> I open several directories on each iteration of a loop,
> and opening some depends upon successful opening
> of the ones preceding them).
In that case, you should be closing them after they're used, possibly by
providing some scope limits to the globs.
Simply replace all calls of the form:
opendir( FOO, ... ) or die ...
with:
opendir( local(*FOO), ... ) or die ...
Then you won't have to explicitly close any of the handles except the
one at top level scope, and possibly not even that one.
--
"I think not," said Descartes, and promptly disappeared.
------------------------------
Date: 29 Aug 2001 22:05:46 -0700
From: static_maelstrom@yahoo.com (static)
Subject: bus error - perl on solaris
Message-Id: <4bfe7db6.0108292105.6118e914@posting.google.com>
Hi,
I have a server program written in C that calls a perl script on
solaris running perl 5.6.
I have 2 accounts set up
foo:x:102:100:Test Foo User:/export/home/foo:/bin/ksh
bar:x:100:100:Test Bar User:/export/home/bar:/bin/ksh
My perl script is
-rwxrwxr-x 1 bar bar 1101 Aug 29 22:36 script.pl
My server program is
-rwx--x--x 1 bar bar 47650 Aug 1 12:49 masterblaster
If I telnet to the sun box and log in as 'bar' and halt/run the server
program, the perl script gets started just fine.
If I telnet to the sun box and log in as 'foo' and do the halt/run, I
get a bus error.
The BEGIN portion is fine, I get the bus error in the script. This
script can be as simple as calling a module and using the Net::FTP
module in that module and I will get a bus error. The programs work
fine on HP, AIX, LINUX and NT.
I originally thought that the problem was due to sun's using your real
id instead of your effective id. However, I have everything
executable to other in the perl tree and on my programs including the
paths to them.
There are some other post of people getting the bus errors with DBI
which is probably related since I can do a use on some modules and get
a bus error.
My server program will call 'perl -U script.pl'.
Here's some of that weirdness only specific to sun platforms
----------------------
BEGIN
{
print "BEGIN: in here\n";
$subdir = "whatever/place";
unshift(@INC,$subdir);
}
use Net::FTP;
use Cwd;
----------------------
$ perl -U script.pl
BEGIN: in here
Bus Error
If I remove the last 2 lines in the BEGIN block, it runs fine.
The unshift is adding the path to the array. The permissions on
whatever/place
are wide open.
The perl compile and make test all went with no errors.
Any input will be appreciated.
static
------------------------------
Date: 30 Aug 2001 02:27:25 -0700
From: demerphq@hotmail.com (Yves Orton)
Subject: Re: Calling sub funcs with scalar variables?
Message-Id: <74f348f7.0108300127.2d4e981f@posting.google.com>
tadmc@augustmail.com (Tad McClellan) wrote in message news:<slrn9or6di.5ak.tadmc@tadmc26.august.net>...
> GunneR <ds@ss.com> wrote:
> >I want the following to execute a sub function:
> >
> >&"$func"; ## Of course this doesnt work... its just to give you an
> >idea.
> >
> >Ive tried &($func); &{$func} and the like but no go. Im sure theres a
> ^^^^^^^^
>
> That one works fine for me (after turning strict off).
>
> What you are asking for is called "Symbolic references". They are bad:
>
> http://www.plover.com/~mjd/perl/varvarname.html
> http://www.plover.com/~mjd/perl/varvarname2.html
> http://www.plover.com/~mjd/perl/varvarname3.html
Well. Im not going to argue they arent a good idea, and shouldn't be
used in general but really 'They are bad' is a little to absolute and
simple for me.
> so I am not going to help you use them. I will instead offer
> an alternative where you won't need them, a dispatch table:
>
> my %subs = (
> mysub1 => \&mysub1,
> mysub2 => \&mysub2,
> );
>
> my $func = 'mysub2';
>
> $subs{$func}->(); # call mysub2()
Im not sure why this is better than using a symbolic reference. Is it
becuase you are restricted as to which subs you can call? I suppose I
would buy this.
Anyway, the reason I am posting is cause it seems to me that using OO
would be a better way to do this.
my $method='new';
my $obj=Foo::Bar->$method();
Generally when I have situations where I need to do this kind of thing
I use OO.
Yves
------------------------------
Date: Thu, 30 Aug 2001 13:57:31 +0400
From: "Oleg Bogumirsky" <oleg_b@newmail.ru>
Subject: Converting Perl to C
Message-Id: <9ml2mg$nt5$1@news.wplus.spb.ru>
Hello ALL,
Could anybody help me to get C source for my perl program, i mean to convert
Perl source to C/C++ source, so I could compile this C source with c
compiler.
Thanks
Oleg
------------------------------
Date: 30 Aug 2001 07:07:47 GMT
From: vek@pharmnl.ohout.pharmapartners.nl (Villy Kruse)
Subject: Re: Difference between .pl, .cgi, and .pm File Extensions.
Message-Id: <slrn9orpi2.rq6.vek@pharmnl.ohout.pharmapartners.nl>
On Wed, 29 Aug 2001 19:12:10 -0700,
Bob Holden <bob@eawf.nospam.com> wrote:
>On Tue, 28 Aug 2001 23:35:23 -0700, Bob Holden <bob@eawf.nospam.com>
>wrote:
>
>>I'm new to Perl, and trying to figure this all out. What I can't find
>>clear references to in all the books I've purchased and info I've
>>downloaded is:
>>
>>What's the difference between a .pl, .cgi, and a .pm file, and why
>>would you use one over another?
>>
>>TIA
>
>Thanks to all for your replies...you clarified it somewhat. However,
>now that leads into another question about .pm files. If I look at
>the instructions for, say, CGI.pm, it says I need to install it onto
>my server.
>If that's the case, then there's something different about .pm files,
>but what you all have stated, there's really no difference between .pl
>and .pm files. I'm confused.
>
When you say "use CGI" the perl compiler is looking for a file
named CGI.pm in the designated perl module directories. You can't
"use" a file with any other extension, although you can "require" one.
see perldoc -f use and perldoc -f require.
Villy
------------------------------
Date: 30 Aug 2001 09:51:09 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Difference between .pl, .cgi, and .pm File Extensions.
Message-Id: <9ml2ad$3t2$1@mamenchi.zrz.TU-Berlin.DE>
According to Alan J. Flavell <flavell@mail.cern.ch>:
> On Aug 29, brian d foy inscribed on the eternal scroll:
>
> (re. use of .pl as a filename 'extension'):
>
> > perl *library*. some people frown on using this (or any)
> > extension for scripts. sometimes you'll see .plx (perl
> > executable) since some operating systems jsut can't do
> > without.
>
> Well, since the canonical building procedure starts with
>
> perl Makefile.PL
>
> it would seem that someone "in authority" thinks that Perl scripts
> have a filename extension of .PL (upper case).
I believe this assumes more deliberation than actually went into the
naming of that file. Before MakeMaker, module authors packed their
own Makefile with a product. This led to subtle and not-so-subtle
differences in the make process for each module.
As a remedy, Andreas Koenig wrote MakeMaker. To make it clear that
you (the module author) were now supposed to replace your former
Makefile with an equivalent template for MakeMaker, and as an indication
to you (the module installer) that you were supposed to run it as a
Perl program, the standard name for the template became Makefile.PL,
using the established .pl suffix for a Perl program. Why upper-case,
I do not know.
I am Cc'ing this to Andreas (Hi!) so he can comment if he feels like it.
Anno
------------------------------
Date: Thu, 30 Aug 2001 05:36:58 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: File handle persistance across fork() ?
Message-Id: <3B8E093A.A5E0D455@earthlink.net>
Villy Kruse wrote:
>
> On Tue, 21 Aug 2001 11:13:03 +0100,
> Paul Johnston <paul.johnston@dsvr.co.uk> wrote:
>
> >
> >I think you're code's fine. Should point out that I've found flock on
> >Linux doesn't work properly of file handles that have been forked.
> >I've found I can simultaneously get an exclusive lock in each process
> >on a file handle created before a fork. Presumably this
> >problem/behaviour exists on other OSs.
> >
>
> Linux systems have two locking methods: flock and fcntl. fcntl locks
> are tied to the pid and will therefore not be inherited by child
> processes, whereas the flock lock is tied to the opened file
> descriptor which are inherited by the child process. It then depends
Shouldn't the child get a *copy* of it's parent's file table, so that
even though the opened file descriptor is inherited, it becomes an entry
in a *different table* ?
> on which system call is used to implement the perl flock command, how
> this works across forks.
>
> You could use strace to find out.
>
> Also note that with file locking based on fcntl you could
> inadvertently unlock the file if you open the same file for a second
> time in the same process and then close it.
Doesn't that also imply that if I open a file twice [getting two
filehandles to it], use fcntl to lock one, then both are effectively
locked? Yuck. This might not sound bad, but if I've got a bunch of
threads, and I want to communicate via pipes [which will magically
buffer data for me], and have the parent thread dump all the jobs it
wants the kiddies to do into one end, then have the child threads each
lock, read one job, then unlock, I've got a problem. [Yes, one could do
it with semaphores, but locking is easier, *especially* if the code may
eventually get changed to use processes instead of threads].
--
"I think not," said Descartes, and promptly disappeared.
------------------------------
Date: Thu, 30 Aug 2001 04:42:49 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: GetOpt::Long error
Message-Id: <3B8DFC89.D7C3C426@earthlink.net>
Joseph wrote:
>
> I am getting an odd error when I try to use GetOpt::Long. Here is a
> code snippet:
> #
> # Standard includes
> #
>
> use strict;
> use diagnostics;
> use GetOpt::Long;
[snip]
As others have said, the problem stems from the fact that the module is
named Getopt::Long, not GetOpt::Long, and you have the wrong name in the
'use' statement. However, neither of the other two responses said the
real reason WHY this causes problems. In most modules, it doesn't. So
why is it a problem here?
Part of the reason is that when you "use" something, it creates an entry
in %INC, which shows where a particular module was loaded from -- with
the item from the "use" line as the hash key [well actually, with "::"
replaced with "/" and a ".pm" added, but that doesn't matter].
Getopt::Long uses AutoLoader, whose AUTOLOAD sub looks at %INC to find
out what directory the autoloaded subroutines should be loaded from.
When you want Getopt::Long::GetOptions(), it calls the AUTOLOAD sub with
the $AUTOLOAD variable set to "Getopt::Long::GetOptions", and then
splits off the package from the subname, then looks for "Getopt/Long.pm"
as a hash key in %INC. But there isn't one; there's a "GetOpt/Long.pm",
but it doesn't see that, and doesn't care, since it considers that a
different module.
IMHO, doing a 'use' or 'require' with the wrong case should cause a
warning. The problem of course is it's a bit hard to detect... you
would need to open the directory containing the file, search through the
list for an item which matches [case insensitively] the "use" line, and
then warn if it doesn't match [case sensitively]. Blech.
--
"I think not," said Descartes, and promptly disappeared.
------------------------------
Date: 30 Aug 2001 09:30:05 GMT
From: rgarciasuarez@free.fr (Rafael Garcia-Suarez)
Subject: Re: GetOpt::Long error
Message-Id: <slrn9os27l.lpf.rgarciasuarez@rafael.kazibao.net>
Benjamin Goldberg wrote in comp.lang.perl.misc:
}
} IMHO, doing a 'use' or 'require' with the wrong case should cause a
} warning. The problem of course is it's a bit hard to detect... you
} would need to open the directory containing the file, search through the
} list for an item which matches [case insensitively] the "use" line, and
} then warn if it doesn't match [case sensitively]. Blech.
The next release of perl (5.8) will (probably) include this warning.
Example, using a very recent build öf the current devel version :
$ echo 'package Foo; 1;' > foo.pm
$ bleadperl -w -Mfoo -e1
Package `foo' not found (did you use the incorrect case?).
However this is not implemented as you said ; this only compares the
file name and the package(s) namespaces created by loading this file.
--
Rafael Garcia-Suarez / http://rgarciasuarez.free.fr/
perl -sleprint -- -_='Just another Perl hacker,'
------------------------------
Date: Thu, 30 Aug 2001 16:09:12 +1000
From: "Sisyphus" <kalinabears@hdc.com.au>
Subject: Re: Help!:compile perl in win98?
Message-Id: <999187994.834154@clover.origin.net.au>
"MMX166+2.1G HD" <no@mail.addr> wrote in message
news:8qvqot4dlbgocuft96kqctnjh6gvtr24sh@4ax.com...
> AP629.TAR.GZ, download form
> http://downloads.activestate.com/ActivePerl/src/5.6/AP629_source.tgz
>
> for the Thread module, I was going to compile perl by myself in
> win98.the C compiler is VC5, and everything was ok until the nmake
> started to link perldll.def. it said many external symbol were
> unsolved. though the libs whom defined these symbol were specified
> correctly. I couldn't solve it. and there wasn't any mistake I could
> find, except the Configure.com, which can't be executed. it said "not
> enough memory" though I have 80M. but I think this is not the key.
>
> have anyone compiled perl successfully in win98? could u help me?
It's a battle !!
I had a go (using both command.com and cmd.exe as the shell), and failed. It
has been done using Borland and dmake ( according to reports I've seen
somewhere ) but I know of only one person who has achieved this with VC++ on
Win 9x.
And that was done using a 4NT shell - which, I think, is available on a 30
day trial, then must be purchased. See:
http://www.jpsoft.com/4ntdes.htm
Here is that person's account of what needed to be done:
---------start
Ingridients for good perl compilation are:
[tested on old 5.00503 version]
Windows 95
ActiveState Perl build 522 source
Visual Studio 97 (Visual C++ 5, without SP3) *
4NT Shell
notepad to change some of the files:)
Attached diff (I have to made those differences, just for compilation
pass)
-First, install 4NT.
this involves adding it to the PATH environment variable, and setting
PERL5SHELL to 4nt /c
-unpack source
-apply patches, but you'll have to edit the one for makefile to
reflect your system...
-Follow the instructions in readme.win32
-wait, wait, wait...
-and that's it
* VC++ is without SP3. Micosoft fault. They have two kinds of SP, CORE
(40MB) and FULL (97MB). I've downloaded CORE, and it broke my
installation, because it doesn't have all things needed to successfully
update VC++. And I'm not in the mood to download 97MB @14400, just to
use 10MB of it all...
4NT is very, very good shell, and without it, nothing would
pass...
command.com is retarded shell, and many things won't pass. I first tried
with 4DOS, but it doesn't understand things like 2>&1, so I have to move
to 4NT. [I've asked JP SOFT to include that feature in next version...]
The source is full (makefile, and modules) are full of things such is
2>&1, assuming cmd shell. That's OK, because 4NT understands it. But,
some of the tests have call to system, with explicit call to cmd, thus
they fail...
In the background, perl is now installing, documentation - to be
precise... And there are many errors, such as:
Use of uninitialased variable in ..\lib\Pod\Html.pm
but I think that they are irelevant...
------------ finish
( They *were* pretty much irrelevant - though I think there might have been
some problem with the installation of the html documentation. I don't know
what this person did in regards to threads.)
If you give me your email address I could send you the file containing the
patches.
Cheers,
Rob
------------------------------
Date: Thu, 30 Aug 2001 08:28:12 GMT
From: "Brent Dax" <brentdax1@earthlink.net>
Subject: Re: how2make @MYARGV from my "cmd-line"? (Might have STRINGS!)
Message-Id: <wOmj7.5930$aC1.540363@newsread1.prod.itd.earthlink.net>
"David Combs" <dkcombs@panix.com> wrote in message
news:9kdrb8$a4d$1@panix6.panix.com...
> pnews: perl: 'how2make @MYARGV from my "cmd-line"? (Might have STRINGS!)'
> How to "parse" something like this:
>
>
> (Note that any string must be enclosed in either single OR double
> quotes.)
>
>
> format (in square-brackets: optional):
> fruit-name [num-in-a-batch] description [asof-date] price
>
> Texas-grapefruit "inside looks and tastes \"red\"." $0.50
> banana 6 "Look and taste \"yellow\"." 2aug01 $0.33
> apple 2 'Look and taste "red".' $0.33
>
>
> WITHOUT the quoted-strings, the above is (I think) *simple* to parse into
an
> @ARGV-like array: just do a split on whitespace.
>
> QUESTION: But how to do it when strings ARE allowed, and each is to be
seen
> as a (shell) "word"?
I assume you mean you call the program like "myprog data.file" and parse a
record format like that. If that isn't the case, the code here will
probably have to be modified; however, the basic techniques should stay the
same.
(Warning: all code is untested.)
Your basic structure will be something like:
while(<>) {
(read in data)
}
(do stuff with data)
I suggest using a regular expression to read each field, as the processing
you're looking for is probably too sophistocated for split. Are we to
assume that column 3 always is quoted somehow and the others never are? If
so, the regexp isn't too difficult, especially with the help of /x:
/^
(\S+) #fruit_name ($1)
\s+
(\d+|) #num_in_batch ($2)
\s+
(['"]) #temporary--internal to RE ($3)
(.*?) #description ($4)
(?<!\\) #last character not a backslash
\3
\s+
(\S+|) #asof_date
\s+
\$(\S+) #price
$/x;
If not, things get more interesting. You end up with a regular expession
where each field extraction is something like this:
(['"]?)
(.*?)
(?<!\\)
\1
except that \1 should go up by 2 for each field. In this case, the even
fields are the useful ones.
Note the use of a lookbehind in both cases to make sure the quotes haven't
been backslashed. This technique is not flawless--"\\" won't stop at the
right point--but it's simple and works in most cases. There have been huge
arguments about how to detect backslashed quotes--most people have an
opinion. This is my personal technique. By a strange coincidence, in the
second regular expression, this allows you to backslash spaces in unquoted
strings--"foo\ bar" (without the quotes) will parse as one block.
Further resources:
-There is an obscure entry in perlfaq about extracting delimited
entries.
-The Text::Balanced module (available from the CPAN) may also be of use,
especially if you want to support the full power of Perl quoting (with
things like q// and qq//).
I welcome constructive criticism on these regular expressions; however,
please send flames to /dev/null.
HTH,
--
Brent Dax
brentdax@cpan.org
"...and if the answers are inadequate, the pumpqueen will be overthrown in a
bloody coup by programmers flinging dead Java programs over the walls with a
trebuchet."
------------------------------
Date: Thu, 30 Aug 2001 05:11:03 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: Is element in array
Message-Id: <3B8E0327.F2F5082D@earthlink.net>
Joe Schaefer wrote:
>
> brian d foy <comdog@panix.com> writes:
>
> > In article <m3pu9fnfnv.fsf@mumonkan.sunstarsys.com>, Joe Schaefer
> > <joe+usenet@sunstarsys.com> wrote:
> >
> > [snip]
> >
> > > That passage sounds more like a bug report than anything else.
> > > IMO the only reason "grep" is in the language is to emulate the
> > > functionality of Unix's grep, which has an "-l" flag.
> >
> > grep is much more powerful that than though, and certainly doesn't
> > act like `grep -l`. if you think that, and only use simple
> > conditions in the grep block, then you are missing most of the fun.
>
> What I think is that "grep blah" is completely equivalent to
> "map blah ? $_ : ()", but I don't see any need to enforce this
> relationship in perl 6 as well. IMO the value of having the
> keyword "grep" is that it mimics the Unix conception of it, so
> IMO Perl's grep should be applicable to the same types of problems
> that the Unix version is (and more of course).
>
> For example, say I wanted to know whether a file contained
> a certain word. grep(1) (possibly with the "-q" or "-l" flag for
> really big files) seems natural for this. But if we shouldn't use
> Perl grep to solve the corresponding problem for Perl lists, that
> doesn't seem like much of a "power" improvement to me.
>
> Again, if we are supposed to discourage people from using Perl
> grep in situations like this, then I think there should be some
> compelling reason why. But despite the FAQ's verbiage, AFAICT
> there doesn't appear to be one.
>
> > > In a boolean context, I think it would be nice if perl6's grep
> > > would behave similarly.
> >
> > but then it wouldn't be grep. you can already use grep in a scalar
> > context to count the number of matches. if you want to search in
> > another fashion, a different function is in order :)
> ^^^^^^^^^^^^^^^^^^
>
> So is OP's question solved using a new method in Perl 6?
>
> Joe Schaefer
Sounds more like he's saying that whatever does solve it, if such a
thing is added to perl6, should have a different name than grep.
I suppose that either grep1 or grepl would be ok, or perhaps member or
index. [Yes, I know the name index already means something, but since
you can have two builtins with the same name differing only by their
prototypes [like the 1 and 4 argument versions of select], I don't see a
problem with using it here].
Here's a silly question: Wouldn't it make more sense to have index
return than undef for failure [and return "0E0" for when the index
succeeds but is 0], than the current behavior of returning $[ - 1 for
failure? Wouldn't this be more useful?
Obviously we can't change it now because it would break code, but
perhaps in perl6...
Actually, I think that since perl6 has that "is" modifyer, so you can
say "return 0 is true", this won't be such a concern. Ooh, and I can
finally think of a use for using "is false" ... by having perl6's
index() use "return -1 is false" for failure, it will help perl5 code
which uses index to be brought over with fewer changes.
How do I make a perl6 rfc?
--
"I think not," said Descartes, and promptly disappeared.
------------------------------
Date: 30 Aug 2001 02:39:01 -0700
From: demerphq@hotmail.com (Yves Orton)
Subject: Re: Is element in array
Message-Id: <74f348f7.0108300139.24d6b2a@posting.google.com>
Tassilo.Parseval@post.rwth-aachen.de (Tassilo v. Parseval) wrote in message news:<9lnvbh$16u$1@nets3.rz.RWTH-Aachen.DE>...
> On Sun, 19 Aug 2001 11:17:16 +0200, Guy <guymal@__NOSPAM__hotmail.com> wrote:
> > How can test a scalar to see if it is an element in a given array?
> > Example:
> > @bla=("one","two","three");
>
> You could always iterate over the array:
>
> my $in_array;
> for my $item (@bla) {
> if ($item eq 'two') {
> $in_array++;
> last;
> }
> }
> if ($in_array) { ... }
sub sequential_search {
my ($array_ref,$value);
$_ eq $value && return $value
foreach @$array_ref;
return
}
> Or you could create a hash where you fill in the array-elements as a
> key. Yet, this always loops over the whole array which only makes sense
> if you often test for a value being in the array. Thus, you would only
> create the %seen-hash once and each time you test for a value you simply
> check whether $seen{key} exists.
>
> my %seen;
> $seen{$_}++ for (@bla);
> if (exists $seen{two}) { ... }
Yes this is much faster.
> In case you are lazy you could also use grep:
>
> if (grep {$_ eq 'two} @bla) { print "Yes, it is there" }
>
> But again, this always iterates over the whole array which makes it sort
> of slow.
You know, I have never used grep in a solution. Everytime I try it I
end up needing to transform the ouput and have to change it to a map.
Yves
------------------------------
Date: 30 Aug 2001 08:38:16 +0100
From: nobull@mail.com
Subject: Re: Matching "bar" not preceded by "foo"
Message-Id: <u9ofoyug9w.fsf@wcl-l.bham.ac.uk>
Benjamin Goldberg <goldbb2@earthlink.net> writes:
> /bar/ && $` !~ /foo/
perlvar gives dire warnings aginst using $`. I'm not sure if these
warnings still apply in 5.6 but on the assumption that they do change
the above to:
/(.*)bar/ && $1 !~ /foo/
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
------------------------------
Date: Thu, 30 Aug 2001 01:40:30 -0400
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: MultiThread with fork?
Message-Id: <3B8DD1CE.F280CE02@earthlink.net>
MMX166+2.1G HD wrote:
>
> my perl, v5.6.1 built for MSWin32-x86-multi-thread, does not support
> Thread. and someone told me to use fork instead. but I've never used
> fork before, how can I use it to do multi-task works? for example, I
> want to download a huge file in several "threads". each of them
> downloads a part of the file. I tried this code:
> >$fid=$$;
> >for ($i=0;$i<3 ;$i++) {
> > fork;
> > if ($$!=$fid) {
> > dosome();
> > exit;
> > }
> >}
> but, it creates and executes these three processes one by one, that
> is, creates one and wait for it returns, and creates the next, just
> like
> >for ($i=0;$i<3 ;$i++) {
> > dosome();
> >}
> obviously it is not like multi-thread. how can I do without the Thread
> module?
Actually, the code you have here *should* work... probably. Replace
your fork() call with
defined(fork()) or die "Couldn't fork: $!";
and tell us a bit more about how dosome() works. For example, if,
outside of the loop, you open a single network connection to a server,
then inside the loop, you try and download all those parts using that
single connection... well, it's not going to work. You have to make
sure that each thread gets it's own network connection -- probably by
creating the connections inside the loop, after the fork() call.
Also, you have to make sure that after the processes are done, their
data is processed/outputted in the correct order.
Also keep in mind that threads created via fork() are designed to
simulate processes... a child thread can't access it's parent's
variables so collecting the data from the children and putting it in
order can be a bit awkward. Usually pipes are used for IPC, but in this
case, downloading a file, you could open a file before the fork() loop,
have each thread seek() to the appropriate position in the file, and
write the data it's gotten there.
Eg:
use LWP::UserAgent;
use LWP::Simple;
my ($type, $size, $age) = head($url) or die ...;
die "Couldn't get size of $url" unless $size;
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => $url);
open( local(*FILE), "<+", $file ) or die ...;
binmode(FILE);
my @kids;
my $nkids = 3;
for( 1 .. $nkids ) {
defined(my $pid = fork) or die ...;
if( $pid ) {
push @kids, $pid;
next;
}
my $start = int( $_ * $size / $nkids );
my $end = int( ($_ + 1) * $size / $nkids - 1 );
exit if $start == $end; # if $nkids is larger than $size
$req->header( Range => "bytes=$start-$end" );
my $resp = $ua->request($req);
$resp->code() == 206 or die ...;
seek( FILE, $start, 0 ) or die ...;
print FILe $resp->content;
exit;
}
waitpid $_ or die ... foreach( @pid );
seek FILE, 0, 0;
print while <FILE>;
--
"I think not," said Descartes, and promptly disappeared.
------------------------------
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 1653
***************************************