"Gary Stainburn" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > Hi folks, > > I've got the code: > > package Trainset; > > my %_BLOCKS=(); # blocks of track > my %_TRAINS=(); # trains > my %_BOXS=(); # signalboxes > > sub blocks { # Return list of blocks > sort keys %_BLOCKS; > } > sub trains { # Return list of trains > sort keys %_TRAINS; > } > sub boxes { # Return list of signalboxes > sort keys %_BOXS; > } > > I wanted to eliminate the duplicated code so I wrote: > > sub list { > my $self=shift; > my $key=uc(shift); > print "using '_$key' as hash name\n"; > return sort keys %${"_$key"}; > } > > which according to the section of symbolic references in perldoc perlrefs > should work. However, while Trainset->blocks returns the list, > Trainset->list('blocks') doesn't. > > Can anyone spot the problem or suggest an alternative please.
You're trying to dereference $_BLOCKS as a hash reference. Use return sort keys %{"_$key"}; and it should work. But note that it won't return the keys from the lexical ('my') hashes that you've used in your code: only package ('our') variables are accessible by name. Even so it's a horrible thing to be doing, if only because you can't 'use strict'. This might be better sub list { my $self = shift; my %hash = ( BLOCKS => \%_BLOCKS, TRAINS => \%_TRAINS, BOXS => \%_BOXS, ); my $key = uc shift; print "using '_$key' as hash name\n"; return sort keys %{$hash{$key}}; } but I'd rather see this implemented as an object method with the hashes stored as $object->{_BLOCKS} etc. As it stands your Trainset class is working as an object, and you can never have more than one trainset in your program. HTH, Rob -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>