"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>