http://www.perlmonks.org?node_id=1025040

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

Hi Monastery

I stumbled about a talk video from a Python Guru propagating a ChainMap feature

http://code.activestate.com/recipes/305268-chained-map-lookups/

In Perl-lingo it's essentially a hash-tie where FETCH dynamically tries to find a key in a list of contained hashes.

Instead of concatenating these long lists statically (i.e. %H=(%h1,%h2,%h3)) this dynamic approach is faster when dealing with big hashes.

(It also implies that changes to underlying hashes are reflected afterwards)

Before I reinvent the wheel ...

sub get { my $key=shift; for my $h (@hash_chain) { return $h->{$key} if exists $h->{$key}; } return undef; }

... is there already a module on CPAN doing this? Couldn't find one!

Cheers Rolf

( addicted to the Perl Programming Language)

PS: Yes it has big similarities to the mechanism of @INC for STASHES and the JS prototype lookup chain.

Replies are listed 'Best First'.
Re: ChainMap of Hashes on CPAN?
by kschwab (Vicar) on Mar 23, 2013 at 16:34 UTC
      Excellent! :)

      especially Tie::Hash::Layered seems identical in most features (maybe not in the order)

      Thanks!

      Just this

      # tie the new hash with the initialised hashes above tie %hash, 'Tie::Hash::Layered', (\%test1, \%test2);

      could be simplified to

      tie %hash, 'Tie::Hash::Layered', \( %test1, %test2 );

      Cheers Rolf

      ( addicted to the Perl Programming Language)

Re: ChainMap of Hashes on CPAN?
by BrowserUk (Patriarch) on Mar 23, 2013 at 16:41 UTC

    Given that the chained hash will only allow access to keys found earlier in the chain -- ie. a key 'a' in a hash later in the chain will be hidden by a key 'a' in an earlier hash -- what is the advantage of a chained hash over composing a simple hash, from the chained hashes in reverse order?

    I'm just wondering (but not dismissing) the use-case?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      > I'm just wondering (but not dismissing) the use-case?

      It's useful to avoid the overhead of concatenating very long hashes if you only need few lookups.

      A "lazy" approach if you want.

      There some use cases listed in the Py-docs and have a look into the talk for his justification (I deep-linked to 29m10s)

      But actually I'm also suspicious about the frequency of such valid use cases, in those rare cases I would personally simply reimplement the get() function as a wrapper like I showed.

      Now my intention was to show how easily a py-idiom can be adapted.

      But this talk is quite interesting, it often goes into length to describe how to solve problems we do not have in the realm of the onion.

      And this with a kind of "hurray" attitude which is somehow alien to me... ¹

      Cheers Rolf

      ( addicted to the Perl Programming Language)

      ¹) but alas Europeans are bad in marketing! ;-)

        It's useful to avoid the overhead of concatenating very long hashes if you only need few lookups.

        Then I think I'd use:

        my $thing; exists $_->{ $key } and $thing = $_->{ $key } for \(%hash1, %hash2, %h +ash3);

        and save constructing a whole (class of) objects for something so trivial.

        But, I don't ever remember having such a requirement; nor can I think of an actual use-case.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        I had to laugh and just wanted to ask what vidoes you are watching... ;-)

        I have to cite from Monty Python’s Life of Brian:

        Are there any women(*) here today?

        McA

        (*) pythonistas

      Especially if at least one of hashes is a tie itself (like a DB wrapper or even more complicated) you will need a more complex container to add defaults and overrides.

      Cheers Rolf

      ( addicted to the Perl Programming Language)

      As the Python guy says: No creation of a new hash based on the other hashes, no data copy, save resources.

      McA

Re: ChainMap of Hashes on CPAN?
by sundialsvc4 (Abbot) on Mar 25, 2013 at 15:17 UTC

    The only time where I have seen this done is where there were several different name-spaces in play, and they did have a visibility-hierarchy relative to one another (such as local vs. global symbols), and the entirety of a name-space was created and then thrown away many times as the program ran.   You unquestionably could human-notice the time that it took to run through all the hashes on a hash-miss, but it was a price to be paid.

    Absent such considerations, though, I generally approach this problem by simply creating one hash into which every symbol encountered is added, but never removed.   The symbol’s hash-entry points to a record/object in which the various meanings-of-the-moment are maintained in a list.   (A symbol might appear in the hash but have no current meanings at all, and in the application that I am thinking about, the same names tended to be re-used many times.   The price of insertion was paid but once, and the price of removal from the hash, not at all.)