From CPAN daily updates, the module Tie::Hash::Layered came across, so I checked it out. It allows a particular key to have one value at a time but the ability to pop and push and shift and unshift values from that particular keys so that the value for a particular key depends on what you have shifted/unshifted/popped/pushed from that value. From the synopsis:
tied(%hash}->push( { slub => 'slob' } ); # $hash{'slub'} eq 'slob' tied(%hash)->unshift( { slub => 'slab' } ); # $hash{'slub'} eq 'slab' tied(%hash}->shift(); # $hash{'slub'} eq 'slob' tied(%hash)->pop(); # $hash{'slub'} is now not defined
Then the author goes on to give a suggested usage of this module:

the obvious application is for preferences. In a CGI app you could tie in the bottom most hash to a database with default all-users' preferences, the second layer with the current user's preferences, the layer above that with the per-session preferences and the layer above that with the per-request values.

In other words, as you continue to layer on preferences, the access of those preferences will pull a value from the hash, whose actual current value will depend on whether one of the new layers unshifted a value onto that hash key.

But I have two issues with this intended use:

  • Why not just overwrite the value? Oh I see the answer: because you will want the old hash value back. In this case, my response is: "just use a lexically scoped copy of the hash for each of the stated contexts above"- let Perl take care of shifting and unshifting for you. You are bound to forget something in all of this manual hash maintenance.
  • Another approach to this problem is a class-based object hierarchy with data inheritiance - just overwrite the values in the subclasses and use accessor methods to get the data at each level. I can't imagine that a tied-class (which is really object-oriented) will be any faster than an object hierarchy. And again, as long as your objects are properly scoped, you dont have to worry about unshifting values as will be necessary with this module.
  • Replies are listed 'Best First'.
    Re: I dont agree with the suggested use of Tie::Hash::Layered
    by Masem (Monsignor) on Aug 06, 2001 at 22:11 UTC
      See my module Tie::Hash::Stack for something that is similar. (Mine runs on an array of hashes, this appears to run on a hash of arrays).

      (big honkin' IMHO warning!) Note that I think my module handles the idea of layers a bit better in the suggestions that you mention. That is, with my module, if you switch to a new 'set' of preferences, using your example, you simply push a new hash; all hash sets are done in that hash, so that if you then want to drop back a layer, you simply pop that last hash off and ALL settings from that layer are gone. Here, to do the same, you have to push every key/value pair and then pop each one of those, a lot more work.

      In my case, I think the idea is more useful when you have several 'panes' of linear data entry, which allow the user to go backwards as well to undo changes, as typical with InstallShield and friends. Each time the user clicks "next", push a new hash onto the stack, and if they hit "back", pop it off.

      -----------------------------------------------------
      Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain