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


Reply via email to