Well done Kevin!

Just a couple of points.

Kevin Pfeiffer wrote:
> In article <[EMAIL PROTECTED]>, John W. Krahn wrote:
>
> > Sharad Gupta wrote:
> > >
> > > Hi Friends,
> >
> > Hello,
>
> Hi,
>
> > > I have a hash whose values can be either array, hash  etc.
> > >
> > > say i have:
> > >
> > > my $self = {
> > >     'hello how' => {
> > >         'r u' => 'I am',
> > >         ....
> > >         ....
> > >         },
> > >     'fine thank' => ['you'],
> > >     'see ya'        => 'next time',
> > >     ....
> > >     ....
> > >     };
> > >
> > > How can i replace the spaces in keys with '_' without copying
> > > $self to some other place.?
> >
> > You can't modify the keys once they are created.  You would have
> > to create a new key and copy the value to the new key.
>
> (I noticed that, too.) But thanks to your tip I think I've created
> my first recursive sub-routine (only tested on this example). If it
> does what the OP requested (and y'all don't find too much wrong
> with it) then I'm a happy man!
>
>
> pad_keys($self);
> print Dumper(\$self);
>
> sub pad_keys {
>    my $ref = shift;
>    if (ref $ref eq "HASH") {
>       for my $value (%$ref) {

This will loop over all the keys and values in the
hash, in the order key1, value1, key2, value2, ...
All you want is the values.

>          if (ref $value eq "HASH") {
>             pad_keys($value);
>          }
>       }
>       for (keys %$ref) {
>          my $old = $_;
>          tr/ /_/;
>          $ref->{$_} = $ref->{$old};

You ought to check whether the new key already exists, otherwise you're
going o be losing data.

>          delete $ref->{$old};
>       }
>    }
> }

Finally, there's no need process the values and then the keys
in separate loops. Each execution of either loop corresponds to
a key/value pair so you can write

  foreach (keys) {
    modify key;
    recurse on value;
  }

This is what I came up with. It skips the rest of the loop
if the new key is the same as the old one, and uses the
fact that 'delete' returns the value of the element it
deleted.

HTH,

Rob


  sub pad_keys {

    my $ref = shift;
    return unless ref $ref eq 'HASH';

    foreach (keys %$ref) {

      pad_keys($ref->{$_});

      next unless (my $new = $_) =~ tr/ /_/;

      if (exists $ref->{$new}) {
        warn "Padded key $new already exists";
      }
      else {
        $ref->{$new} = delete $ref->{$_};
      }
    }
  }




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to