[23564] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 5772 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sun Nov 9 21:10:42 2003

Date: Sun, 9 Nov 2003 18:10:12 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Sun, 9 Nov 2003     Volume: 10 Number: 5772

Today's topics:
        Perl HASH problem <sg47@cse.buffalo.edu>
    Re: Perl HASH problem <jwillmore@remove.adelphia.net>
    Re: Perl HASH problem <invalid-email@rochester.rr.com>
    Re: Perl HASH problem <sg47@cse.buffalo.edu>
    Re: Perl HASH problem <sg47@cse.buffalo.edu>
    Re: Perl HASH problem <sg47@cse.buffalo.edu>
    Re: Perl HASH problem <invalid-email@rochester.rr.com>
    Re: Perl HASH problem <usenet@morrow.me.uk>
    Re: Perl HASH problem <invalid-email@rochester.rr.com>
    Re: Perl HASH problem <usenet@morrow.me.uk>
    Re: Perl HASH problem <sg47@cse.buffalo.edu>
    Re: Perl HASH problem <jwillmore@remove.adelphia.net>
    Re: Perl HASH problem <sg47@cse.buffalo.edu>
    Re: Perl HASH problem <usenet@morrow.me.uk>
    Re: Perl HASH problem <sg47@cse.buffalo.edu>
    Re: Perl HASH problem <invalid-email@rochester.rr.com>
    Re: Split problem. <krahnj@acm.org>
    Re: Style question: map versus foreach <usenet@morrow.me.uk>
    Re: Style question: map versus foreach <dmcbride@naboo.to.org.no.spam.for.me>
    Re: Style question: map versus foreach <abigail@abigail.nl>
    Re: Style question: map versus foreach <abigail@abigail.nl>
    Re: Subnet / Subnet Mask ---> IP calculation <krahnj@acm.org>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: Sun, 09 Nov 2003 16:59:21 -0500
From: Shripathi Guruprasannaraj <sg47@cse.buffalo.edu>
Subject: Perl HASH problem
Message-Id: <3FAEB8B9.4000604@cse.buffalo.edu>

Hi,

   The function am trying to write reads strings from a file. The file's 
contents are numbers like 00101201. I am inserting them into a hashtable 
removing the duplicates. I then write the keys into a file. The output 
file contains a HASH(0x1169e4) string but the other keys are written 
properly. I guess its actually a reference but I dont know how to 
eliminate it. I am giving the code sample below.

   foreach $line (@filecontents) {

     ($key,$value) = split(" ",$line);
     if($key =~ m/^$year/) {
     if (! defined($nodes{"$key"})) {
       $nodes{"$key"} = 1;
     }
   }
   }

   @keys = keys %nodes;
   foreach(@keys) {
     print outputfile "\n$_";
   }


Please give me some suggestions and also why its happening.

Thanks,

Raj



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

Date: Sun, 09 Nov 2003 22:36:15 GMT
From: James Willmore <jwillmore@remove.adelphia.net>
Subject: Re: Perl HASH problem
Message-Id: <20031109173501.7811a425.jwillmore@remove.adelphia.net>

On Sun, 09 Nov 2003 16:59:21 -0500
Shripathi Guruprasannaraj <sg47@cse.buffalo.edu> wrote:

> Hi,
> 
>    The function am trying to write reads strings from a file. The
>    file's 
> contents are numbers like 00101201. I am inserting them into a
> hashtable removing the duplicates. I then write the keys into a
> file. The output file contains a HASH(0x1169e4) string but the other
> keys are written properly. I guess its actually a reference but I
> dont know how to eliminate it. I am giving the code sample below.
> 
>    foreach $line (@filecontents) {
> 
>      ($key,$value) = split(" ",$line);
>      if($key =~ m/^$year/) {
>      if (! defined($nodes{"$key"})) {
>        $nodes{"$key"} = 1;
>      }
>    }
>    }

	foreach my $line(@filecontents){
		my($key, $value) = split(" ", $line);
		$nodes{"$key"}++ if($key =~ /$year/);
	}

This does two things:
1) matches the regular expression
2) increments the $key value of the nodes (since it appears you don't
care/want the $value).

You don't need 'm' for the regular expression usless you're going to
extract something from the match.

OTOH, if you *are* trying to do a match, then

       $nodes{"$key"} = 1;

should be
       $nodes{"$key"} = "$1";

HTH

-- 
Jim

Copyright notice: all code written by the author in this post is
 released under the GPL. http://www.gnu.org/licenses/gpl.txt 
for more information.

a fortune quote ...
I can't understand why a person will take a year or two to write 
a novel when he can easily buy one for a few dollars.   -- Fred
<Allen 


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

Date: Sun, 09 Nov 2003 22:37:02 GMT
From: Bob Walton <invalid-email@rochester.rr.com>
Subject: Re: Perl HASH problem
Message-Id: <3FAEC164.3010606@rochester.rr.com>

Shripathi Guruprasannaraj wrote:

 ...

>   The function am trying to write reads strings from a file. The file's 
> contents are numbers like 00101201. I am inserting them into a hashtable 
> removing the duplicates. I then write the keys into a file. The output 
> file contains a HASH(0x1169e4) string but the other keys are written 
> properly. I guess its actually a reference but I dont know how to 
> eliminate it. I am giving the code sample below.


I don't get a line with a stringified hash reference (the HASH(0x...) 
above) when I run your code below.  But, since you asked for suggestions...


> 


You are missing:

    use strict;
    use warnings;

unless you just didn't show them.  But then you'd need some "my" statements.


>   foreach $line (@filecontents) {
> 
>     ($key,$value) = split(" ",$line);


Given data like you say you have, split won't have anything to split on, 
so the while line will end up in $key.  So why the split?  You're not 
using it in place of chomp to remove the trailing newline, are you?


>     if($key =~ m/^$year/) {
>     if (! defined($nodes{"$key"})) {

------------^^^^^^^
---------------------------^----^
Here you probably want exists rather than defined.  But why bother with 
the test at all?  The only thing you are setting the hash values to is 
1, and if you set a key's value to 1 more than once, so what?  Also, you 
have a useless use of a double-quoted string, which is bad style.


Also, your indenting style, or lack thereof, makes it hard 

to follow your if statements and loop.

>       $nodes{"$key"} = 1;

---------------^----^
Ditto on the useless use of a double-quoted string.

Also, note that your whole loop could be replaced with:

     @nodes{@filecontents}=1;

since split() isn't doing anything.


>     }
>   }
>   }
> 
>   @keys = keys %nodes;
>   foreach(@keys) {
>     print outputfile "\n$_";

------------------------^^^^
Are you sure you want the newline and your data in this order?  You will 
get an initial blank line.  Also, it is widely accepted style to use 
UPPERCASE for filehandles -- that avoids the potential to use reserved 
words (possibly in future versions of Perl -- no one knows what they 
will be, except they will not be uppercase) for filehandles.  Also, you 
could use:

     print OUTPUTFILE join "\n",keys %nodes;

and made quicker work of it.  If the hash were huge, though, you would want:

     while(($keys,$values)=each(%nodes)){
        print OUTPUTFILE "$keys\n";
     }

although I guess it isn't, since you input your whole file into an array 
in the first place.


>   }
> 
> 
> Please give me some suggestions and also why its happening.
 ...


> Raj

-- 
Bob Walton
Email: http://bwalton.com/cgi-bin/emailbob.pl



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

Date: Sun, 9 Nov 2003 17:47:44 -0500
From: Shripathi Guruprasannaraj <sg47@cse.buffalo.edu>
Subject: Re: Perl HASH problem
Message-Id: <Pine.SOL.4.56.0311091747090.9179@sol.cse.Buffalo.EDU>





On Sun, 9 Nov 2003, Shripathi Guruprasannaraj wrote:

>
>
>
>
> On Sun, 9 Nov 2003, Bob Walton wrote:
>
> > Shripathi Guruprasannaraj wrote:
> >
> > ...
> >
> > >   The function am trying to write reads strings from a file. The file's
> > > contents are numbers like 00101201. I am inserting them into a hashtable
> > > removing the duplicates. I then write the keys into a file. The output
> > > file contains a HASH(0x1169e4) string but the other keys are written
> > > properly. I guess its actually a reference but I dont know how to
> > > eliminate it. I am giving the code sample below.
> >
> >
> > I don't get a line with a stringified hash reference (the HASH(0x...)
> > above) when I run your code below.  But, since you asked for suggestions...
> >
> >
> > >
> >
> >
> > You are missing:
> >
> >     use strict;
> >     use warnings;
> >
> > unless you just didn't show them.  But then you'd need some "my" statements.
> >
> >
> > >   foreach $line (@filecontents) {
> > >
> > >     ($key,$value) = split(" ",$line);
> >
> >
> > Given data like you say you have, split won't have anything to split on,
> > so the while line will end up in $key.  So why the split?  You're not
> > using it in place of chomp to remove the trailing newline, are you?
> >
> >
> > >     if($key =~ m/^$year/) {
> > >     if (! defined($nodes{"$key"})) {
> >
> > ------------^^^^^^^
> > ---------------------------^----^
> > Here you probably want exists rather than defined.  But why bother with
> > the test at all?  The only thing you are setting the hash values to is
> > 1, and if you set a key's value to 1 more than once, so what?  Also, you
> > have a useless use of a double-quoted string, which is bad style.
> >
> >
> > Also, your indenting style, or lack thereof, makes it hard
> >
> > to follow your if statements and loop.
> >
> > >       $nodes{"$key"} = 1;
> >
> > ---------------^----^
> > Ditto on the useless use of a double-quoted string.
> >
> > Also, note that your whole loop could be replaced with:
> >
> >      @nodes{@filecontents}=1;
> >
> > since split() isn't doing anything.
> >
> >
> > >     }
> > >   }
> > >   }
> > >
> > >   @keys = keys %nodes;
> > >   foreach(@keys) {
> > >     print outputfile "\n$_";
> >
> > ------------------------^^^^
> > Are you sure you want the newline and your data in this order?  You will
> > get an initial blank line.  Also, it is widely accepted style to use
> > UPPERCASE for filehandles -- that avoids the potential to use reserved
> > words (possibly in future versions of Perl -- no one knows what they
> > will be, except they will not be uppercase) for filehandles.  Also, you
> > could use:
> >
> >      print OUTPUTFILE join "\n",keys %nodes;
> >
> > and made quicker work of it.  If the hash were huge, though, you would want:
> >
> >      while(($keys,$values)=each(%nodes)){
> >         print OUTPUTFILE "$keys\n";
> >      }
> >
> > although I guess it isn't, since you input your whole file into an array
> > in the first place.
> >
> >
> > >   }
> > >
> > >
> > > Please give me some suggestions and also why its happening.
> > ...
> >
> >
> > > Raj
> >
> > --
> > Bob Walton
> > Email: http://bwalton.com/cgi-bin/emailbob.pl
> >
> >
>
>
> Hi,
>
>   I understand that my Perl code looks bad. I have been trying to work on
> it for a while but since am mostly just processing text, I use Perl
> fleetingly. Anyway I am attaching a sample input file. Actually I dint
> have the double-quotes over the keys before. I thought it would make a
> difference. It dint and I dint bother to change it before sending it
> across. I am trying to get only unique keys into the hash table. The value
> is just a dummy value. In the data file am sending, the first column is
> the same. But in the actual file, it increases. The file is actually a
> citation graph with the first column indicating the id of the paper that
> cites a paper and the second column indicating the id of the paper its
> citing to. I am trying to get the unique ids in the first column.
>
>
> Raj
>


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

Date: Sun, 09 Nov 2003 17:49:36 -0500
From: Shripathi Guruprasannaraj <sg47@cse.buffalo.edu>
Subject: Re: Perl HASH problem
Message-Id: <3FAEC480.4020402@cse.buffalo.edu>

I forgot to attach the sample input file

Shripathi Guruprasannaraj wrote:
> 
> 
> 
> On Sun, 9 Nov 2003, Shripathi Guruprasannaraj wrote:
> 
> 
>>
>>
>>
>>On Sun, 9 Nov 2003, Bob Walton wrote:
>>
>>
>>>Shripathi Guruprasannaraj wrote:
>>>
>>>...
>>>
>>>
>>>>  The function am trying to write reads strings from a file. The file's
>>>>contents are numbers like 00101201. I am inserting them into a hashtable
>>>>removing the duplicates. I then write the keys into a file. The output
>>>>file contains a HASH(0x1169e4) string but the other keys are written
>>>>properly. I guess its actually a reference but I dont know how to
>>>>eliminate it. I am giving the code sample below.
>>>
>>>
>>>I don't get a line with a stringified hash reference (the HASH(0x...)
>>>above) when I run your code below.  But, since you asked for suggestions...
>>>
>>>
>>>
>>>
>>>You are missing:
>>>
>>>    use strict;
>>>    use warnings;
>>>
>>>unless you just didn't show them.  But then you'd need some "my" statements.
>>>
>>>
>>>
>>>>  foreach $line (@filecontents) {
>>>>
>>>>    ($key,$value) = split(" ",$line);
>>>
>>>
>>>Given data like you say you have, split won't have anything to split on,
>>>so the while line will end up in $key.  So why the split?  You're not
>>>using it in place of chomp to remove the trailing newline, are you?
>>>
>>>
>>>
>>>>    if($key =~ m/^$year/) {
>>>>    if (! defined($nodes{"$key"})) {
>>>
>>>------------^^^^^^^
>>>---------------------------^----^
>>>Here you probably want exists rather than defined.  But why bother with
>>>the test at all?  The only thing you are setting the hash values to is
>>>1, and if you set a key's value to 1 more than once, so what?  Also, you
>>>have a useless use of a double-quoted string, which is bad style.
>>>
>>>
>>>Also, your indenting style, or lack thereof, makes it hard
>>>
>>>to follow your if statements and loop.
>>>
>>>
>>>>      $nodes{"$key"} = 1;
>>>
>>>---------------^----^
>>>Ditto on the useless use of a double-quoted string.
>>>
>>>Also, note that your whole loop could be replaced with:
>>>
>>>     @nodes{@filecontents}=1;
>>>
>>>since split() isn't doing anything.
>>>
>>>
>>>
>>>>    }
>>>>  }
>>>>  }
>>>>
>>>>  @keys = keys %nodes;
>>>>  foreach(@keys) {
>>>>    print outputfile "\n$_";
>>>
>>>------------------------^^^^
>>>Are you sure you want the newline and your data in this order?  You will
>>>get an initial blank line.  Also, it is widely accepted style to use
>>>UPPERCASE for filehandles -- that avoids the potential to use reserved
>>>words (possibly in future versions of Perl -- no one knows what they
>>>will be, except they will not be uppercase) for filehandles.  Also, you
>>>could use:
>>>
>>>     print OUTPUTFILE join "\n",keys %nodes;
>>>
>>>and made quicker work of it.  If the hash were huge, though, you would want:
>>>
>>>     while(($keys,$values)=each(%nodes)){
>>>        print OUTPUTFILE "$keys\n";
>>>     }
>>>
>>>although I guess it isn't, since you input your whole file into an array
>>>in the first place.
>>>
>>>
>>>
>>>>  }
>>>>
>>>>
>>>>Please give me some suggestions and also why its happening.
>>>
>>>...
>>>
>>>
>>>
>>>>Raj
>>>
>>>--
>>>Bob Walton
>>>Email: http://bwalton.com/cgi-bin/emailbob.pl
>>>
>>>
>>
>>
>>Hi,
>>
>>  I understand that my Perl code looks bad. I have been trying to work on
>>it for a while but since am mostly just processing text, I use Perl
>>fleetingly. Anyway I am attaching a sample input file. Actually I dint
>>have the double-quotes over the keys before. I thought it would make a
>>difference. It dint and I dint bother to change it before sending it
>>across. I am trying to get only unique keys into the hash table. The value
>>is just a dummy value. In the data file am sending, the first column is
>>the same. But in the actual file, it increases. The file is actually a
>>citation graph with the first column indicating the id of the paper that
>>cites a paper and the second column indicating the id of the paper its
>>citing to. I am trying to get the unique ids in the first column.
>>
>>
>>Raj
>>
> 



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

Date: Sun, 09 Nov 2003 18:00:18 -0500
From: Shripathi Guruprasannaraj <sg47@cse.buffalo.edu>
Subject: Re: Perl HASH problem
Message-Id: <3FAEC702.8010507@cse.buffalo.edu>



Shripathi Guruprasannaraj wrote:
> Hi,
> 
>   The function am trying to write reads strings from a file. The file's 
> contents are numbers like 00101201. I am inserting them into a hashtable 
> removing the duplicates. I then write the keys into a file. The output 
> file contains a HASH(0x1169e4) string but the other keys are written 
> properly. I guess its actually a reference but I dont know how to 
> eliminate it. I am giving the code sample below.
> 
>   foreach $line (@filecontents) {
> 
>     ($key,$value) = split(" ",$line);
>     if($key =~ m/^$year/) {
>     if (! defined($nodes{"$key"})) {
>       $nodes{"$key"} = 1;
>     }
>   }
>   }
> 
>   @keys = keys %nodes;
>   foreach(@keys) {
>     print outputfile "\n$_";
>   }
> 
> 
> Please give me some suggestions and also why its happening.
> 
> Thanks,
> 
> Raj


Following Some of your suggestions , I made the changes to my code. Let 
me know if I can improvise further.

#!/usr/bin/perl

use strict;
use warnings;


my $year = shift @ARGV;
my $file = shift @ARGV;
getNodes($year,$file);

sub getNodes() {

  my  $year = shift;
   my $file = shift;

   open(FILEHANDLE,"citationgraph") or die "Cannot open file $!\n";
   open(OUTPUTFILE, ">$file") or die "Cannot open file $!\n";

   my @filecontents = <FILEHANDLE>;
   my %nodes = {};

   foreach my $line (@filecontents) {

     my ($key,$value) = split(" ",$line);
     if($key =~ m/^$year/) {
       $key =~ s/\s+$//;
       if (! defined($nodes{$key})) {
	$nodes{$key} = 1;
       }
   }
   }

   my @keys = keys %nodes;
   foreach(@keys) {
     print OUTPUTFILE "\n$_";
   }

}


> 



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

Date: Sun, 09 Nov 2003 23:06:36 GMT
From: Bob Walton <invalid-email@rochester.rr.com>
Subject: Re: Perl HASH problem
Message-Id: <3FAEC851.5090904@rochester.rr.com>

Shripathi Guruprasannaraj wrote:

> I forgot to attach the sample input file

Looks like you forget to attach it again.  You might have better luck if 
you just copy/pasted it in -- hopefully just a few representative lines 
of it.  And while you're at it, put it with your program so the whole 
thing can be copy/pasted/executed by anyone, something along the lines of:

#!/usr/bin/perl
use strict;
use warnings;
my @data=<DATA>;
chomp @data;
#do stuff with @data
print join "\n",@data;
__END__
data line1
data line2
data line3

and make sure the combo demonstrates the problem you are having when one 
copy/paste/executes it.  Thanks!
-- 
Bob Walton
Email: http://bwalton.com/cgi-bin/emailbob.pl



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

Date: Sun, 9 Nov 2003 23:08:40 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Perl HASH problem
Message-Id: <bomhdo$i12$2@wisteria.csv.warwick.ac.uk>


James Willmore <jwillmore@remove.adelphia.net> wrote:
> You don't need 'm' for the regular expression usless you're going to
> extract something from the match.
> 
> OTOH, if you *are* trying to do a match, then
> 
>        $nodes{"$key"} = 1;
> 
> should be
>        $nodes{"$key"} = "$1";

What?! This is complete nonsense.

You may omit the 'm' on a m// match if and only if the delimiter you
use is '/'; i.e. 'm|\d|' needs the 'm' but 'm/\d/' could have been
simply written '/\d/'. There is otherwise no significance to it.

$1 refers to what the first bracketed subexpression of the last
*successful* pattern match matched. So

$_ = "ab";
/(a)/;    # Now $1 eq 'a'.
/(c)/;    # $1 eq 'a' still, as the pattern didn't match.
/b/;      # $1 is undef, as the pattern matched but didn't have any
          # capturing parentheses.

Please don't talk rubbish.

Ben

-- 
I've seen things you people wouldn't believe: attack ships on fire off the
shoulder of Orion; I've watched C-beams glitter in the darkness near the
Tannhauser Gate. All these moments will be lost, in time, like tears in rain.
Time to die.  |-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-|  ben@morrow.me.uk


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

Date: Sun, 09 Nov 2003 23:24:45 GMT
From: Bob Walton <invalid-email@rochester.rr.com>
Subject: Re: Perl HASH problem
Message-Id: <3FAECC92.8040104@rochester.rr.com>

Shripathi Guruprasannaraj wrote:

> 
> 
> Shripathi Guruprasannaraj wrote:
> 
 ...
> 
> Following Some of your suggestions , I made the changes to my code. Let 
> me know if I can improvise further.
> 
> #!/usr/bin/perl
> 
> use strict;
> use warnings;
> 
> 
> my $year = shift @ARGV;
> my $file = shift @ARGV;
> getNodes($year,$file);
> 
> sub getNodes() {

--------------^^
Are you sure this is the prototype you want for you sub?  It doesn't 
seem to go along with the actual usage you are making.  Or perhaps you 
inadvertently places the parens there, not realizing you were defining a 
prototype for you sub by so doing?


> 
>  my  $year = shift;
>   my $file = shift;
> 
>   open(FILEHANDLE,"citationgraph") or die "Cannot open file $!\n";
>   open(OUTPUTFILE, ">$file") or die "Cannot open file $!\n";
> 
>   my @filecontents = <FILEHANDLE>;
>   my %nodes = {};

-------^^^^^^^^^^^
AHA!  This is where your stringified hash reference is coming from. The 
RHS of the above defines a scalar value which is a reference to an empty 
anonymous hash.  The LHS is a hash, so the assignment operator is 
expecting a list with an even number of elements.  Perl attempts to 
DWYM, and so sets up a key in %nodes which is the stringified hash 
reference, and an undef value.  Which, of course, is not WYM.

But the

    use warnings;

above caused Perl to mention that.  Did you not pay attention?  If you 
didn't understand the warning, add:

    use diagnostics;

to your program, which will generate a paragraph of explanation for each 
warning you receive.

What should you do?  Either:

     my %nodes;

or

     my %nodes=();


> 
>   foreach my $line (@filecontents) {
> 
>     my ($key,$value) = split(" ",$line);
>     if($key =~ m/^$year/) {
>       $key =~ s/\s+$//;
>       if (! defined($nodes{$key})) {
>     $nodes{$key} = 1;
>       }
>   }
>   }
> 
>   my @keys = keys %nodes;
>   foreach(@keys) {
>     print OUTPUTFILE "\n$_";
>   }
> 
> }
> 
> 
>>
> 



-- 
Bob Walton
Email: http://bwalton.com/cgi-bin/emailbob.pl



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

Date: Sun, 9 Nov 2003 23:28:24 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Perl HASH problem
Message-Id: <bomiio$iuq$1@wisteria.csv.warwick.ac.uk>

sg47@cse.buffalo.edu wrote:
> Following Some of your suggestions , I made the changes to my code. Let 
> me know if I can improvise further.

I think you mean 'improve'... :)[1]

> #!/usr/bin/perl
> 
> use strict;
> use warnings;
> 
> my $year = shift @ARGV;
> my $file = shift @ARGV;

It is usual to omit the @ARGV here, as Perl will assume it.

> getNodes($year,$file);

If you declare the sub at the top with
  use subs qw/getNodes/;
then you can call it without brackets, viz:
  getNodes $year, $file;
which is cleaner.

> sub getNodes() {

You do not want the () there. They do not mean what you think they
mean.

>   my  $year = shift;
>    my $file = shift;
> 
>    open(FILEHANDLE,"citationgraph") or die "Cannot open file $!\n";

You checked the return of open(): good :).  

You would be better off with a more descriptive name than FILEHADLE.

You should also not append "\n" to die() messages, in general, as it
prevents Perl from telling you where the error occurred.

You would also be better off using a 'my' variable for the filehandle,
viz:

   open my $GRAPH, "< citationgraph" 
        or die "Cannot open 'citationgraph': $!";

>    open(OUTPUTFILE, ">$file") or die "Cannot open file $!\n";
> 
>    my @filecontents = <FILEHANDLE>;
>    my %nodes = {};
> 
>    foreach my $line (@filecontents) {
> 
>      my ($key,$value) = split(" ",$line);
>      if($key =~ m/^$year/) {
>        $key =~ s/\s+$//;

The split on " " will remove all whitespace for you.

>        if (! defined($nodes{$key})) {

As someone else pointed out, you do not need this test.

> 	$nodes{$key} = 1;
>        }
>    }
>    }

You still need to sort out your indenting. Get an editor which does it
for you (see perldoc -q editor).

>    my @keys = keys %nodes;
>    foreach(@keys) {
>      print OUTPUTFILE "\n$_";

You can get rid of the need for "\n" by putting
  $\ = "\n";
at the top; this whole loop can then be written
  print for keys %nodes;
which is rather clearer.

>    }
> 
> }

Ben

[1] In case anyone should get the wrong idea: I in no way wish to
criticise people with poor English, and I appreciate the effort made
to write a language which is not your own. I seek only to help you
make yourself understood better :).

-- 
Musica Dei donum optimi, trahit homines, trahit deos.    |
Musica truces molit animos, tristesque mentes erigit.    |   ben@morrow.me.uk
Musica vel ipsas arbores et horridas movet feras.        |


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

Date: Sun, 9 Nov 2003 18:30:57 -0500
From: Shripathi Guruprasannaraj <sg47@cse.buffalo.edu>
Subject: Re: Perl HASH problem
Message-Id: <Pine.SOL.4.56.0311091830190.10156@sol.cse.Buffalo.EDU>

Hi Bob,

 Thanks a lot for helping me out. There is a blank line as the first line
of my output file. Do you know whats causing that ?

Raj



On Sun, 9 Nov 2003, Bob Walton wrote:

> Shripathi Guruprasannaraj wrote:
>
> >
> >
> > Shripathi Guruprasannaraj wrote:
> >
> ...
> >
> > Following Some of your suggestions , I made the changes to my code. Let
> > me know if I can improvise further.
> >
> > #!/usr/bin/perl
> >
> > use strict;
> > use warnings;
> >
> >
> > my $year = shift @ARGV;
> > my $file = shift @ARGV;
> > getNodes($year,$file);
> >
> > sub getNodes() {
>
> --------------^^
> Are you sure this is the prototype you want for you sub?  It doesn't
> seem to go along with the actual usage you are making.  Or perhaps you
> inadvertently places the parens there, not realizing you were defining a
> prototype for you sub by so doing?
>
>
> >
> >  my  $year = shift;
> >   my $file = shift;
> >
> >   open(FILEHANDLE,"citationgraph") or die "Cannot open file $!\n";
> >   open(OUTPUTFILE, ">$file") or die "Cannot open file $!\n";
> >
> >   my @filecontents = <FILEHANDLE>;
> >   my %nodes = {};
>
> -------^^^^^^^^^^^
> AHA!  This is where your stringified hash reference is coming from. The
> RHS of the above defines a scalar value which is a reference to an empty
> anonymous hash.  The LHS is a hash, so the assignment operator is
> expecting a list with an even number of elements.  Perl attempts to
> DWYM, and so sets up a key in %nodes which is the stringified hash
> reference, and an undef value.  Which, of course, is not WYM.
>
> But the
>
>     use warnings;
>
> above caused Perl to mention that.  Did you not pay attention?  If you
> didn't understand the warning, add:
>
>     use diagnostics;
>
> to your program, which will generate a paragraph of explanation for each
> warning you receive.
>
> What should you do?  Either:
>
>      my %nodes;
>
> or
>
>      my %nodes=();
>
>
> >
> >   foreach my $line (@filecontents) {
> >
> >     my ($key,$value) = split(" ",$line);
> >     if($key =~ m/^$year/) {
> >       $key =~ s/\s+$//;
> >       if (! defined($nodes{$key})) {
> >     $nodes{$key} = 1;
> >       }
> >   }
> >   }
> >
> >   my @keys = keys %nodes;
> >   foreach(@keys) {
> >     print OUTPUTFILE "\n$_";
> >   }
> >
> > }
> >
> >
> >>
> >
>
>
>
> --
> Bob Walton
> Email: http://bwalton.com/cgi-bin/emailbob.pl
>
>


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

Date: Sun, 09 Nov 2003 23:31:58 GMT
From: James Willmore <jwillmore@remove.adelphia.net>
Subject: Re: Perl HASH problem
Message-Id: <20031109183044.20813601.jwillmore@remove.adelphia.net>

On Sun, 9 Nov 2003 23:08:40 +0000 (UTC)
Ben Morrow <usenet@morrow.me.uk> wrote:
> James Willmore <jwillmore@remove.adelphia.net> wrote:
> > You don't need 'm' for the regular expression usless you're going
> > to extract something from the match.
> > 
> > OTOH, if you *are* trying to do a match, then
> > 
> >        $nodes{"$key"} = 1;
> > 
> > should be
> >        $nodes{"$key"} = "$1";
> 
> What?! This is complete nonsense.
> 
> You may omit the 'm' on a m// match if and only if the delimiter you
> use is '/'; i.e. 'm|\d|' needs the 'm' but 'm/\d/' could have been
> simply written '/\d/'. There is otherwise no significance to it.
> 
> $1 refers to what the first bracketed subexpression of the last
> *successful* pattern match matched. So
> 
> $_ = "ab";
> /(a)/;    # Now $1 eq 'a'.
> /(c)/;    # $1 eq 'a' still, as the pattern didn't match.
> /b/;      # $1 is undef, as the pattern matched but didn't have any
>           # capturing parentheses.

Yes.  You have stated much better than I what I was trying to say. 

Thank you.

-- 
Jim

Copyright notice: all code written by the author in this post is
 released under the GPL. http://www.gnu.org/licenses/gpl.txt 
for more information.

a fortune quote ...
Veni, Vidi, Visa. 



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

Date: Sun, 09 Nov 2003 18:43:27 -0500
From: Shripathi Guruprasannaraj <sg47@cse.buffalo.edu>
Subject: Re: Perl HASH problem
Message-Id: <3FAED11F.8050603@cse.buffalo.edu>



Ben Morrow wrote:
> sg47@cse.buffalo.edu wrote:
> 
>>Following Some of your suggestions , I made the changes to my code. Let 
>>me know if I can improvise further.
> 
> 
> I think you mean 'improve'... :)[1]

=> No I meant improvise.

> 
> 
>>#!/usr/bin/perl
>>
>>use strict;
>>use warnings;
>>
>>my $year = shift @ARGV;
>>my $file = shift @ARGV;
> 
> 
> It is usual to omit the @ARGV here, as Perl will assume it.
> 
> 
>>getNodes($year,$file);
> 
> 
> If you declare the sub at the top with
>   use subs qw/getNodes/;
> then you can call it without brackets, viz:
>   getNodes $year, $file;
> which is cleaner.
> 
> 
>>sub getNodes() {
> 
> 
> You do not want the () there. They do not mean what you think they
> mean.
> 
> 
>>  my  $year = shift;
>>   my $file = shift;
>>
>>   open(FILEHANDLE,"citationgraph") or die "Cannot open file $!\n";
> 
> 
> You checked the return of open(): good :).  
> 
> You would be better off with a more descriptive name than FILEHADLE.
> 
> You should also not append "\n" to die() messages, in general, as it
> prevents Perl from telling you where the error occurred.
> 
> You would also be better off using a 'my' variable for the filehandle,
> viz:
> 
>    open my $GRAPH, "< citationgraph" 
>         or die "Cannot open 'citationgraph': $!";
> 
> 
>>   open(OUTPUTFILE, ">$file") or die "Cannot open file $!\n";
>>
>>   my @filecontents = <FILEHANDLE>;
>>   my %nodes = {};
>>
>>   foreach my $line (@filecontents) {
>>
>>     my ($key,$value) = split(" ",$line);
>>     if($key =~ m/^$year/) {
>>       $key =~ s/\s+$//;
> 
> 
> The split on " " will remove all whitespace for you.
> 
> 
>>       if (! defined($nodes{$key})) {
> 
> 
> As someone else pointed out, you do not need this test.
> 
> 
>>	$nodes{$key} = 1;
>>       }
>>   }
>>   }
> 
> 
> You still need to sort out your indenting. Get an editor which does it
> for you (see perldoc -q editor).
> 
> 
>>   my @keys = keys %nodes;
>>   foreach(@keys) {
>>     print OUTPUTFILE "\n$_";
> 
> 
> You can get rid of the need for "\n" by putting
>   $\ = "\n";
> at the top; this whole loop can then be written
>   print for keys %nodes;
> which is rather clearer.
> 
> 
>>   }
>>
>>}
> 
> 
> Ben
> 
> [1] In case anyone should get the wrong idea: I in no way wish to
> criticise people with poor English, and I appreciate the effort made
> to write a language which is not your own. I seek only to help you
> make yourself understood better :).
> 



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

Date: Mon, 10 Nov 2003 00:18:00 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Perl HASH problem
Message-Id: <bomlfo$kf7$1@wisteria.csv.warwick.ac.uk>


sg47@cse.buffalo.edu wrote:
> Ben Morrow wrote:
> > sg47@cse.buffalo.edu wrote:
> > 
> >>Following Some of your suggestions , I made the changes to my code. Let 
> >>me know if I can improvise further.
> > 
> > I think you mean 'improve'... :)[1]
> 
> => No I meant improvise.

Please explain. 

AFAIK, 'to improve' means 'to make better', which makes sense; 'to
improvise' means 'to play music which you are making up as you go
along', or, from this, 'to make the best you can of a situation where
there are no rules to follow', which doesn't.

> > [1] In case anyone should get the wrong idea: I in no way wish to
> > criticise people with poor English, and I appreciate the effort made
> > to write a language which is not your own. I seek only to help you
> > make yourself understood better :).

Ben

-- 
If I were a butterfly I'd live for a day, / I would be free, just blowing away.
This cruel country has driven me down / Teased me and lied, teased me and lied.
I've only sad stories to tell to this town: / My dreams have withered and died.
  ben@morrow.me.uk   <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>   (Kate Rusby)


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

Date: Sun, 09 Nov 2003 19:31:02 -0500
From: Shripathi Guruprasannaraj <sg47@cse.buffalo.edu>
Subject: Re: Perl HASH problem
Message-Id: <3FAEDC46.4030404@cse.buffalo.edu>



Ben Morrow wrote:
> sg47@cse.buffalo.edu wrote:
> 
>>Ben Morrow wrote:
>>
>>>sg47@cse.buffalo.edu wrote:
>>>
>>>
>>>>Following Some of your suggestions , I made the changes to my code. Let 
>>>>me know if I can improvise further.
>>>
>>>I think you mean 'improve'... :)[1]
>>
>>=> No I meant improvise.
> 
> 
> Please explain. 
> 
> AFAIK, 'to improve' means 'to make better', which makes sense; 'to
> improvise' means 'to play music which you are making up as you go
> along', or, from this, 'to make the best you can of a situation where
> there are no rules to follow', which doesn't.
> 

=>'to make the best you can of a situation where
there are no rules to follow'

  This is a perfect situation in which there are no hard and fast rules 
to follow. By improvise I meant something like writing /\d/ instead of 
m/\d/ . I know this is not a perfect example but I hope you get what I 
am trying to put across.

I could have also said 'improve' which probably fits in better than 
improvise.



> 
>>>[1] In case anyone should get the wrong idea: I in no way wish to
>>>criticise people with poor English, and I appreciate the effort made
>>>to write a language which is not your own. I seek only to help you
>>>make yourself understood better :).
=> I definitely understand that you are helping me out. But FYI, English 
has been my medium of instruction
	since I was 2. I know to read, write , speak English while I can only 
speak my mother-tongue (native language).

> 
> Ben
> 



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

Date: Mon, 10 Nov 2003 00:42:59 GMT
From: Bob Walton <invalid-email@rochester.rr.com>
Subject: Re: Perl HASH problem
Message-Id: <3FAEDEE8.7010009@rochester.rr.com>

Shripathi Guruprasannaraj wrote:

> Hi Bob,
> 
>  Thanks a lot for helping me out. There is a blank line as the first line
> of my output file. Do you know whats causing that ?
> 
> Raj
 ...
>>>    print OUTPUTFILE "\n$_";

Yes.  As I mentioned in my first post, that is because the first thing 
you print is a newline -- hence the first line is blank.  You probably want:

     print OUTPUTFILE "$_\n";

-- 
Bob Walton
Email: http://bwalton.com/cgi-bin/emailbob.pl



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

Date: Sun, 09 Nov 2003 19:29:01 GMT
From: "John W. Krahn" <krahnj@acm.org>
Subject: Re: Split problem.
Message-Id: <3FAE9547.6967492F@acm.org>

Richard S Beckett wrote:
> 
> I have a line of text like this "         5    6       0        7   176
> 0". i.e. 9 spaces before the 5.
> 
> When I try to place the numbers into an array with split (my @temp = split
> (/\s*/, $input);), I get a blank element at the start. What am I doing
> wrong?

Use the match operator to get the data you want instead of using split
to remove the data you don't want.  :-)

my @array = $line =~ /\d/g;

Or if you really want ( 176 ) instead of ( 1, 7, 6 ) then:

my @array = $line =~ /\d+/g;



John
-- 
use Perl;
program
fulfillment


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

Date: Sun, 9 Nov 2003 19:36:46 +0000 (UTC)
From: Ben Morrow <usenet@morrow.me.uk>
Subject: Re: Style question: map versus foreach
Message-Id: <bom50e$d7s$1@wisteria.csv.warwick.ac.uk>


"LaDainian Tomlinson" <go@away.spam> wrote:
> "Abigail" wrote:
> > I'm curious, what made you think that map () in void context was bad
> > practice?
> 
> I guess I don't like discarding return values.  It seems like a bad habit to
> get into.

From 'info gcc':

| Coming as I do from a Lisp background, I balk at the idea that there
| is something dangerous about discarding a value.  There are
| functions that return values which some callers may find useful; it
| makes no sense to clutter the program with a cast to `void' whenever
| the value isn't useful.

*Everything* returns a value[1]: a statement such as

  my $i = 5;

returns $i, which you then discard.

Ben

[1] OK, with a couple of exceptions, such as 'package'...

-- 
Musica Dei donum optimi, trahit homines, trahit deos.    |
Musica truces molit animos, tristesque mentes erigit.    |   ben@morrow.me.uk
Musica vel ipsas arbores et horridas movet feras.        |


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

Date: Sun, 09 Nov 2003 23:14:17 GMT
From: Darin McBride <dmcbride@naboo.to.org.no.spam.for.me>
Subject: Re: Style question: map versus foreach
Message-Id: <dTzrb.355948$6C4.127445@pd7tw1no>

Ben Morrow wrote:

> 
> "LaDainian Tomlinson" <go@away.spam> wrote:
>> "Abigail" wrote:
>> > I'm curious, what made you think that map () in void context was bad
>> > practice?
>> 
>> I guess I don't like discarding return values.  It seems like a bad habit
>> to get into.
> 
> From 'info gcc':
> 
> | Coming as I do from a Lisp background, I balk at the idea that there
> | is something dangerous about discarding a value.  There are
> | functions that return values which some callers may find useful; it
> | makes no sense to clutter the program with a cast to `void' whenever
> | the value isn't useful.

I suppose it all depends on what you're trying to do.  And it depends
on what choices you have.  For example, as long as we're on gcc (which
usually also does C++), using ++i vs i++ can have huge impacts on
speed.  Both return a value, but that value is usually discarded.  So
which one to use?

In Perl, we have the same choice with "use overload" to some degree
(perl is smart enough to do the Right Thing if your increment function
is done right).

If the 'i' object is a heavy type where copying it can be expensive,
then you definitely want to use "++i" because that can then return a
reference to i after the increment is finished.  However, "i++" will
copy itself, increment itself, and then return the copy (by value, not
reference).

Thus, even when discarding a return value, it can be important to use
the right version.  If you're discarding the return from ++, then use
the preincrement - it can be tons faster.  And where it isn't, it can't
be any slower than postincrement.

Similarly with map vs for/foreach.  If you're discarding the return
value from map, then why bother at all?  It's much clearer to use
foreach instead.  And, as reported, foreach is still marginally faster
than map in cases where you ignore the return from map.  Clarity AND
speed - what more can one ask for?

Now, if you're writing another JAPH sig or competing for obsfucated
code, map may make more sense.  But for any code that might need
maintenance, write the code that means what you want it to do.  In this
case, foreach.

I think I use map more than foreach, but that's because I'm constantly
rewriting my arrays, or converting arrays to hashes, or converting
hashes to arrays or other nonsense.  I use the return values.  I figure
that this is probably faster than writing it in foreach, and besides,
that's what I mean to do - completely clear.

> *Everything* returns a value[1]: a statement such as
> 
>   my $i = 5;
> 
> returns $i, which you then discard.

The difference is that this "returns" a single scalar.  Map allocates
and returns an array (or at least, that's the concept).  Big
difference.

> Ben
> 
> [1] OK, with a couple of exceptions, such as 'package'...


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

Date: 10 Nov 2003 00:10:48 GMT
From: Abigail <abigail@abigail.nl>
Subject: Re: Style question: map versus foreach
Message-Id: <slrnbqtls7.lpt.abigail@alexandra.abigail.nl>

LaDainian Tomlinson (go@away.spam) wrote on MMMDCCXXII September MCMXCIII
in <URL:news:Jrvrb.91943$fl1.3981732@twister.southeast.rr.com>:
##  "Abigail" wrote:
## >
## > I'm curious, what made you think that map () in void context was bad
## > practice?
##  
##  I guess I don't like discarding return values.  It seems like a bad habit to
##  get into.  At least in this case, it could have easily been avoided with a
##  solution like Roy's (printing the list returned by grep() or map() rather
##  than printing in the map() itself).

print returns a value, which is discarded in void context..
Assignment returns a value, which is discarded in void context.
s/// returns a value, which is discarded in void context.
pop returns a value, which is discarded in void context.
map returns a value, which is discarded in void context.


Do you think that using any of these five operations in void context is
bad practise? If not, could you indicate why using some operations in
void context is fine, but map in void context is bad practise? Because
I really fail to see what map has done to get this special status.



Abigail
-- 
INIT  {print "Perl "   }
CHECK {print "another "}
BEGIN {print "Just "   }
END   {print "Hacker\n"}


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

Date: 10 Nov 2003 00:19:57 GMT
From: Abigail <abigail@abigail.nl>
Subject: Re: Style question: map versus foreach
Message-Id: <slrnbqtmdd.lpt.abigail@alexandra.abigail.nl>

Darin McBride (dmcbride@naboo.to.org.no.spam.for.me) wrote on MMMDCCXXII
September MCMXCIII in <URL:news:dTzrb.355948$6C4.127445@pd7tw1no>:
""  
""  The difference is that this "returns" a single scalar.  Map allocates
""  and returns an array (or at least, that's the concept).  Big
""  difference.


Wrong. First of all, from the language point of view, what a function
returns is determined by the *CONTEXT*, not the function. As Randal
likes to chant "there are no lists in scalar context". So, a function
in void context (it being a special case of scalar context) simply
*cannot* return a list (arrays are never returned by Perl anyway).

Secondly, the fact than in older versions of Perl map was implemented
inefficiently was a bug in perl, that now is luckely fixed. But it's
pretty lame to call a certain style of Perl programming "bad practise",
just because the implementation was inefficient. But that's no longer
an issue anymore.


Abigail
-- 
perl -wleprint -eqq-@{[ -eqw\\- -eJust -eanother -ePerl -eHacker -e\\-]}-


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

Date: Sun, 09 Nov 2003 20:34:17 GMT
From: "John W. Krahn" <krahnj@acm.org>
Subject: Re: Subnet / Subnet Mask ---> IP calculation
Message-Id: <3FAEA493.E731C739@acm.org>

kielhd wrote:
> 
> I'm looking for a small script which would return all possible IPs
> within a given Subnet and corresponding Subnet Mask.
> ie:     input: Subnet 10.152.186.0, Subnet Mask 255.255.255.192
>         output: 10.152.186.0, 10.152.186.1, 10.152.186.2 ... 10.152.186.63

use Socket;
sub range {
    my ( $sub, $mask ) = map unpack( 'N', inet_aton( $_ ) ), @_;
    map inet_ntoa( pack( 'N', $sub | $_ ) ), $sub & ~$mask .. ~$mask;
    }

print for range( '10.152.186.0', '255.255.255.192' );


John
-- 
use Perl;
program
fulfillment


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

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


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