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

my (%abs, %ilb); for my $lc ( Sql ( 'select blah blah1 - but just put a list of test va +lues will do' ) ) { my ( $ln, $pos, $key ) = split /\t/, $lc; $abs{ $key } = {}; # just want a hash reference for now } for my $lc ( Sql ( 'select blah blah2 - for testing: test values that +have an intersection with the first set' ) ) { my ( $ln, $pos, $key ) = split /\t/, $lc; $ilb{ $key } = { pos => $pos, abs => defined( $abs{ $key } ) }; # +this hash is about to get used immediately in the unwritten code to f +ollow }
The problem: Data::Dumper reveals at this point that in %ilb none of the abs subvalues are true. Unfortunately the obvious double loop to look for an intersection between the two sets of keys DOES find them at the same point in the code. The data returning from SQL is an irrelevant id followed by a relevant number followed by a relevant id separated by tabs - my own version uses the real SQL but if you are testing to see the problem you;d have to use test data. Any ideas what did I do wrong?

Update: Just one unusual factor to throw in detected so far - the perl version is v5.005__3

TIA, ^M

__________________________________________________________________________________

^M Free your mind!

  • Comment on putting the return value from defined for one hash as the value in another
  • Download Code

Replies are listed 'Best First'.
Re: putting the return value from defined for one hash as the value in another
by Limbic~Region (Chancellor) on Apr 18, 2007 at 21:31 UTC
    Moron,
    I suspect your problem isn't where you think it is. Do you get the expected results when you run:
    #!/usr/bin/perl use strict; use warnings; my (%ilb, %abs); for my $key (qw/foo bar baz/) { $abs{$key} = {}; } for my $key (qw/blah baz asdf/) { $ilb{$key} = {pos => $key, abs => (defined $abs{$key} ? 1 : 0)}; }
    If you do, then the problem is not in your logic but your data.

    Cheers - L~R

      Yes, now I get the 1's appearing - thx that means I can move on with this work. My remaining surprise is that I didn't get a true value without forcing one on it.
      __________________________________________________________________________________

      ^M Free your mind!

      Key to hats: ^I=white ^B=black ^P=yellow ^E=red ^C=green ^M=blue - see Moron's scratchpad for fuller explanation.

Re: putting the return value from defined for one hash as the value in another
by roboticus (Chancellor) on Apr 19, 2007 at 11:50 UTC
    Moron:

    This isn't an answer to your question, just an observation.

    Looking at the code you have, you might make things a bit simpler if you let the database do more of the work. All databases (that I'm familiar with) allow you to do a left join, so you can return all your data in one SQL statement, rather than two. Something like:

    SELECT L.key, L.blah1, R.key, R.blah2 FROM FirstTable AS L LEFT JOIN SecondTable AS R ON R.key = L.key
    Then you can read the result, placing all items in %abs, and also placing them into %ilb if the R.key column happens to be null--or more simply, not equal to L.key.

    ...roboticus

      You are right of course, but the last time I tried that I found a 1000 or so times performance improvement by doing the join in Perl instead of the database. Oracle seems to be particularly slow at outer joins.
      __________________________________________________________________________________

      ^M Free your mind!