Alien has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks!

I have the following code :
use strict; use warnings; use Tie::File; my $first = shift || die "first file\n"; my $sec = shift || die "second\n"; tie my @first,'Tie::File',$first or die "tie error $!\n"; tie my @sec ,'Tie::File',$sec or die "tie error $!\n"; my (%h1,%h2,%common); print "processing $first\n"; map { if(/^\s*(\?.*?)\s/) { $h1{$1}++; } } @first; print "processing $sec\n"; map { if(/^\s*(\?.*?)\s/) { $h2{$1}++; } } @sec; print "finding common keys\n"; map { if(exists $h2{$_}) { $common{$_}++; } } keys %h1; print "there are @{[length keys %common]}:\n"; system("pause"); for my $key(keys %common) { print "\n\n\n$key\n\n\n"; } untie @first; untie @sec;

I am using this to find common stuff inside 2 files . My question is :
- if I print length keys %common ,it outputs 3
- if I assign keys %common to an array , it's size is 159 . Why ?

Replies are listed 'Best First'.
Re: what's wrong with this?
by ccn (Vicar) on Oct 24, 2008 at 08:23 UTC

    length returns the length in characters of given argument

    keys in scalar context (your case) returns numner of keys ina hash

    So if your hash has 153 keys than length '153' returns 3 i.e. three characters

    change you code as:

    print "there are @{[scalar keys %common]}:\n";
Re: what's wrong with this?
by jwkrahn (Abbot) on Oct 24, 2008 at 12:53 UTC
    what's wrong with this?

    my $first = shift || die "first file\n"; my $sec = shift || die "second\n";

    The  || operator has higher precedence than the  = operator so you need to either enclose the assignment in parentheses or use the lower precedence  or operator.

    You can accomplish the same result more simply with a single hash:

    #!/usr/bin/perl use strict; use warnings; my $first = shift or die "first file\n"; my $sec = shift or die "second\n"; open my $FIRST, '<', $first or die "$first: $!"; open my $SEC, '<', $sec or die "$sec: $!"; print "processing $first\n"; my %common = map { /^\s*(\?.*?)\s/, 0 } <$FIRST>; print "processing $sec\n"; /^\s*(\?.*?)\s/ and $common{ $1 }++ while <$SEC>; print "finding common keys\n"; delete @common{ grep !$common{ $_ }, keys %common }; print "there are @{[scalar keys %common]}:\n"; system 'pause'; for my $key ( keys %common ) { print "\n\n\n$key\n\n\n"; }
Re: what's wrong with this?
by Alien (Monk) on Oct 24, 2008 at 08:21 UTC
    never mind. I'm stupid :)
      You crashed at Roswell didn't you? :D