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

Here's an interesting one... I had configured a Tk Entry widget such that its -textvariable was reference to a value in a hash. Of course that worked fine, both as input and as readout. But then sometime later I tied the hash with IxHash. Once its hash had been tied the Tk Entry widget only ever worked one way, as input from the GUI side, not at all as a readout. The hash itself was not troubled at all.

By this I mean that any change made to the Entry box produced expected changes in the tied hash. But no change to the value of that key in the tied hash ever had effect on the readout in the Tk Entry widget.

The wisdom I seek is whether this be a bug or a feature?

Replies are listed 'Best First'.
Re: Tk Entry and IxHash
by tilly (Archbishop) on Apr 12, 2004 at 02:12 UTC
    This sounds like a bug, where that bug would be I am not sure. I had a guess where it might be in how taking a reference to the hash value might interact with Tie::IxHash, but I could not demonstrate any misbehaviour. (I was playing around with tying a hash to Tie::IxHash, building up the hash, taking a reference to a hash value and then manipulating that value both through the reference and through the hash.)

    Can you produce a minimal code example that shows the problem with directions for how to run it and how it misbehaves? If you do that, then I can try to run it and see if it misbehaves for me. If it works for one person and not for another, it may be that the bug is fixed and all that you have to do is upgrade.

Re: Tk Entry and IxHash
by graff (Chancellor) on Apr 12, 2004 at 05:22 UTC
    It's not clear to me that what you want is at all possible, without violating the "information hiding" strategy of the IxHash object. Looking at the docs for Tie::IxHash, it seems that the OO interface on this module does not provide any direct accessors to the actual storage for hash values -- it only provides methods that return lists of things (i.e. copies of values or keys), and methods that add, delete or rearrange elements in its internal (hidden) data structure. You have the FETCH( $key ) and STORE( $key ) methods, but again these are really just function calls, not direct access to scalar storage.

    So the problem is that the "-textvariable" attribute on the Tk::Entry widget requires a reference to a scalar, but the OO design of IxHash does not provide the necessary access for doing this. You'd have to break the rules of OO, look into the IxHash code to see how the value is actually stored, and work out the syntax so that you pass a reference to that storage location when you configure the Entry widget. Very ugly and not a good idea.

    (update: Just checked the Tk::Entry "textvariable" specs -- I've actually tried it with both "-textvariable => $scalar" and "-textvariable => \$scalar", and they both work; but trying to do it with an IxHash object makes no sense: I'm not supposed to know what the module's internal scalar values are actually called, so I can't pass their names to -textvariable. :end-of-update)

    Now the question is: what is IxHash giving you that you don't get with the normal hash? If I understand its man page, it allows the elements of the hash to be retrieved in a fixed order -- in other words, it seems to be implementing something like an array where "name" attributes are associated with each array index.

    If that's what you want, it might be easier to build that yourself, so that you have direct access to where the values are stored, and can assign references to that storage when setting up the "-textvariable" attribute of the Entry widget. One way to do this would be to use a HoH to hold both values and ordering sequence in a single data structure:

    for $ord (0..5) { # set $key and $val for this iteration, and: $hash{$key}{value} = $val; $hash{$key}{order} = $ord; }
    This way, you can still pass a reference to the value, and you can sort the hash elements by their established index order. Another way would be an AoA, to store name/value pairs in a fixed sequence:
    for (0..5) { # set $key and $val for this iteration, and: push @array, [ $key, $val ]; } # equivalent to: $array[0][0] => $array[0][1]

      Most informative. I think I grok now. It seems a feature the way you've explained it. Mystery is solved. Thanks.

Re: Tk Entry and IxHash
by Courage (Parson) on Apr 12, 2004 at 07:32 UTC
    Show us the code

    Courage, the Cowardly Dog