[28480] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 9844 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Fri Oct 13 14:10:15 2006

Date: Fri, 13 Oct 2006 11:10:07 -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, 13 Oct 2006     Volume: 10 Number: 9844

Today's topics:
        read from a file and create a hash <mark.leeds@morganstanley.com>
    Re: read from a file and create a hash <David.Squire@no.spam.from.here.au>
    Re: read from a file and create a hash <mark.leeds@morganstanley.com>
    Re: read from a file and create a hash usenet@DavidFilmer.com
    Re: read from a file and create a hash anno4000@radom.zrz.tu-berlin.de
    Re: read from a file and create a hash <David.Squire@no.spam.from.here.au>
    Re: read from a file and create a hash <David.Squire@no.spam.from.here.au>
    Re: read from a file and create a hash <tadmc@augustmail.com>
    Re: read from a file and create a hash <jgibson@mail.arc.nasa.gov>
    Re: read from a file and create a hash <uri@stemsystems.com>
    Re: Sorting and moving files to dir for DVD burn <bik.mido@tiscalinet.it>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: 13 Oct 2006 08:36:52 -0700
From: "markpark" <mark.leeds@morganstanley.com>
Subject: read from a file and create a hash
Message-Id: <1160753812.253033.60300@e3g2000cwe.googlegroups.com>

I have what is most likely a simple problem tosolve. I am reading from
a text file which
is shown below and i just wanted to make a key value paired hash table
out of it.
( maybe key value paied hash table is redundant since that's the def of
a hash table )

datadir       /u/etlfs/dev/users/leedsmar/res/proj2/wrk
startdate       20060120
currency       eur/usd.FXEBSLN
enddate       20060130
outfile       test.dat
starttime       00:00:01
endtime       00:05:00
exchange       fxebsln
driverfile       r_driver.EUROUSD

the code for doing this routine is shown below and it almost works. the
only problem is that
a tenth key value pair ( there are only
nine lines in the file so something weird is happening )  of the hash
seems to get
inserted because i get HASH(080fb174) s one of my key value pairs when
i print it out the hash.

thank you very much to whoever would be kind enough
to look at this routine. i must be doing something slightly wrong.

sub get_driver_file {

my $infile = $_[0];

my %driver={};

open IN_FILE, "<$infile" or die "could not open $infile for reading";

while ( <IN_FILE> ) {
  my ($key,$value) = split /\s+/,$_;
       $driver{$key} = $value;
}

print "          \n";
print "check if we get the correct keys and values\n";

while  ( my ( $key,$value ) = each %driver ) {
  print "$key  $value \n";
}

return (%driver);

}


#----------------------------------------------------------------------------------------------------------------------------------

my $params =
get_driver_file("/u/etlfs/dev/users/leedsmar/res/proj2/wrk/test.dat");



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

Date: Fri, 13 Oct 2006 17:03:38 +0100
From: David Squire <David.Squire@no.spam.from.here.au>
Subject: Re: read from a file and create a hash
Message-Id: <egodcq$3g$1@gemini.csx.cam.ac.uk>

markpark wrote:
> I have what is most likely a simple problem tosolve. I am reading from
> a text file which
> is shown below and i just wanted to make a key value paired hash table
> out of it.
> ( maybe key value paied hash table is redundant since that's the def of
> a hash table )
> 
> datadir       /u/etlfs/dev/users/leedsmar/res/proj2/wrk
> startdate       20060120
> currency       eur/usd.FXEBSLN
> enddate       20060130
> outfile       test.dat
> starttime       00:00:01
> endtime       00:05:00
> exchange       fxebsln
> driverfile       r_driver.EUROUSD
> 
> the code for doing this routine is shown below and it almost works. the
> only problem is that
> a tenth key value pair ( there are only
> nine lines in the file so something weird is happening )  of the hash
> seems to get
> inserted because i get HASH(080fb174) s one of my key value pairs when
> i print it out the hash.

Could you show us your *complete* actual output? I can't see how that
would happen in the script you present below.
> 
> thank you very much to whoever would be kind enough
> to look at this routine. i must be doing something slightly wrong.
> 
> sub get_driver_file {
> 
> my $infile = $_[0];

I would write:

my $infile = shift;

> 
> my %driver={};

initialization not necessary.

> open IN_FILE, "<$infile" or die "could not open $infile for reading";

I would use a lexical filehandle, the safer three argument form of
"open", and report what has gone wrong on failure using $!:

open my $IN_FILE, '<', $infile or die "could not open $infile for
reading: $!";

> 
> while ( <IN_FILE> ) {

You almost certainly want to "chomp" here to remove the end-of-line
character(s):

chomp;

>   my ($key,$value) = split /\s+/,$_;

No need to specify the $_ variable in that line. On the other hand, you
probably want to specify that you only want two results from split, in
case the "value" part of your line contains \s characters anywhere:

my ($key,$value) = split /\s+/, $_, 2;

>        $driver{$key} = $value;
> }
> 
> print "          \n";
> print "check if we get the correct keys and values\n";
> 
> while  ( my ( $key,$value ) = each %driver ) {
>   print "$key  $value \n";
> }
> 
> return (%driver);

You are returning a hash here, but you are assigning the result of the
call to a scalar below. You probably want to return a hash reference:

return \%driver;

> 
> }
> 
> 
> #----------------------------------------------------------------------------------------------------------------------------------
> 
> my $params =
> get_driver_file("/u/etlfs/dev/users/leedsmar/res/proj2/wrk/test.dat");
> 

Here's a test script based on yours (also illustrating the use of
"__DATA__" so that you don't need to depend on an external file when
posting here). I've also moved the test printing out of the subroutine
for clarity:

----
#!/usr/bin/perl

use strict;
use warnings;

sub get_driver_file {

	my %driver;
	while ( <DATA> ) {
		chomp;
		my ($key, $value) = split /\s+/, $_, 2;
		$driver{$key} = $value;
	}
	return (\%driver);

}

my $params_ref = get_driver_file();
while  ( my ( $key, $value ) = each %$params_ref ) {
	print "$key:\t$value \n";
}


__DATA__
datadir       /u/etlfs/dev/users/leedsmar/res/proj2/wrk
startdate       20060120
currency       eur/usd.FXEBSLN
enddate       20060130
outfile       test.dat
starttime       00:00:01
endtime       00:05:00
exchange       fxebsln
driverfile       r_driver.EUROUSD


----

Output:


check if we get the correct keys and values
currency:       eur/usd.FXEBSLN
outfile:        test.dat
starttime:      00:00:01
enddate:        20060130
driverfile:     r_driver.EUROUSD
endtime:        00:05:00
startdate:      20060120
datadir:        /u/etlfs/dev/users/leedsmar/res/proj2/wrk
exchange:       fxebsln

----

So you see it works fine. It also works fine without the chomp, but the
values all have trailing EOL characters (though in your original version
they aren't there as a side-effect of your split).

I suspect that there is something in your code that we can't see here...


DS


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

Date: 13 Oct 2006 09:12:04 -0700
From: "markpark" <mark.leeds@morganstanley.com>
Subject: Re: read from a file and create a hash
Message-Id: <1160755924.300183.298890@m7g2000cwm.googlegroups.com>

Thank you very much david. i will definitely change my code to yours
because
i'm a total novice and i'm sure everything you said is useful.

below is my output ? it's very weird. maybe it has something
to do with some of the things you mentioned ? i'll change mine to yours
and not worry about
it for now. Thanks soo much. This list is truly amazing. I can't
believe how generous and
helpful people are.

check if we get the correct keys and values
startdate  20060120
datadir  /u/etlfs/dev/users/leedsmar/res/proj2/wrk
enddate  20060130
outfile  test.dat
HASH(0x80fb174)
driverfile  r_driver.EUROUSD
exchange  fxebsln
currency  eur/usd.FXEBSLN
starttime  00:00:01
endtime  00:05:00




David Squire wrote:
> markpark wrote:
> > I have what is most likely a simple problem tosolve. I am reading from
> > a text file which
> > is shown below and i just wanted to make a key value paired hash table
> > out of it.
> > ( maybe key value paied hash table is redundant since that's the def of
> > a hash table )
> >
> > datadir       /u/etlfs/dev/users/leedsmar/res/proj2/wrk
> > startdate       20060120
> > currency       eur/usd.FXEBSLN
> > enddate       20060130
> > outfile       test.dat
> > starttime       00:00:01
> > endtime       00:05:00
> > exchange       fxebsln
> > driverfile       r_driver.EUROUSD
> >
> > the code for doing this routine is shown below and it almost works. the
> > only problem is that
> > a tenth key value pair ( there are only
> > nine lines in the file so something weird is happening )  of the hash
> > seems to get
> > inserted because i get HASH(080fb174) s one of my key value pairs when
> > i print it out the hash.
>
> Could you show us your *complete* actual output? I can't see how that
> would happen in the script you present below.
> >
> > thank you very much to whoever would be kind enough
> > to look at this routine. i must be doing something slightly wrong.
> >
> > sub get_driver_file {
> >
> > my $infile = $_[0];
>
> I would write:
>
> my $infile = shift;
>
> >
> > my %driver={};
>
> initialization not necessary.
>
> > open IN_FILE, "<$infile" or die "could not open $infile for reading";
>
> I would use a lexical filehandle, the safer three argument form of
> "open", and report what has gone wrong on failure using $!:
>
> open my $IN_FILE, '<', $infile or die "could not open $infile for
> reading: $!";
>
> >
> > while ( <IN_FILE> ) {
>
> You almost certainly want to "chomp" here to remove the end-of-line
> character(s):
>
> chomp;
>
> >   my ($key,$value) = split /\s+/,$_;
>
> No need to specify the $_ variable in that line. On the other hand, you
> probably want to specify that you only want two results from split, in
> case the "value" part of your line contains \s characters anywhere:
>
> my ($key,$value) = split /\s+/, $_, 2;
>
> >        $driver{$key} = $value;
> > }
> >
> > print "          \n";
> > print "check if we get the correct keys and values\n";
> >
> > while  ( my ( $key,$value ) = each %driver ) {
> >   print "$key  $value \n";
> > }
> >
> > return (%driver);
>
> You are returning a hash here, but you are assigning the result of the
> call to a scalar below. You probably want to return a hash reference:
>
> return \%driver;
>
> >
> > }
> >
> >
> > #----------------------------------------------------------------------------------------------------------------------------------
> >
> > my $params =
> > get_driver_file("/u/etlfs/dev/users/leedsmar/res/proj2/wrk/test.dat");
> >
>
> Here's a test script based on yours (also illustrating the use of
> "__DATA__" so that you don't need to depend on an external file when
> posting here). I've also moved the test printing out of the subroutine
> for clarity:
>
> ----
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> sub get_driver_file {
>
> 	my %driver;
> 	while ( <DATA> ) {
> 		chomp;
> 		my ($key, $value) = split /\s+/, $_, 2;
> 		$driver{$key} = $value;
> 	}
> 	return (\%driver);
>
> }
>
> my $params_ref = get_driver_file();
> while  ( my ( $key, $value ) = each %$params_ref ) {
> 	print "$key:\t$value \n";
> }
>
>
> __DATA__
> datadir       /u/etlfs/dev/users/leedsmar/res/proj2/wrk
> startdate       20060120
> currency       eur/usd.FXEBSLN
> enddate       20060130
> outfile       test.dat
> starttime       00:00:01
> endtime       00:05:00
> exchange       fxebsln
> driverfile       r_driver.EUROUSD
>
>
> ----
>
> Output:
>
>
> check if we get the correct keys and values
> currency:       eur/usd.FXEBSLN
> outfile:        test.dat
> starttime:      00:00:01
> enddate:        20060130
> driverfile:     r_driver.EUROUSD
> endtime:        00:05:00
> startdate:      20060120
> datadir:        /u/etlfs/dev/users/leedsmar/res/proj2/wrk
> exchange:       fxebsln
>
> ----
>
> So you see it works fine. It also works fine without the chomp, but the
> values all have trailing EOL characters (though in your original version
> they aren't there as a side-effect of your split).
>
> I suspect that there is something in your code that we can't see here...
> 
> 
> DS



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

Date: 13 Oct 2006 09:49:21 -0700
From: usenet@DavidFilmer.com
Subject: Re: read from a file and create a hash
Message-Id: <1160758160.771654.137760@h48g2000cwc.googlegroups.com>

markpark wrote:
> I have what is most likely a simple problem tosolve. I am reading from
> a text file which
> is shown below and i just wanted to make a key value paired hash table
> out of it.

Uri Guttman's famous config file parser (small and simple):

   my %conf = read_file( $filename ) =~ /^([^=]+)=(.+)$/mg ;

can be easily adapted to this (using whitespace instead of '=')

--
The best way to get a good answer is to ask a good question.
David Filmer (http://DavidFilmer.com)



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

Date: 13 Oct 2006 16:52:42 GMT
From: anno4000@radom.zrz.tu-berlin.de
Subject: Re: read from a file and create a hash
Message-Id: <4p9uiqFhvj92U2@news.dfncis.de>

David Squire  <David.Squire@no.spam.from.here.au> wrote in comp.lang.perl.misc:
> markpark wrote:

[...]

> > inserted because i get HASH(080fb174) s one of my key value pairs when
> > i print it out the hash.
> 
> Could you show us your *complete* actual output? I can't see how that
> would happen in the script you present below.
> > 
> > thank you very much to whoever would be kind enough
> > to look at this routine. i must be doing something slightly wrong.
> > 
> > sub get_driver_file {
> > 
> > my $infile = $_[0];
> 
> I would write:
> 
> my $infile = shift;
> 
> > 
> > my %driver={};
> 
> initialization not necessary.

Here we go.  It's not only unnecessary but it's wrong.  warnings would
have caught it.

> > open IN_FILE, "<$infile" or die "could not open $infile for reading";
> 
> I would use a lexical filehandle, the safer three argument form of
> "open", and report what has gone wrong on failure using $!:
> 
> open my $IN_FILE, '<', $infile or die "could not open $infile for
> reading: $!";
> 
> > 
> > while ( <IN_FILE> ) {
> 
> You almost certainly want to "chomp" here to remove the end-of-line
> character(s):
>
> chomp;
> 

Not with the kind of split that follows

> >   my ($key,$value) = split /\s+/,$_;

The final linefeed is eaten by split on white space.  The resulting
trailing empty field is eaten by split without a limit specification.
The result is the same with or without chomp.

It may be wise to chomp anyhow.

[...]

Anno


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

Date: Fri, 13 Oct 2006 18:01:50 +0100
From: David Squire <David.Squire@no.spam.from.here.au>
Subject: Re: read from a file and create a hash
Message-Id: <egogpu$6g1$1@gemini.csx.cam.ac.uk>

anno4000@radom.zrz.tu-berlin.de wrote:
> David Squire  <David.Squire@no.spam.from.here.au> wrote in comp.lang.perl.misc:
>> markpark wrote:
>>
>>> my %driver={};
>> initialization not necessary.
> 
> Here we go.  It's not only unnecessary but it's wrong.  warnings would
> have caught it.

Could you elaborate?

>> You almost certainly want to "chomp" here to remove the end-of-line
>> character(s):
>>
>> chomp;
> 
> Not with the kind of split that follows
> 
>>>   my ($key,$value) = split /\s+/,$_;
> 
> The final linefeed is eaten by split on white space.  The resulting
> trailing empty field is eaten by split without a limit specification.
> The result is the same with or without chomp.
> 
> It may be wise to chomp anyhow.

 ... as indeed I observed further down in my post...


DS


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

Date: Fri, 13 Oct 2006 18:04:28 +0100
From: David Squire <David.Squire@no.spam.from.here.au>
Subject: Re: read from a file and create a hash
Message-Id: <egogus$6g1$2@gemini.csx.cam.ac.uk>

David Squire wrote:
> anno4000@radom.zrz.tu-berlin.de wrote:
>> David Squire  <David.Squire@no.spam.from.here.au> wrote in comp.lang.perl.misc:
>>> markpark wrote:
>>>
>>>> my %driver={};
>>> initialization not necessary.
>> Here we go.  It's not only unnecessary but it's wrong.  warnings would
>> have caught it.
> 
> Could you elaborate?
> 

Ah. I just saw it. It's being initialized with anonymous hashref, rather
than an empty hash. That explains the OP's observed output. Ta.

I was thinking of

my %driver=();

which would be unnecessary, but harmless.


DS


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

Date: Fri, 13 Oct 2006 12:22:18 -0500
From: Tad McClellan <tadmc@augustmail.com>
Subject: Re: read from a file and create a hash
Message-Id: <slrneiviqa.bo3.tadmc@magna.augustmail.com>

David Squire <David.Squire@no.spam.from.here.au> wrote:
> anno4000@radom.zrz.tu-berlin.de wrote:
>> David Squire  <David.Squire@no.spam.from.here.au> wrote in comp.lang.perl.misc:
>>> markpark wrote:
>>>
>>>> my %driver={};
>>> initialization not necessary.
>> 
>> Here we go.  It's not only unnecessary but it's wrong.  warnings would
>> have caught it.
> 
> Could you elaborate?


    perl -we 'my %driver={}'

    Reference found where even-sized list expected at -e line 1.


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


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

Date: Fri, 13 Oct 2006 10:36:04 -0700
From: Jim Gibson <jgibson@mail.arc.nasa.gov>
Subject: Re: read from a file and create a hash
Message-Id: <131020061036042987%jgibson@mail.arc.nasa.gov>

In article <1160753812.253033.60300@e3g2000cwe.googlegroups.com>,
markpark <mark.leeds@morganstanley.com> wrote:

> I have what is most likely a simple problem tosolve. I am reading from
> a text file which
> is shown below and i just wanted to make a key value paired hash table
> out of it.
> ( maybe key value paied hash table is redundant since that's the def of
> a hash table )
> 
> datadir       /u/etlfs/dev/users/leedsmar/res/proj2/wrk
> startdate       20060120
> currency       eur/usd.FXEBSLN
> enddate       20060130
> outfile       test.dat
> starttime       00:00:01
> endtime       00:05:00
> exchange       fxebsln
> driverfile       r_driver.EUROUSD
> 
> the code for doing this routine is shown below and it almost works. the
> only problem is that
> a tenth key value pair ( there are only
> nine lines in the file so something weird is happening )  of the hash
> seems to get
> inserted because i get HASH(080fb174) s one of my key value pairs when
> i print it out the hash.
> 
> thank you very much to whoever would be kind enough
> to look at this routine. i must be doing something slightly wrong.
> 
> sub get_driver_file {
> 
> my $infile = $_[0];
> 
> my %driver={};

This is the wrong syntax for declaring an empty hash. The '{}' is a
reference to a hash, hence the key 'HASH(080fb174)' that you get. You
want an empty hash:

   my %driver=();

or even more simply as:

   my %driver;


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

Date: Fri, 13 Oct 2006 13:41:48 -0400
From: Uri Guttman <uri@stemsystems.com>
Subject: Re: read from a file and create a hash
Message-Id: <x77iz4qfj7.fsf@mail.sysarch.com>

>>>>> "DS" == David Squire <David.Squire@no.spam.from.here.au> writes:

  DS> markpark wrote:

  >> my %driver={};

  DS> initialization not necessary.

especially incorrect initialization. using warnings would have caught
this.

  DS> ----
  DS> #!/usr/bin/perl

  DS> use strict;
  DS> use warnings;

  DS> sub get_driver_file {

  DS> 	my %driver;
  DS> 	while ( <DATA> ) {
  DS> 		chomp;
  DS> 		my ($key, $value) = split /\s+/, $_, 2;
  DS> 		$driver{$key} = $value;
  DS> 	}
  DS> 	return (\%driver);

  DS> }

file::slurp and a single regex call is so much cleaner and faster.

use File::Slurp ;

	my %conf = read_file( \*DATA ) =~ m/^(\w+)\s+(.+)$/gm ;

done. use a filename instead of DATA if you want.

uri

-- 
Uri Guttman  ------  uri@stemsystems.com  -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs  ----------------------------  http://jobs.perl.org


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

Date: 13 Oct 2006 17:45:06 +0200
From: Michele Dondi <bik.mido@tiscalinet.it>
Subject: Re: Sorting and moving files to dir for DVD burn
Message-Id: <cmavi2p0gj3hl9a4kntrg4lh7p62nf352q@4ax.com>

On Fri, 13 Oct 2006 08:30:01 -0400, at <"romorris(at)"@bellsouth.net>
wrote:

>>>> use constant QUOTA => 4.7 * 2**30;
>>>>       
>>> Haha! Don't be fooled by the hype. I thought so too. But it turned out
>>> to be 4.7 * 10**3...
>>>     
>>
>> In fact I was the original author of that line myself...
>> ;-P
>>
>>
>> Michele
>>   
>So what does it mean?

What does it mean *what*?

The line in itself is a use of constant.pm to build a (sort of)
constant fixed to a given value, i.e. that describing 4.7 Gb which in
turn *should* be the size of a DVD. Point is it is common in the IT to
have the Kilo-, Mega-, Giga- (and so on) prefixes to refer to 2**10,
2**20, 2**30 (and so on). It all boils down to x=3, y=7 being a good
approximate solution to the equation 5^x=2^y, which of course does not
have integer nontrivial solutions. But so called 4.7 Gb DVDs do not
actually have a size of 4.7 * 2**30 bytes, but 4.7 * 10**3, which
amounts to about 4.37 Gb. Of course it must also be said that for the
SI the usual prefixes must *always* refer to the powers of 10, and it
adopted alternative ones for binary quantities. Notwithstanding this
the common and virtually standard acceptation in CS is the traditional
one, although storage media producers occasionally take advantage of
the other one, as with DVDs, mostly for marketing reasons, one has to
infer...


Michele
-- 
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
 .'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,


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

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 9844
***************************************


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