[10849] in Perl-Users-Digest
Perl-Users Digest, Issue: 4450 Volume: 8
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Dec 17 23:07:50 1998
Date: Thu, 17 Dec 98 20:00:16 -0800
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Thu, 17 Dec 1998 Volume: 8 Number: 4450
Today's topics:
Re: $&, $', and $` and parens.... (Larry Rosler)
Re: Anyone have a workaround for crippled ActiveState p hutchiss@my-dejanews.com
Re: bug? <jas@pdc.kth.se>
constructors and object methods <rakesh_puthalath@hotmail.com>
Re: constructors and object methods (Mark-Jason Dominus)
Re: how can I create my html file elsewhere than in the imchat@ionet.net
How to "clear" a namespace? <bradfitz@bradfitz.com>
Re: How to "clear" a namespace? <tchrist@mox.perl.com>
Re: Intentionally causing a trap/dump/GPF? (David Formosa)
Passing Multiple Arrays (Jacque Weddle)
Re: Passing Multiple Arrays (Mark-Jason Dominus)
Re: PERL & IIS internals <kprice@cardinal.co.nz>
Re: problem naming a directory with a number (Martien Verbruggen)
Re: problem naming a directory with a number <egwong@netcom.com>
Re: Reference Troubles (Mark-Jason Dominus)
Re: Search Not Working <due@murray.fordham.edu>
Re: Search Not Working (Larry Rosler)
Re: Syntax Error...Not able to find. (Mark-Jason Dominus)
Re: telnet by perl (Lee Lindley)
Special: Digest Administrivia (Last modified: 12 Dec 98 (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Thu, 17 Dec 1998 16:48:37 -0800
From: lr@hpl.hp.com (Larry Rosler)
Subject: Re: $&, $', and $` and parens....
Message-Id: <MPG.10e3463c25cc4ea29898d7@nntp.hpl.hp.com>
[Posted to comp.lang.perl.misc and a copy mailed.]
In article <75c5b8$59r$1@mathserv.mps.ohio-state.edu> on 17 Dec 1998
23:50:00 GMT, Ilya Zakharevich <ilya@math.ohio-state.edu> says...
> [A complimentary Cc of this posting was sent to Larry Rosler
> <lr@hpl.hp.com>],
> who wrote in article <MPG.10e31d08458e2d059898d6@nntp.hpl.hp.com>:
> > Yes. You *never* need to use $`, $&, $'.
> >
> > my ($pre_match, $match, $post_match) = /(.*)(...whatever...)(.*)/s;
>
> I would make it
>
> m/\A(.*?)(...whatever...)(.*)/s;
^^ ^
\A -- Isn't the anchor-to-start implicit, just as the anchor-to-end is?
(.*?) -- Yes, to preserve the semantics of 'first match' instead of
'last match'. But I was concerned about performance impacts. 'Greedy'
is faster if it preserves the semantics, yes?
> Still, it may disable many important optimizations.
More than using $` or $' does? I understand $& has been 'fixed' in
5.005, but is there any reason to use $& instead of parens around the
match?.
--
(Just Another Larry) Rosler
Hewlett-Packard Company
http://www.hpl.hp.com/personal/Larry_Rosler/
lr@hpl.hp.com
------------------------------
Date: Fri, 18 Dec 1998 01:46:55 GMT
From: hutchiss@my-dejanews.com
Subject: Re: Anyone have a workaround for crippled ActiveState perl -- fork()
Message-Id: <75cc6f$pvu$1@nnrp1.dejanews.com>
I've found a workaround which is despicable but functional,
that is, using Win32::Process::CreateProcess, and doing all
the I/O connections over again. Bleah.
However, I'm now running into a situation where I can't open
our old friend COM1 from the child process because the parent
already has it open. I'm just unbelievably happy to discover
that this is true. Maybe I'll find some other bit of useful
info about the obscure twiddle you have to do with bit 15 of
some random register in order to allow the two processes to
share this resource. Feh feh.
Hutch
In article <75brrb$bnc$1@nnrp1.dejanews.com>,
hutchiss@my-dejanews.com wrote:
> In the time-honored tradition of not re-inventing the wheel,
> I'm looking for hints or examples of ways to get around the
> gaping hole in Active State Perl...
>
> $main::whinge=1;
> Is there a reason why these guys didn't bother to implement
> a feature that NT supports and that even the 16-bit Windows
> API had ways to approximate?
> $main::whinge=0;
>
> I'm looking at different ways to do a fork equivalent. If I'm
> forced to use Tcl to do this part of things it will be high irony.
>
> I'm going to be using perlTk to do the GUI part of the project
> and it needs to be able to spawn off a number of different
> pieces that have to be able to run concurrently (this app can be
> run on Unix or NT) ... without the use of 'fork' I'm not sure
> just how I'll be able to do this.
>
> Hints? Pointers? Derisive laughter? Anything?
>
> -----------== Posted via Deja News, The Discussion Network ==----------
> http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
>
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
------------------------------
Date: 18 Dec 1998 01:49:02 +0100
From: Simon Josefsson <jas@pdc.kth.se>
Subject: Re: bug?
Message-Id: <ilun24m9sw1.fsf@fangblenny.pdc.kth.se>
Russ Allbery <rra@stanford.edu> writes:
> >> This works on Solaris, but not on IBM AIX 4.2. Is this a known bug?
>
> >> $ perl -e 'printf "%f", NaN;'
> >> panic: frexp at -e line 1.
> >> $ perl -v
>
> >> This is perl, version 5.004_04 built for aix
> >> ...
>
> > I suppose that it's a different implementation of sprintf in the
> > standard libraries of the compiler or the platform you used. Perl just
> > calls those.
>
> I believe that as of Perl 5.004, Perl includes its own sprintf and no
> longer calls the system library version. But I think your diagnosis is
> correct, just not the function you're blaming. This appears to be a
> problem with the string to floating-point conversion routine in the C
> library on that host.
Which routine in the C library, to be specific? If we can come up
with a testcase in C I could send a bug report to ibm.
Perhaps the `Gconvert' define macro could be tweaked? It is set to
gcvt currently, I'll change it to sprintf and re-compile and test.
-s
------------------------------
Date: Fri, 18 Dec 1998 10:33:04 +0800
From: Rakesh Puthalath <rakesh_puthalath@hotmail.com>
Subject: constructors and object methods
Message-Id: <3679BEDF.F9D9EC56@hotmail.com>
The below given code under execution, gives the follwoing error message
:
Can't use string ("Person") as a HASH ref while "strict refs" in use at
Person.p
m line 32.
The suspect the problem is because of the last line in the code.
$x = Person->get_name();
Why does strict compain now, although it works fine for a similar call
ie. after all both are object methods .
$he = Person->new();
Does strict differentiate constructors and object methods ?
Thanks
Rakesh
Code:
#!/usr/bin/perl -w
use Person;
$he = Person->new();
$he->set_name("John");
print $he->get_name() , "\n";
$x = Person->get_name();
-----------------------------------------
File : Person.pm
package Person;
use Carp;
use strict;
my $Persons = 0;
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
$self->{Name} = undef;
$self->{Age} = undef;
$self->{Sex} = undef;
$self->{Height} = undef;
$self->{Weight} = undef;
$self->{Persons} = \$Persons;
++${$self->{Persons}};
return bless($self, $class);
}
sub set_name{
my $self = shift;
croak "No name passed \n" unless @_ == 1;
$self->{Name} = shift;
}
sub get_name{
my $self = shift;
return defined($self->{Name}) ? $self->{Name} : "Unknown";
}
1;
------------------------------
Date: 17 Dec 1998 22:14:20 -0500
From: mjd@op.net (Mark-Jason Dominus)
Subject: Re: constructors and object methods
Message-Id: <75chac$r5j$1@monet.op.net>
In article <3679BEDF.F9D9EC56@hotmail.com>,
Rakesh Puthalath <rakesh_puthalath@hotmail.com> wrote:
>Can't use string ("Person") as a HASH ref while "strict refs" in use at
>Person.p
>m line 32.
>The suspect the problem is because of the last line in the code.
>$x = Person->get_name();
Person->get_name() is the Perl syntax for calling a class method. But
get_name is an object method, not a class method.
What is Person->get_name() suppsoed to mean? What object is it
supposed to return the name of? It doesn't make any sense, and so
`strict' has diagnosed a real error in your program.
>Why does strict compain now, although it works fine for a similar call
>ie. after all both are object methods .
>$he = Person->new();
`new' is also a class method; that's why Person->new() works.
>Does strict differentiate constructors and object methods ?
No. The complaint here is that you have asked for the ->{Name} member
of something that is not an object, because you have called `get_name'
as if it were a class method, and it is not a class method.
>sub get_name {
> my $self = shift;
> return defined($self->{Name}) ? $self->{Name} : "Unknown";
>}
------------------------------
Date: Fri, 18 Dec 1998 02:25:31 GMT
From: imchat@ionet.net
Subject: Re: how can I create my html file elsewhere than in the cgi-bin folder??
Message-Id: <3679bb06.1208169936@news.ionet.net>
I guess you want to generate the ski conditions pages instead
of the page that I modified, but the premise is the same. Just specify
the directory you want to save it to and then make sure it has the
needed permissions.
On Thu, 17 Dec 1998 09:23:56 -0500, "Alexandre Hamel"
<ahamel@intrawest.com> wrote:
>I've tryied many ways but without success... :( here's my code )
>
>#!/usr/perl
>push(@INC, "/cgi-bin");
>require ("cgi-lib.pl");
$datadir = '/path_to_directory/data';
>
># Script Perl
># Updates des conditions de neige
># Auteur : Alexandre Hamel, lundi, 14 dic. 1998
open(DATA,">$datadir/$name.html") || die $!;
>
>print DATA "Content-type: text/html\n\n";
>
>print DATA "<HTML><HEAD><TITLE>test updates</TITLE></HEAD>\n";
>print DATA "<BODY bgcolor=#FFFFFF>\n";
>print DATA "<CENTER>\n";
>
>
>@my_query_string = split(/&/,$ENV{'QUERY_STRING'});
>my %conditions;
>
>foreach $index (0..$#my_query_string)
>{
> ($key, $val) = split(/=/, $my_query_string[$index],2);
> $conditions{$key} = $val;
>}
>
>
>print DATA "</BODY></HTML>\n";
close(DATA);
>
>#
># Criation du fichier newcondf.htm francais
>#
>
>open (CONDF, ">newcondf.htm")
> or die "Problhme lors de la criation du fichier!";
>printf CONDF "<HTML><HEAD><TITLE>Conditions de neige</TITLE></HEAD>";
>printf CONDF "<BODY bgcolor=#FFFFFF>";
>printf CONDF "<CENTER>";
>printf CONDF "<FONT SIZE=6 COLOR=#99003><B>Conditions de
>neige</B></FONT><BR>";
>printf CONDF "$conditions{'jour'}, le $conditions{'date'}
>$conditions{'mois'} $conditions{'annee'} a
>$conditions{'hour'}:$conditions{'minute'}$conditions{'ampm'}";
>printf CONDF "</center>";
>printf CONDF "<table border=1 width=400 align=center CELLPADDING=3
>CELLSPACING=0>";
>printf CONDF "<tr><td bgcolor='#0066cc'>";
>printf CONDF "<b><center>Accumulation de neige</center></b>";
>printf CONDF "</td></tr>";
>printf CONDF "<tr><td bgcolor='#0099cc'>";
>printf CONDF "<ul>";
>printf CONDF "<li>Dernier 24 heures : $conditions{'24hrs'} cm.<br>";
>printf CONDF "<li>Dernihre semaine : $conditions{'lastweek'} cm.<br>";
>printf CONDF "<li>Dibut de la saison : $conditions{'season'} cm.<br>";
>printf CONDF "</ul>";
>printf CONDF "</td></tr>";
>printf CONDF "<br>";
>printf CONDF "<tr><td bgcolor='#0066cc'>";
>printf CONDF "<b><center>Tempiratures</center></b>";
>printf CONDF "</td></tr>";
>printf CONDF "<tr><td bgcolor='#0099cc'>";
>printf CONDF "<ul>";
>printf CONDF "<li>Tempirature au sommet : $conditions{'wsummit'}
>celcius.<br>";
>printf CONDF "<li>Vitesse des vents : $conditions{'wind'} km/h.<br>";
>printf CONDF "</ul>";
>printf CONDF "</td></tr>";
>printf CONDF "<tr><td bgcolor='#0066cc'>";
>printf CONDF "<b><center>Information sur la station</center></b>";
>printf CONDF "</td></tr>";
>printf CONDF "<tr><td bgcolor='#0099cc'>";
>printf CONDF "<ul>";
>printf CONDF "<li>Longueur des pistes : $conditions{'pistes'} km.<br>";
>printf CONDF "<li>Heure d'ouverture : $conditions{'open'}h AM.<br>";
>printf CONDF "<li>Nombre de remonties : $conditions{'remontees'}<br>";
>printf CONDF "</ul>";
>printf CONDF "</td></tr>";
>printf CONDF "</table>";
>printf CONDF "</BODY></HTML>";
>close ( CONDF );
>
>#
># Criation du fichier newconde.htm anglais
>#
>
>open (CONDE, ">newconde.htm")
> or die "Problhme lors de la criation du fichier!";
>printf CONDE "<HTML><HEAD><TITLE>Snow conditions</TITLE></HEAD>";
>printf CONDE "<BODY bgcolor=#FFFFFF>";
>printf CONDE "<CENTER>";
>printf CONDE "<FONT SIZE=6 COLOR=#99003><B>Snow conditions</B></FONT><BR>";
>printf CONDE "$conditions{'day'}, $conditions{'month'}
>$conditions{'date'}<sup>th</sup> $conditions{'annee'},
>$conditions{'hour'}:$conditions{'minute'}$conditions{'ampm'}";
>printf CONDE "</center>";
>printf CONDE "<table border=1 width=400 align=center CELLPADDING=3
>CELLSPACING=0>";
>printf CONDE "<tr><td bgcolor='#0066cc'>";
>printf CONDE "<b><center>Snow Accumulation</center></b>";
>printf CONDE "</td></tr>";
>printf CONDE "<tr><td bgcolor='#0099cc'>";
>printf CONDE "<ul>";
>printf CONDE "<li>Last 24 hours : $conditions{'24hrs'} cm.<br>";
>printf CONDE "<li>In the last week : $conditions{'lastweek'} cm.<br>";
>printf CONDE "<li>Since season's beginning : $conditions{'season'} cm.<br>";
>printf CONDE "</ul>";
>printf CONDE "</td></tr>";
>printf CONDE "<br>";
>printf CONDE "<tr><td bgcolor='#0066cc'>";
>printf CONDE "<b><center>Temperatures</center></b>";
>printf CONDE "</td></tr>";
>printf CONDE "<tr><td bgcolor='#0099cc'>";
>printf CONDE "<ul>";
>printf CONDE "<li>Temperature at the summit : $conditions{'wsummit'}
>celcius.<br>";
>printf CONDE "<li>Wind speed : $conditions{'wind'} km/h.<br>";
>printf CONDE "</ul>";
>printf CONDE "</td></tr>";
>printf CONDE "<tr><td bgcolor='#0066cc'>";
>printf CONDE "<b><center>Resort information</center></b>";
>printf CONDE "</td></tr>";
>printf CONDE "<tr><td bgcolor='#0099cc'>";
>printf CONDE "<ul>";
>printf CONDE "<li>Longest run : $conditions{'pistes'} km.<br>";
>printf CONDE "<li>Opening time : $conditions{'open'}h AM.<br>";
>printf CONDE "<li>Number of lifts : $conditions{'remontees'}<br>";
>printf CONDE "</ul>";
>printf CONDE "</td></tr>";
>printf CONDE "</table>";
>printf CONDE "</BODY></HTML>";
>close ( CONDE );
>
>
>
>
------------------------------
Date: Thu, 17 Dec 1998 17:20:38 -0800
From: Brad Fitzpatrick <bradfitz@bradfitz.com>
Subject: How to "clear" a namespace?
Message-Id: <Pine.A41.4.05.9812171718070.102482-100000@dante27.u.washington.edu>
What's the best way to clear/erase a namespace? I have a persistent Perl
process which loads in other files and sometimes executes embedded Perl
code in a separate namespace, but I want that to all be erased before new
code is executed in that same namespace.
Perhaps a better question is-- where do I learn more about Perl's symbol
tables?
Thanks!
Brad
------------------------------
Date: 18 Dec 1998 01:50:09 GMT
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: How to "clear" a namespace?
Message-Id: <75ccch$c0k$1@csnews.cs.colorado.edu>
In comp.lang.perl.misc, Brad Fitzpatrick <bradfitz@bradfitz.com> writes:
:What's the best way to clear/erase a namespace?
Newer versions of Perl have a standard Symbol::delete_package function
that might well do what you want.
--tom [courtesy cc sent]
--
An Inteligent terminal is not a smart-ass terminal; it is one you can educate.
--Rob Pike
------------------------------
Date: 18 Dec 1998 00:12:26 GMT
From: dformosa@zeta.org.au (David Formosa)
Subject: Re: Intentionally causing a trap/dump/GPF?
Message-Id: <slrn77j7fa.1gf.dformosa@godzilla.zeta.org.au>
In article <75bqko$alh$1@nnrp1.dejanews.com>, chess@watson.ibm.com wrote:
>Is there some portable way in Perl to cause the current OS's
>version of a nasty crash? (GPF, trap, coredump, whatever?)
dump will cause perl to coredump.
--
Please excuse my spelling as I suffer from agraphia. See
http://www.zeta.org.au/~dformosa/Spelling.html to find out more.
------------------------------
Date: 18 Dec 1998 02:35:04 GMT
From: jacque@netleaf.com (Jacque Weddle)
Subject: Passing Multiple Arrays
Message-Id: <75cf0o$30g$1@slave3.aa.net>
Hello,
I have, what I hope will be, a simple question. How are multiple arrays
and hashes passed into a function. (They must be passed, I can't just
make them global) For example:
MyFunction(@array1,@array2,%hash1)
sub
MyFunction {
local(@array1,@array2,%hash1) = @_;
...
code
...
}
All of the data exists in @_ but I don't know how to make sure the data
coming into the function is split into separate arrays and not interpeted
as belonging all to the first array.
Any assistance would be much appreciated.
Thanks,
Jacque
--
------------------------------
Date: 17 Dec 1998 22:20:29 -0500
From: mjd@op.net (Mark-Jason Dominus)
Subject: Re: Passing Multiple Arrays
Message-Id: <75chlt$rfc$1@monet.op.net>
In article <75cf0o$30g$1@slave3.aa.net>,
Jacque Weddle <jacque@netleaf.com> wrote:
>I have, what I hope will be, a simple question. How are multiple arrays
>and hashes passed into a function.
See the `perlsub' man page; there is a section that begins:
Pass by Reference
If you want to pass more than one array or hash into a function--or
return them from it...
>Any assistance would be much appreciated.
I live only to serve.
------------------------------
Date: Fri, 18 Dec 1998 13:39:30 +1300
From: Kelvin Price <kprice@cardinal.co.nz>
Subject: Re: PERL & IIS internals
Message-Id: <3679A442.F736074@cardinal.co.nz>
Curt Cranfield wrote:
>
> Hi Everyone,
>
> I am a die-hard PERL unix programmer but I have been tasked with
> programming a script with PERL on NT.
>
> What I am wondering is - has anyone been able to access the internals of
> IIS to create such things a virtual servers - without having to do a
> system(iisadmin.exe .....) or system(createvirtual.vbs...)? Using these
> little MS programs is not a whole lot of fun!
>
> Ultimately, it would be nice to have a module that could access the
> internal files? Something I haven't been able to find at CPAN.
>
> Any help is greatly appreciated.
>
> Cheers,
>
> Curt
I haven't done exactly what you ask, but I have used Win32::OLE to
stop/start a W3SVC and find out where it's log files are (I needed to do
this for an automatic unattended backup of an app which had a web
component). The objects/methods/properties found in the .vbs scripts
are the same ones you can access via Win32::OLE.
HTH
Kelvin 8-D
------------------------------
Date: Fri, 18 Dec 1998 01:22:10 GMT
From: mgjv@comdyn.com.au (Martien Verbruggen)
Subject: Re: problem naming a directory with a number
Message-Id: <67ie2.89$Ep5.266@nsw.nnrp.telstra.net>
In article <Zhge2.39809$Pk4.21919942@news.inreach.com>,
"Brendan Murphy" <INFO@ARKSON.COM> writes:
> Hello!
>
> I am trying to have a cgi redirect to a page such as
> http://www.hello.com/redirect1111
>
> But instead of directing to that page it goes to
> http://www.hello.com/redirect111
Show us your code. We can't tell you what's wrong with it until we see
it.
Martien
--
Martien Verbruggen | My friend has a baby. I'm writing down
Webmaster www.tradingpost.com.au | all the noises the baby makes so later
Commercial Dynamics Pty. Ltd. | I can ask him what he meant - Steven
NSW, Australia | Wright
------------------------------
Date: Fri, 18 Dec 1998 01:38:12 GMT
From: Eric Wong <egwong@netcom.com>
Subject: Re: problem naming a directory with a number
Message-Id: <egwongF450Jo.C3@netcom.com>
Brendan Murphy <INFO@ARKSON.COM> wrote:
: Hello!
: I am trying to have a cgi redirect to a page such as
: http://www.hello.com/redirect1111
: But instead of directing to that page it goes to
: http://www.hello.com/redirect111
: Please, help.... must be some reason....
I think you left off a '1' in the second url.
Seriously though, it'd help if you were a bit more explicit
with your problem; perhaps even share a little of your code?
Are you using the CGI module?
Eric
------------------------------
Date: 17 Dec 1998 21:49:58 -0500
From: mjd@op.net (Mark-Jason Dominus)
Subject: Re: Reference Troubles
Message-Id: <75cfsm$ppt$1@monet.op.net>
In article <36797BF6.B8840280@psu.edu>, Brett Borger <bxb121@psu.edu> wrote:
>The definitions file is in the format:
>Name: Item1
>Value: Bob
>Special: Frank
>Name: Item2
>Special: None
>my(%list)={}; #Do I need to do this?
A. No. It's empty when you get it.
B. It's wrong anyway. {} is a reference to a hash, which is a single
scalar value. But when you assign to a hash, you have to specify a
list of pairs, like this:
%Wife = ( Ralph => Alice, Ed => Trixie, Nat => Jenine );
Note parentheses, not braces. See
http://www.plover.com/~mjd/perl/FAQs/Reference.html
for a short explanation of reference syntax.
>I get three "Odd number of hash elements" warnings (which I don't
>understand)
%hash = ( Ralph => Alice );
makes sense, because hash items always come in key-value pairs.
%hash = ( );
makes the hash empty.
%hash = ( Bonzo );
generates an error: `Odd number of hash elements', because there
should have been an even number, because hash items always come in
key-value pairs.
%hash = Bonzo;
is exactly the same; the parentheses weren't adding any meaning. In
this case, Perl' just ignores the extra item and makes the hash empty.
%hash = {};
is similar: {} is a scalar value: it's a *reference* to an anonymous
hash. So you're trying to assign a single item to a hash, and hashes
always want items in pairs.
By the way, the `perldiag' manual page explains this in detail; it has
an explanation of every error message.
>open(DATA,$filename);
No! No! Bad programmer! No biscuit.
open(DATA,$filename)
or die "Couldn't open `$filename' for reading: $!; aborting";
But you know, it seems like a shame to write a program that only works
on one file. Someday it might be useful to be able to say
process file1 file2 file3
and have it read in all three files, or to be able to say
someprogram | process -
to have it process the output of `someprogram'. There's a really easy
way to get that: Instead of opening the file yourself, just say
while (defined($line = <>)) {
The <> means to read from the files named on the command line, or from
the standard input if there are no files named on the command ilne.
On the command line, `-' means to read the standard input anyway.
Now you can play a sly trick here:
unless (@ARGV) { @ARGV = ($filename) }
If there are no command line arguments, you pretend that the user
specified the default file, and you go ahead and process it with <>
anyway.
>READIN: while(defined($line=<DATA>)){
Labels should be named according to the thing they control, like
`LINE' or `SECTION', because that way things like this make sense:
next LINE;
last SECTION;
Now, the main loop of your program is broken in a very interesting
way. You accumulate a bunch of stuff in variables, ($thisitem,
$thisname, $thiscontent, %list) and each time you see a new thing, you
install the current thing into the main data structure and then save
the new thing w into the variables here the current thing was.
This is a bad design, because you always have some data left over in
these variables that hasn't made it into the data structure yet. You
have a bunch of extra variables, and they have data in them that is
left over after you've read the input. A special part of the program
will have to gather up the missed data from these variables at the
end. (I think you forgot to do this anyway.)
In a well-designed program, the structure of the program will
correspond to the structure of the input. One good principle to
follow is that each thing should be installed into its final place as
soon as possible; that helps avoid errors in which you've forgotten to
something.
In my version of the program, we create a new item as soon as we see
the `Name' that introduces it. It's incomplete, because we haven't
read its properties yet, but that's all right. We will build it up as
we go, and if it turns out to be erroneous, it is easy to have the
program remove it again.
This is probably the most important part of this article, by the way.
All the other stuff is trivia, but this issue is central to
programming.
> push @items, \%list unless $notready;
> $gear{$thisname}=\%list unless $notready;
> $notready=0;
I think it would have been easier to understand if you had replaced
`notready' with `ready':
> push @items, \%list if $ready;
> $gear{$thisname}=\%list if $ready;
> $ready=1;
Then you don't have to initialize `$notready'. But it would have been
even simpler to ditch `$notready' entirely:
> push @items, \%list if defined $thisitem;
> $gear{$thisname}=\%list if defined $thisitem;
or some such. Also, it's silly to explicitly construct @items. If
you have %gear, you can get @items for free:
@items = values %gear;
If the idea here was to remember the order in which the items
appeared, there are several solutions that are better than the one you
chose. The simplest is to make a list of the names:
push @items, $thisname;
Also, you're pushing in a reference to a hash, and then a few lines
later you (try to) empty out the hash; that means that the reference
you just put into %gear now refers to an empty hash. Ooops. To evade
this, you need to copy the hash and install a reference to the copy
into %gear:
$gear{$thisname} = { %list };
But see the way I did it, below.
> ($thisitem,$thiscontent)=split(/:/,$line);
Here you just misunderstood the Perl `split' operator. If $line had
Hamlet: Alas, poor Yorick! I knew him, Horatio: a fellow of infinite jest
Then `$thisitem' gets `Hamlet', which is what you want, and
`$thiscontent' gets ` Alas, poor Yorick! I knew him, Horatio'. You
may be unhappy about the space at the beginning, but you will probably
be much more unhappy to lose `a fellow of infinite jest.' Poor Yorick
indeed! You should use:
($thisitem,$thiscontent) = split(/:\s*/, $line, 2);
The `2' on the end tells it to only split into 2 items, and not to
bother splitting up the second one.
>for ($i=0;$i<=$#items;$i++){
Any time you write this in Perl, back up and see if you haven't maybe
made a mistake. It's almost always better to say
foreach $item (@items) {
Because then this nastiness:
> foreach $key (keys(%{$items[$i]})){
> print "-$key: ${$items[$i]}{$key}\n";
becomes much less nasty:
> foreach $key (keys(%$item)){
> print "-$key: $$item{$key}\n";
Actually you can do even better:
> while (($key => $value) = keys %$item) {
> print "-$key: $value\n";
Now it's actually readable!
Of course, if you use `foreach $item (@items)' you don't get the index
number that you need for
> print "Item: $i\n";
If you really need that, here's how to write it. Instead of this:
>for ($i=0;$i<=$#items;$i++){
Say this:
>for ($i=0; $i < @items; $i++) {
Note the white space that breaks up the line into its logical
components. If in doubt, always add a space after a comma or a
semicolon.
Then instead of this:
> print "Item: $i\n";
> foreach $key (keys(%{$items[$i]})){
> print "-$key: ${$items[$i]}{$key}\n";
Use this:
> print "Item: $i\n";
> $item = $items[$i];
> foreach $key (keys %$item) {
> print "-$key: $$item{$key}\n";
Or:
> print "Item: $i\n";
> $item = $items[$i];
> while (($key, $value) = each %$item) {
> print "-$key: $value\n";
Perl has too much punctuation, so it's always a good idea to use as
little as possible.
>And that is all. I'd fight my way through it, but I'm not sure which
>end I screwed up, the storage or retreival.
Storage. Retrieval was basically sound, if somewhat turgid. Although
I notice that you never emitted the names. Was that on purpose?
>Any help is appreciated,
#!/usr/bin/perl -w
use strict;
my $cur_name = undef;
my %property; # This is where we store the input
unless (@ARGV) { @ARGV = ('/the/default/data/file') }
# Read in the input files
LINE: while (<>) {
s/#.*//; # Trim comments
/\S/ or next LINE; # Skip entirely blank lines
chomp;
# If the current line ends with a backslash, it is continued on the
# following line.
CONTINUATION:
while (/\\\s*$/) { # Check for backslash
my $next_line = <>;
$next_line =~ s/#.*//; # Trim comments
# Otherwise, append it to the current line:
$_ .= $next_line;
chomp;
# If the continuation line ends in a backslash, repeat the loop again
}
# Now we have processed comments and continuations; we have assembled
# one logical line that might have spanned several physical lines.
my ($key, $value) = split /:\s*/, $_, 2;
if ($key eq 'Name') { # Beginning of info about a new item
$cur_name = $value;
if (exists $property{$cur_name}) {
# This assumes that if you have two sections in your file with
# the same name, the second one is just a continuation of the first.
# You may want different behavior.
warn "There are two items named `$cur_name'; accumulating data.\n";
}
next LINE;
}
unless (defined $cur_name) {
warn "Unnamed data at the beginning of file at line $.; skipping.\n";
next LINE;
}
# Here's the part that uses references. Gosh, it sure is simple!
if (exists $property{$cur_name}{$key}) {
warn "Duplicate `$key' for item `$cur_name' at line $.; skipping.\n";
next LINE;
}
# Those references are practically invisible.
$property{$cur_name}{$key} = $value;
}
Hmm, that's all.
Now we have the data structure built, and it's easy to get what we want:
@names = keys %property; # Get list of all item names
@items = values %property; # Get list of all item hashes
my %properties = %{$property{'Item1'}}; # Get properties of `Item1'
print $properties{'Special'}; # `Frank'
So let's do an output something like yours:
# Generate report
foreach $name (sort keys %property) {
print "Item: $name\n";
my $item = $property{$name};
my ($key => $value);
foreach $key (sort keys %$item) {
print "-$key: $$item{$key}\n";
}
}
Hope this helps.
>thanks.
Have a nice day.
------------------------------
Date: 18 Dec 1998 00:01:06 GMT
From: "Allan M. Due" <due@murray.fordham.edu>
Subject: Re: Search Not Working
Message-Id: <75c602$971$0@206.165.165.139>
Tim Hicks wrote in message ...
|Hi all,
|
|I am pretty new to perl, but have read through 'Learning Perl' a couple of
|times.
|I am now trying to write a simple search script that looks through a small
|'|' delimitted text database file. I have tried to give people the option
|of which column they want to search by. I have made everything run without
|any errors, except that it doesn't output what I expect from doing the
|process myself. Here is my script and a sample of my database.
|
|Thanks for your help, if you give any!!
|
|#!/usr/bin/perl -w
use strict is always a good idea.
|
|open(TOURN2, "tourndata2.txt") || die "cannot open tourndata2.txt for
|reading: $!";
|open(TEMP, ">temp.txt") || die "cannot open temp.txt for writing: $!";
|
|print "Here is the template for the database...\n\n";
|print "Name|Events|Closing_Date|Start_Date|Venue|Region|Ratings\n";
|print " 1 | 2 | 3 | 4 | 5 | 6 | 7\n\n";
|print "Choose which field to search using the number codes: ";
|chomp ($select=<STDIN>);
|
|if ($select == 1) {
| searcher (0);
|} elsif ($select == 2) {
| searcher (1);
|} elsif ($select == 3) {
| searcher (2);
|} elsif ($select == 4) {
| searcher (3);
|} elsif ($select == 5) {
| searcher (4);
|} elsif ($select == 6) {
| searcher (5);
|} elsif ($select == 7) {
| searcher (6);
|} else {
| print "You input an unexpected value, please run the search engine again.";
|}
I will leave discussions of the above to others and deal with the major
problem.
|sub searcher {
| $col=$_[0];
| print "Enter your search word: ";
| chomp ($word=<STDIN>);
|
| foreach (<TOURN2>) {
| @record = split(/|/,$_);
Well, that | is a problem as it is the alternation metacharacter. You need to
escape it
@record = split(/\|/,$_);
HTH
AmD
------------------------------
Date: Thu, 17 Dec 1998 17:02:19 -0800
From: lr@hpl.hp.com (Larry Rosler)
Subject: Re: Search Not Working
Message-Id: <MPG.10e3497b293c24139898d8@nntp.hpl.hp.com>
In article <75c602$971$0@206.165.165.139> on 18 Dec 1998 00:01:06 GMT,
Allan M. Due <due@murray.fordham.edu> says...
> Tim Hicks wrote in message ...
...
> | @record = split(/|/,$_);
>
> Well, that | is a problem as it is the alternation metacharacter. You need to
> escape it
>
> @record = split(/\|/,$_);
Judging by the frequency of that bug in this newsgroup, it would make
any "top 10" list of Frequent Perl Bugs, at least in the regex area.
Such lists for C and C++ ended up in books, "C Traps And Pitfalls" by
Andrew Koenig, ISBN 0201179288, and "Ruminations on C++" by Andrew
Koenig and Barbara Moo, ISBN 0201423391. Any similar lists for Perl?
--
(Just Another Larry) Rosler
Hewlett-Packard Company
http://www.hpl.hp.com/personal/Larry_Rosler/
lr@hpl.hp.com
------------------------------
Date: 17 Dec 1998 22:40:11 -0500
From: mjd@op.net (Mark-Jason Dominus)
Subject: Re: Syntax Error...Not able to find.
Message-Id: <75ciqr$sd7$1@monet.op.net>
In article <19981217153906.04524.00000593@ng-ca1.aol.com>,
Groovy94 <groovy94@aol.com> wrote:
>I see no apparent errors in the syntax,
Well, Uri found three, and here's another four:
>While(-f resellers.lock) {
You need quotes around `resellers.lock' here, or it'll think that the
`.' is a string concatenate operator:
>while(-f 'resellers.lock') {
Also, your locking strategy doesn't work. Suppose two instances of
your program both reach this test at the same time. They'll both see
that the lock file doesn't exist, and then they'll move on to the next
line:
> open(RESELLERS,">resellers.lock") || &error("Unable to write to
>resellers.dat");
Then they'll both succeed in opening the lock file, and they'll
continue and ruin your data. Since you don't know what you're doing,
I'd recommend that you try to use DB_File or GDBM_File; they do the
locking automatically. Just add
use GDBM_File;
or
use DB_File;
at the top of your program; if one doesn't work, try the other, and if
neither works, give up.
> dbmopen(%resellers, $real_path/resellers, 0666);
You need quotes on the filename here or it'll think that the / means division:
dbmopen(%resellers, "$real_path/resellers", 0666);
> $resellers{'reseller$number_resellers'}=$INPUT{'name'},$INPUT{'email'},
>$INPUT{'url'}, $INPUT{'username'}, $pass;
Uri already pointed out that you used the wrong quotes here. But
also, the commas here aren't doing what you think. The comma operator
evaluates its left argmuent, throws the result away, and then
evaluates its right argument. So what you wrote here is just the same
as if you had left out the various $INPUT items.
Maybe you should have done
$resellers{"reseller$number_resellers"}=
join ',', $INPUT{'name'},$INPUT{'email'},
$INPUT{'url'}, $INPUT{'username'},
$pass;
But I would have written
$resellers{"reseller$number_resellers"}=
join ',', @INPUT{'name','email','url','username'}, $pass;
> dbmclose (resellers);
Here you need `%resellers'.
Maybe you need to look at more examples.
------------------------------
Date: 18 Dec 1998 01:49:57 GMT
From: ltl@rgpcultl.viasystems.com (Lee Lindley)
Subject: Re: telnet by perl
Message-Id: <75ccc5$co7$1@rguxd.viasystems.com>
Sam Curren (samc@empirewest.com) wrote:
:>I'm attempting to open a telnet session to a server on a specific port,
:>wait for the init string, then send it one line of text and disconnect.
:>All servers being linux.
:>Being able to save all the output of the other server would be a plus.
:>I can do all the work, but does anyone have a general place to start? I'd
:>rather use a module then a system call, but a system call can be made.
Download Net::Telnet from CPAN.
--
// Lee.Lindley | There was a time when I thought that "being right"
// @bigfoot.com | was everything. Then I realized that getting along
// | was more important. Still, being right is more fun!
// | And if I'm wrong, somebody will get some joy out of telling me!
------------------------------
Date: 12 Dec 98 21:33:47 GMT (Last modified)
From: Perl-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Special: Digest Administrivia (Last modified: 12 Dec 98)
Message-Id: <null>
Administrivia:
Well, after 6 months, here's the answer to the quiz: what do we do about
comp.lang.perl.moderated. Answer: nothing.
]From: Russ Allbery <rra@stanford.edu>
]Date: 21 Sep 1998 19:53:43 -0700
]Subject: comp.lang.perl.moderated available via e-mail
]
]It is possible to subscribe to comp.lang.perl.moderated as a mailing list.
]To do so, send mail to majordomo@eyrie.org with "subscribe clpm" in the
]body. Majordomo will then send you instructions on how to confirm your
]subscription. This is provided as a general service for those people who
]cannot receive the newsgroup for whatever reason or who just prefer to
]receive messages via e-mail.
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.misc (and this Digest), send your
article to perl-users@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.
The Meta-FAQ, an article containing information about the FAQ, is
available by requesting "send perl-users meta-faq". The real FAQ, as it
appeared last in the newsgroup, can be retrieved with the request "send
perl-users FAQ". Due to their sizes, neither the Meta-FAQ nor the FAQ
are included in the digest.
The "mini-FAQ", which is an updated version of the Meta-FAQ, is
available by requesting "send perl-users mini-faq". It appears twice
weekly in the group, but is not distributed in the digest.
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 V8 Issue 4450
**************************************