[26214] in Perl-Users-Digest
Perl-Users Digest, Issue: 8400 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Fri Sep 9 11:05:29 2005
Date: Fri, 9 Sep 2005 08:05:04 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Fri, 9 Sep 2005 Volume: 10 Number: 8400
Today's topics:
Re: Complex data structures and variable scope (Anno Siegel)
Re: Complex data structures and variable scope <news@lawshouse.org>
Re: Complex data structures and variable scope <1usa@llenroc.ude.invalid>
Re: Echoing fatal errors in Unix vs. Windows <tadmc@augustmail.com>
Re: My Net::eBay PERL module now recommended by eBay it <ignoramus965@NOSPAM.965.invalid>
Re: scalar variable in system command function (Anno Siegel)
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: 9 Sep 2005 10:05:19 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Complex data structures and variable scope
Message-Id: <dfrmov$g03$1@mamenchi.zrz.TU-Berlin.DE>
Henry Law <news@lawshouse.org> wrote in comp.lang.perl.misc:
> I wonder if someone can help me with working out where to define my
> variables so as to give the desired result here...
>
> Personnel data is to be read from a file. Attributes for each
> employee are presented as name/value pairs; some pairs occur once
> only, but each person can have more than one qualification. The data
> is to be accumulated in a hash, keyed by the person's name; each
> person's hash contains their attributes, plus an reference to an array
> containing their qualifications. This enables me (using other
> programming not relevant here) to look up any employee by name and
> present their attributes and qualifications.
>
> Here's a runnable program which shows where I've got to. It gives the
> wrong results and I'm trying to work out how to fix it.
I haven't completely analyzed your code. The two remarks I added are
inessential to your problem.
> --------------- <start of example> -----------------
> #! C:\Perl\bin\perl.exe
>
> use strict;
> use warnings;
> use Data::Dumper;
>
> my %people;
> my %attrs;
> my @quals;
>
> while (my $rec = <DATA>) {
> #my %attrs;
> #my @quals;
> chomp $rec;
> if ($rec) {
> my ($name,$value) = split /:/, $rec;
> if ($name eq "qual") {
> push @quals,$value;
> next;
> }
> $attrs{$name} = $value;
> } else { # End of person
> $attrs{quals} = \@quals;
> $people{$attrs{name}} = \%attrs;
> #undef %attrs;
> #undef @quals;
The normal way to clear an aggregate is by setting it to (), so the
commented code should be
%attrs = ();
@quals = ();
Undef'ing does work as expected, but has the effect of destroying
the aggregate entirely. That is normally not what you want.
> }
> }
> print Dumper(%people);
That dump is a bit misleading. Data::Dumper dumps references, so
that should be
print Dumper \ %people;
> __END__
> name:alice
> occupation:analyst
> born:aberdeen
> qual:a1
> qual:a2
>
> name:bob
> occupation:baker
> status:broken
> qual:b1
> qual:b2
> ---------------- <end of example> ------------------
>
> This results in
> $VAR1 = 'alice';
> $VAR2 = {
> 'quals' => [
> 'a1',
> 'a2',
> 'b1',
> 'b2'
> ],
> 'status' => 'broken',
> 'name' => 'bob',
> 'born' => 'aberdeen',
> 'occupation' => 'baker'
> };
With the corrected dump the result looks a little more plausible:
$VAR1 = {
'alice' => {
'status' => 'broken',
'born' => 'aberdeen',
'name' => 'bob',
'quals' => [
'a1',
'a2',
'b1',
'b2'
],
'occupation' => 'baker'
}
};
though that's still not what you want.
> I can see what's wrong: %attrs and @quals have scope outside the
> file-read loop, so when the program gets to Bob's records they either
> add to or replace Alice's. But I can't define them inside the read
> loop because they then disappear and reappear with each record (you
> can see where I tried this in the comments). I've also tried
> undef-ing the arrays at the end of each person (also as shown),
> without getting the desired result.
One difficulty is that you are reading the input line-wise, but
process it by paragraphs. This is always a bit tricky because
some passes through the loop are different from the others. Reading
the file paragraph-wise simplifies things because each loop processes
one person. In particular, you can now declare a lexical hash %person
in the loop body. It will be re-used each time through the loop (which
wouldn't work if each person required multiple passes).
my %people;
$/ = ''; # paragraph mode
while ( <DATA> ) {
my %person;
for ( split /\n/ ) { # process all lines for one person
my ( $key, $val) = split /:/;
if ( $key eq 'qual' ) {
push @{ $person{ quals}}, $val;
} else {
$person{ $key} = $val;
}
}
$people{ $person{ name}} = \ %person;
}
print Dumper \ %people;
__DATA__
(etc)
Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
------------------------------
Date: Fri, 09 Sep 2005 11:33:28 +0100
From: Henry Law <news@lawshouse.org>
Subject: Re: Complex data structures and variable scope
Message-Id: <gpo2i1d1ntu93k0n6dnohcpd49hkj26fh2@4ax.com>
On 9 Sep 2005 10:05:19 GMT, anno4000@lublin.zrz.tu-berlin.de (Anno
Siegel) wrote:
>Reading
>the file paragraph-wise simplifies things because each loop processes
>one person.
That's the key suggestion; I hadn't even considered trying paragraphs.
>In particular, you can now declare a lexical hash %person
>in the loop body. It will be re-used each time through the loop (which
>wouldn't work if each person required multiple passes).
... which is precisely what I need.
> my %people;
... followed by code that does exactly what I want.
> __DATA__
> (etc)
Thank you Anno. How good it is that you're in a European time zone,
so I don't have to wait for Sinan, Paul etc to wake up :-)
--
Henry Law <>< Manchester, England
------------------------------
Date: Fri, 09 Sep 2005 11:49:23 GMT
From: "A. Sinan Unur" <1usa@llenroc.ude.invalid>
Subject: Re: Complex data structures and variable scope
Message-Id: <Xns96CC4F9622E86asu1cornelledu@127.0.0.1>
Henry Law <news@lawshouse.org> wrote in
news:26h2i1dk2hp5eu46lhblp8sllhuebjhjj2@4ax.com:
> --------------- <start of example> -----------------
> #! C:\Perl\bin\perl.exe
I have nothing useful to add to Anno's response, but I am just going to
point out that you do not need the shebang line above on Windows.
It is convenient to use
#!/usr/bin/perl
in case you later want to move the script to a *nix system. In setups I
have worked with, that tends to be symlinked to the system default perl.
Note that you can still specify options on the shebang line above on
Windows. perl will respect them.
Hope this helps.
Sinan
--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)
comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
------------------------------
Date: Fri, 9 Sep 2005 06:59:40 -0500
From: Tad McClellan <tadmc@augustmail.com>
Subject: Re: Echoing fatal errors in Unix vs. Windows
Message-Id: <slrndi2u9c.5e8.tadmc@magna.augustmail.com>
Bob <uctraing@ultranet.com> wrote:
> How can I redirect the error output to dump back to
> the browser ?
perldoc -q error
My CGI script runs from the command line but not the browser. (500
Server Error)
How can I get better error messages from a CGI program?
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
------------------------------
Date: Fri, 09 Sep 2005 14:05:23 GMT
From: Ignoramus965 <ignoramus965@NOSPAM.965.invalid>
Subject: Re: My Net::eBay PERL module now recommended by eBay itself
Message-Id: <DEgUe.38123$U74.24798@fe19.usenetserver.com>
On Thu, 08 Sep 2005 23:14:39 -0500, Eric J. Roode <sdn.girths00869@zoemail.net> wrote:
> Ignoramus12789 <ignoramus12789@NOSPAM.12789.invalid> wrote in
> news:MBPRe.60261$Jz4.50444@fe50.usenetserver.com:
>
>> The Perl::eBay module that I wrote a few days ago, is now recommended
>> by ebay:
>>
>> http://developer.ebay.com/php/
>
> Hey, that's pretty cool. Good for you.
>
Thanks.
Someone already wrote to me asking for new features and such. I am
quite happy.
i
--
------------------------------
Date: 9 Sep 2005 11:35:52 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: scalar variable in system command function
Message-Id: <dfrs2o$irj$1@mamenchi.zrz.TU-Berlin.DE>
Rocky Allen <everythingelse@bobotheclown.org> wrote in comp.lang.perl.misc:
> I have an odd problem with the $file variable listed in the loop below
Paul Lalli has cleared up your main problem.
Somewhere else you say:
> foreach my $file (@largefiles) {
> $file =~ s/\.\///;
That is an unsafe way to clean up a file name. Look at what it does
to "a./b". On the other hand, it doesn't deal with "././x" correctly.
File::Spec has the function canonpath() to logically clean up paths.
Use it.
Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
------------------------------
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.
NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice.
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 8400
***************************************