belg4mit,
I tried for the better part of an hour trying to figure out how to do one of the following with no luck:
  • Get rid of the eval all together
  • Prefer not to use eval, but allow it for backwards compatability

    The issue is that you are creating a sort routine for a %hash that is defined in the module, not the calling script.
    I don't see how to get around this even with your suggestion and updated code.

    The smart sort came from the original module - I left it for backwards compatability.

    Cheers - L~R

    Update: I figured out how to do the second one. eval is now only used for backwards compatability if the calling script uses the old q($a cmp $b) syntax instead of a code ref:

    package Tie::SortHash; use strict; use constant HASH => 0; use constant LOOKUP => 1; use constant ARRAY => 2; use constant SUB => 3; use constant EVAL => 4; use constant CHANGED => 5; use vars qw($VERSION); $VERSION = '1.02'; sub TIEHASH { my $class = shift; my $hash = shift || {}; my $sort = shift || sub { my $hash = shift; sort {$a cmp $b || $a <=> $b} keys %$hash; }; my $self = bless [], $class; $self->_Build($hash, $sort); return $self; } sub FETCH { my($self, $key) = @_; $self->[HASH]{$key}; } sub STORE { my($self, $key, $value) = @_; $self->[HASH]{$key} = $value; $self->[CHANGED] = 1; } sub EXISTS { my($self, $key) = @_; return exists $self->[HASH]{$key}; } sub DELETE { my($self, $key) = @_; delete $self->[HASH]{$key}; splice(@{$self->[ARRAY]}, $self->[LOOKUP]{$key}, 1); delete $self->[LOOKUP]{$key}; } sub FIRSTKEY { my $self = shift; $self->_ReOrder if $self->[CHANGED]; $self->_Iterate; } sub NEXTKEY { my ($self, $lastkey) = @_; $self->_ReOrder if $self->[CHANGED]; $self->_Iterate($self->[LOOKUP]{$lastkey}); } sub CLEAR { my $self = shift; $self->[HASH] = {}; $self->[CHANGED] = 1; } sub DESTROY { } sub _Build { my ($self, $hash, $sort) = @_; @{$self->[HASH]}{keys %$hash} = values %$hash; $self->sortblock($sort); $self->_ReOrder; } sub _ReOrder { my $self = shift; $self->[LOOKUP] = (); $self->[ARRAY] = (); my $index = 0; my $hash = $self->[HASH]; for my $key ($self->[SUB] ? $self->[SUB]($hash) : eval $self->[EVA +L]) { $self->[LOOKUP]{$key} = $index; $self->[ARRAY][$index] = $key; $index++; } $self->[CHANGED] = 0; } sub _Iterate { my ($self, $index) = @_; $index = -1 unless defined $index; $index++; defined $self->[ARRAY][$index] ? $self->[ARRAY][$index] : undef; } sub sortblock { my($self, $sort) = @_; if (ref $sort eq 'CODE') { $self->[SUB] = $sort; } else { my $hash = $self->[HASH]; $sort =~ s/\$hash/\$hash->/g; $self->[EVAL] = "sort { $sort } keys %\$hash"; eval $self->[EVAL]; die $@ if $@; } $self->[CHANGED] = 1; } 1;

    In reply to Re: Re: RFC - inplace upgrade for Tie::SortHash by Limbic~Region
    in thread RFC - inplace upgrade for Tie::SortHash by Limbic~Region

    Title:
    Use:  <p> text here (a paragraph) </p>
    and:  <code> code here </code>
    to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.