0

我有以下问题,可能是我试图以一种不好的方式解决它,所以如果你告诉我如何以正确的方式去做,我将非常感激!

我有一个基类,它有一个方法,我想访问基于真实对象类(ref($self))的包变量。

#!/usr/bin/env perl

my $var = SubClass->new();
$var->method();

package BaseClass;

sub new { construct... }
sub method { 
   my $self = shift;

   # in this method I wan to get values from 'our %VAR' of the children class or ref($self) class, something like that:
   return ${ref($self)::VAR}{k1}; 

   # of course I can create a method and do it in the following way but I am not sure that it's a good idea
   return $self->get_var()->{k1};
}
sub get_var { die "Imaplement in children"; }

package SubClass;

use base 'BaseClass';

our %VAR = (k1 => 'smth', k2 => 'smth', ...);
sub get_var { return \%VAR } # don't like this idea

1;
4

1 回答 1

3

使用该%{ref($self)::VAR}解决方案有时可能是最简单的,尽管偏执的程序员会包括一些检查:

# Accessing %__PACKAGE__::VAR:
# I hope that I'm not in a subclass,
#    because that would change the value reported by `ref($self)`
#    and I can't be bothered to search @ISA manually...

unless (defined ref $self) {
   die "\$self is not a reference!";
}
if (ref $self ~~ [qw/SCALAR ARRAY HASH
   CODE REF GLOB LVALUE FORMAT IO VSTRING Regexp /]) {
   die "\$self is not an object!";
}
no strict 'refs'; # Hehe, I can't use strict here :S
unless (%{ref($self).'::VAR'}) {
   warn "Umm, this hash is empty."
      . "I don't know if I just created it, or it is meant to be that way.";
}
return ${ref($self).'::VAR'}{k1};

总而言之,使用访问器方法不仅可以避免重复,而且更安全、更少hackish并且更面向对象:

sub return_var {
   # We know that we are in the right package.
   # We know we are accessing the correct hash.
   # It is irrelevant whether I call this method
   #    from the package/class or from an object.
   # And I'm glad to take the method performance penalty
   #    in exchange for clear code.
   return \%VAR;
}

在结论#2中,有不止一种方法可以做到这一点。在 Perl 中,没有“正确”的方法。尽管您可能会理解为什么我发现第二种解决方案更优雅。

于 2012-08-01T09:38:20.787 回答