Loading ...
Sorry, an error occurred while loading the content.

Re: [PBML] Re: Hashes with Multiple Values per Key

Expand Messages
  • Charles K. Clarkson
    b_harnish ... Spooky, Isn t it? ... I m not certain, but I think it has to do with the way for (and foreach ) handle lvalues.
    Message 1 of 3 , Feb 2, 2002
    • 0 Attachment
      "b_harnish" <bharnish@...>

      : --- In perl-beginner@y..., "Charles K. Clarkson" <cclarkson@h...>
      : wrote:
      : <snip>
      : > $_ = [ $_->[0] || $. , ++$_->[1] ] for $lines{ length $_ };
      : >
      : > is a shorter, more obscure, way to write:
      : >
      : > $lines{ length $_ } = [
      : > $lines{ length $_ } ->[0] || $. ,
      : > ++$lines{ length $_ } ->[1] ];
      : >
      : > that calls length only once.
      : >
      : > Charles.
      :
      : Wow, I never thought that would work. It challenged my views of
      : reality ;-).

      Spooky, Isn't it?

      : I always figured (but never tried), that the for statement
      : wouldn't do anything, because there was no key by that name. I
      : was wrong. If I understand this correctly, a key actually gets
      : created with an undef value, then that is passed in $_. And
      : whatever $_ returns with, get placed back into the hash?
      : my %x; for($x{1}){};
      : Since I didn't modify $_, it gets put back in as undef. Why does
      : this happen in a 'for' and not an 'if'?
      : if($x{1}) {};

      I'm not certain, but I think it has to do with the way 'for'
      (and 'foreach') handle lvalues. According to perlsyn:

      "If any element of LIST is an lvalue, you can modify it by
      modifying VAR inside the loop. That's because the foreach
      loop index variable is an implicit alias for each item in
      the list that you're looping over."

      When we write:

      my %hash;
      for ( $hash{1} ) { }

      for creates an alias ( $_ ) for all the list items that are
      lvalues ( in this case $hash{1} ). This aliasing autovivifies
      $hash{1}, assigning it undef.

      'if ( $hash{1} ) { ' doesn't autovivfy.

      I originally didn't think this:

      $_ = [ $_->[0] || $. , ++$_->[1] ] for $lines{ length $_ };

      would work either and I tested a few times to be certain.
      I figured perl wouldn't localize the second $_ and complain
      about 2 of them.
      Of course, when I got to this point I realized I had obcured
      what was happening. I'm sure if I look at this again in a few
      months, it will take a while to grasp what it is doing.


      HTH,
      Charles K. Clarkson
      Clarkson Energy Homes, Inc.
      254 968-8328


      Reality is that which, when you stop believing in it, doesn't go away.
      - Philip K. Dick
    Your message has been successfully submitted and would be delivered to recipients shortly.