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

Chaps,

I have data in a three-deep hash reference (HoHoH) called $rhHandles and I wanted to extract those second level hash records with the "public" attribute set and place them in another HoH structure, $rhPublicHandles. I had the keys I wanted in a list, @publicHandles, and my first solution was to iterate over @publicHandles in a for loop;

$rhPublicHandles->{$_} = $rhHandles->{handles}->{$_} for @publicHandles;

However, I wondered whether using a hash slice would be a more efficient solution. After a struggle to get my head around the syntax I came up with this.

@{%{$rhPublicHandles}}{@publicHandles} = @{%{$rhHandles->{handles}}}{@publicHandles};

It works very well and benchmarks faster that the loop but it is not nearly as readable for those who have to maintain my code when I move on.

The question, then, is whether there is a simpler, more readable syntax for hash reference slicing that I could employ to do this job. I don't really want to sacrifice the efficiency of the slice but the loop is far more obvious in what it is doing.

Cheers,

JohnGG

Replies are listed 'Best First'.
Re: Tricky syntax with hash ref. slicing
by Fletch (Bishop) on Mar 10, 2006 at 14:49 UTC

    The %s are unnecessary, so you can wipe one level of dereferencing there.

    @{ $rhPublicHandles }{ @publicHandles } = @{ $rhHandles->{handles} }{ @publicHandles };

    If you're worried about verbosity, you could stick $rhHandles->{handles} into a temporary scalar; however if this is the one and only place you're referring to it in this particular scope it's probably overkill (whereas if you're using it several times it might make things a little cleaner).

    Update: maybe play with the formatting and make things line up?

    @{ $rhPublicHandles }{ @publicHandles } = @{ $rhHandles->{handles} }{ @publicHandles };
      So they are, wow! How does that work? I thought I would have to get right back to the hash by de-referencing with %{...} before being able to move forward again slicing out a list @{...}.

      Another example of Perl automagically doing clever things. Yes, I was only referring to it twice actually and I did consider a temporary scalar for $rhHandles->{handles} but decided not to more to see if I could crack the problem.

      Thank you,

      JohnGG

Re: Tricky syntax with hash ref. slicing
by VSarkiss (Monsignor) on Mar 10, 2006 at 15:50 UTC
      Thank you. A very useful resource which I will bookmark.

      Cheers,

      JohnGG

        I have a nice little table on the subject.
Re: Tricky syntax with hash ref. slicing
by borisz (Canon) on Mar 10, 2006 at 16:16 UTC
    If you are unsure, that someone else understand your code, add a comment.
    Boris
      As a newbie programmer I inherited a suite of about twenty Cobol and Fortran programs ranging between 100 and 1000 lines each. There were about a dozen comments in the whole lot plus useful variable names like I, J and K. After that experience I always go OTT with comments

      Cheers,

      JohnGG

Re: Tricky syntax with hash ref. slicing
by shotgunefx (Parson) on Mar 10, 2006 at 16:24 UTC
    In addition to Fletch's note, I'd just like to add that a well placed comment would make it fairly obvious to anyone to grok what it was doing. Maybe not how, but that's another story ;)

    -Lee
    "To be civilized is to deny one's nature."