Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I would like to define some errorcodes in a base class and be able to use them in all of the sub-classes. Following "Perl Best Practices" I tried it with the Readonly module:
# in base class: our $TIMEOUT_ERROR; Readonly $TIMEOUT_ERROR => 10; # I also tried this instead: # Readonly our $TIMEOUT_ERROR => 10; # then in the sub class: if ($nothing_happens) { $self->errorcode( $TIMEOUT_ERROR ); }
But this doen't work. I always get:
Global symbol "$TIMEOUT_ERROR" requires explicit package name at <sub class source file>

I also tried it with "use vars qw($TIMEOUT_ERROR)" in the base class but same result.
What I would like to avoid:
- copy and paste the constant definitions to every subclass
- use readonly object attributes like $self->TIMEOUT_ERROR

Do I have to fall back to the traditional "use constant" or is there a solution with Readonly?

Thanks
Michael

Replies are listed 'Best First'.
Re: inherit Readonly variables (constants)
by ikegami (Patriarch) on Mar 16, 2009 at 14:04 UTC
    Child classes don't inherit variables, only methods. You'll need to usee the qualified variable name ($My::Base::Class::TIMEOUT_ERROR) or have the base class export the variable and import it into the child.
    use My::Base::Class qw( $TIMEOUT_ERROR );

    Or create a tag if you have lots of error codes:

    use My::Base::Class qw( :error_codes );
Re: inherit Readonly variables (constants)
by JavaFan (Canon) on Mar 16, 2009 at 13:37 UTC
    If you use "use constants", you run into the same problems. The problem you get have nothing to do with Readonly. You're creating the read only values in one name space, and try to access from the other.

    Just as with any other variables (including subroutines), you have have to use the fully qualified name from the other package, or export/import the variables.

Re: inherit Readonly variables (constants)
by bellaire (Hermit) on Mar 16, 2009 at 13:44 UTC
    Using our here will only work if your packages happen to be defined in the same source file. As JavaFan says, otherwise you will need to export the variable to the subclass. The fact that the variable exists in the base class means nothing to the subclass. You still have to export the variable, just as you would for packages that don't share an inheritance tree.
Re: inherit Readonly variables (constants)
by Herkum (Parson) on Mar 16, 2009 at 16:04 UTC

    Ever try tracing back a variable that could come from any one of seven modules that are useed with the current code you are trying to debug? There is nothing worse than working with modules that automatically export variables and methods without you knowing about. Don't do it!

    That being said, maybe you should abstract out your time-out error to a method that returns the variable if you need to use it in several places. That is the whole point of subclassing, so you don't cut-and-paste the same piece of code all over the place.

Re: inherit Readonly variables (constants)
by Anonymous Monk on Mar 16, 2009 at 14:04 UTC
    Thanks for your answers but what would be a common solution? I read that it is bad practice to export from an object module. Or perhaps use a separate "Constants" module which exports what I need? But then again I will have to "use" it in every sub class which looks somewhat clumsy.
    Is there a (clean) way where I can do whatever is necessary in the base class and have the variables automatically be imported into every sub-class?
      I read that it is bad practice to export from an object module.
      If someone says "bad practice" (or "good practice") they usually voice an opinion. And if the practice includes the words "never" or "always", it usually means they haven't really thought things over.

      I happily export constants from object modules. It takes the user of the module not more than 2 keystrokes from preventing any importing anyway, so it's not something that's forced upon the inheriter.