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

INPUT: List1: //depot/asic/tools/perl/scripts/examples/modem.c#7

//depot/asic/tools/perl/files/examples/file.txt#2

//depot/asic/tools/perl/proc/examples/apps.c#14

List2: //depot/asic/tools/perl/scripts/examples/modem.c#6

//depot/asic/tools/perl/files/examples/file.txt#2

//depot/asic/tools/perl/proc/examples/apps.c#12

OUTPUT: Picking File2 overwrites

//depot/asic/tools/perl/scripts/examples/modem.c#7-> 6

//depot/asic/tools/perl/proc/examples/apps.c#14->12

1.What's wrong with the below code.I am getting the below error.Basically I want to print all the lower version filepaths in list2 compared to list1

syntax error at orphan_overwrite.pl line 25, near "}{" syntax error at orphan_overwrite.pl line 35, near "}" Execution of orphan_overwrite.pl aborted due to compilation errors.

2.Is the if condition"if ($2 < pathname_versions{$1}{$2} )" valid?Does pathname_versions{$1}{$2} give the version value in List1 ?How do I access the value for the matched path in list1 and compare?

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; @ARGV == 2 and -f $ARGV[0] or die "Usage: $0 list1 list2\n"; my ( $list1, $list2 ) = @ARGV; my %pathname_versions; open( IN, $list1 ) or die "$list1: $!"; while (<IN>) { next unless ( m:(.+?)#(\d+)$: ); $pathname_versions{$1}{$2} = undef; } print Dumper( \%pathname_versions ); open( IN, $list2 ) or die "$list2: $!"; while (<IN>) { next unless ( m:(.+?)#(\d+)$: ); #print "\nLIST 2:$1 $2"; if ( exists( $pathname_versions{$1} )) { if ($2 < pathname_versions{$1}{$2} ) {#if the version in list2 + is less than version for the same path in list1 print "$1 pathname_versions{$1}{2}->$2"; } if ( exists( $pathname_versions{$1}{$2} )) { # we have a match on version# as well, so... } else { # version number wasn't seen in list1, so... } } }

Replies are listed 'Best First'.
Re: If condition failing..
by graff (Chancellor) on Dec 13, 2010 at 05:28 UTC
    From the OP:
    Is the if condition if ($2 < pathname_versions{$1}{$2} ) valid?

    No. It should be "$pathname_versions{$1}{$2}" -- note the "$", which is missing from your code. Without that "sigil", perl has to treat "pathname_version" as a function name, but you can't have "{" after (or as part of) a function name.

    From one of the sub-replies:

    What is the use of undef here? $pathname_versions{$1}{$2} = undef;

    That's just an economical assignment statement; by assigning "undef" as the value of a hash element, no memory is allocated to store the value, but the hash key is made to exist.

    How do I do a hash look up for the hash pathname_versions to see if $2(version in the second list) is less than the version in the list 1?

    Based on your earlier posts, I assume that each input list could have 2 or more entries with the same path/name and different version numbers, so it's still not clear to me what particular task you are trying to accomplish with your code,

    You never have said what your real purpose is for the scripts you're trying to write, and I'm getting the impression that you haven't completely worked that out yet. It's hard to write effective code when you aren't sure what it's supposed to do. Anyway, here's a version that shows how to handle cases that involve comparing version numbers, assuming that list1 might contain several versions for a given path:

    ... open( IN, $list2 ) or die "$list2: $!"; while (<IN>) { next unless ( m:(.+?)#(\d+)$: ); my ( $p, $v ) = ( $1, $2 ); next unless ( exists( $pathname_versions{$p} )); if ( exists( $pathname_versions{$p}{$v} )) { # get here if we have a full match (path and version) } else { # create a sorted list of version numbers from list1: my @list1versions = sort {$a<=>$b} keys %{$pathname_versions{$ +p}}; if ( $v < $list1versions[0] ) { # list2 version number is lower than _all_ matching list1 +entries } elsif ( $v > $list1versions[-1] ) { # list2 version number is higher than _all_ matching list1 + entries } } }
    Note how I use indentation to indicate code block nesting for the "if" conditions. Proper indentation is very important for legibility.
Re: If condition failing..
by Anonyrnous Monk (Hermit) on Dec 13, 2010 at 00:05 UTC

      1.What is the use of undef here?

      $pathname_versions{$1}{$2} = undef;

      2.How do I do a hash look up for the hash pathname_versions to see if $2(version in the second list) is less than the version in the list 1?

        I didn't follow the discussion in the original thread, so maybe I'm missing something... but why don't you store the version as the value of the hash entries?

        while (<IN>) { # first list next unless ( m:(.+?)#(\d+)$: ); $pathname_versions{$1} = $2; }

        In this case you could later simply do (where $pathname_versions{$1} retrieves the corresponding version from the first list)

        while (<IN>) { # second list next unless ( m:(.+?)#(\d+)$: ); ... if ( $pathname_versions{$1} < $2 ) { ...