in reply to Re: Retaining hash order with Config::General?
in thread Retaining hash order with Config::General?

yes, I need it for internal purposes. Some of the entries in the file are listed to the user as available options for run-time configuration. from the user perspective, it looks silly when the menus change order for no apparant reason. Granted, I could force an alphabetical listing, or even maintain a separate sort list. Alphabetical is essentially random in this case, since anything except the structured order will not appear sane.. Cheers
  • Comment on Re^2: Retaining hash order with Config::General?

Replies are listed 'Best First'.
Re^3: Retaining hash order with Config::General?
by jeffa (Bishop) on Dec 15, 2008 at 17:03 UTC

    "Alphabetical is essentially random in this case, since anything except the structured order will not appear sane "

    So use a label field and sort by that. Consider a database. I don't care how the database stores the internals, only that I can retrieve that data. If i want to sort that data, i have to make sure that the data is sortable in a meaningful way. Personally, i would not store information into a Config file that would be better suited in a database, such as data that changes often. YMMV.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    

      I see your point(s). However this data doesn't change often, and is fairly complex (ie would involve a number of tables with one-to-many, m-to-o and o-to-o relationships. In short, a database solution would require signifficant development time as opposed to a few lines of Config::General creating a fully usable complex data structure that needs little or no maintenance and is simple to backup and modify.

      Second, what I need to retain here is only the order at which the keys were inserted. This works perfectly via the -Tie parameter when reading, just not when writing (see bart's post below).

      So by your database analogy, I need "SELECT * FROM tbl" -- no sorting or other magic, if I could simply keep the tie during save I'd be happy ;-)

Re^3: Retaining hash order with Config::General?
by kennethk (Abbot) on Dec 15, 2008 at 17:08 UTC

    Based on the code I've seen, you are best off just resorting the hash keys to the order you want just prior to display. Alphabetical is easiest, but you can resort the hash order with a custom test like this:

    #!/usr/bin/perl use strict; use warnings; use Config::General qw{ParseConfig}; use Tie::IxHash; my $file = 'test.cfg'; tie my %CFG, "Tie::IxHash"; %CFG = ParseConfig( -ConfigFile => $file, -Tie => "Tie::IxHash", ); print "When freshly loaded:\n"; print join "\n", keys %CFG; print "\n\n"; (new Config::General( -ConfigHash => \%CFG, -Tie => "Tie::IxHash", ))->save_file($file); # SaveConfig appears "equally bad" at this.. %CFG = ParseConfig( -ConfigFile => $file, -Tie => "Tie::IxHash", ); print "When saved & reloaded:\n"; print join "\n", sort {myfunction($a, $b)} keys %CFG; sub myfunction { my($key1, $key2) = @_; if (substr($key1,length($key1)-1,1) == substr($key2,length($key2)- +1,1)) { return ($key1 cmp $key2); } else { return (substr($key1,length($key1)-1,1) cmp substr($key2,lengt +h($key2)-1,1)); } }