Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Multiple Package in one file with equal named variables

by Brutha (Friar)
on Jan 27, 2006 at 09:42 UTC ( [id://525933]=perlquestion: print w/replies, xml ) Need Help??

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

Hello,

I just learned another lesson about variable scope, names and packages, but I am not sure which of my solutions should be prefered.

I have a quite great number (about 40) of slightly different objects, so I created a base class and used a macro to generate the code for the specialized subclasses with their differing attribute, which is a constant list of values (simplified, untested code):

package Baseclass; # common attributes and methods sub use_values { croak ("Abstract class"); } package Subclass_1; use base 'Baseclass'; my @values = (...); sub use_values { ... } package Subclass_2; use base 'Baseclass'; my @values = (...); sub use_values { ... }

This did not work, as the package statement does not affect the scope of @values.

One solution would be to name them different (e.g. @Subclass_1_values), which would keep me typing the rest of the day and does not increase readability.

One solution would be to wrap it in a function:

package Subclass_1; use base 'Baseclass'; sub use_values { my @values = (...); ... }
Does that initialize the list everytime the method is called? Not very efficient then.

Next try is a local scope:

package Subclass_1; use base 'Baseclass'; { my @values = (...); sub use_values { ... } }

Should work, but I do not like the increased indenting.

What else can I try? What are your experiences?

Thank You for comments.

And it came to pass that in time the Great God Om spake unto Brutha, the Chosen One: "Psst!"
(Terry Pratchett, Small Gods)

Replies are listed 'Best First'.
Re: Multiple Package in one file with equal named variables
by rinceWind (Monsignor) on Jan 27, 2006 at 09:57 UTC

    The verb my defines lexical scope, and the variables live in pad space. The second point is that inheritance only works for method calls, not access to variables.

    If you provide accessor/mutator functions to get at your variables, inheritance will work, and you will have much cleaner code.

    --

    Oh Lord, won’t you burn me a Knoppix CD ?
    My friends all rate Windows, I must disagree.
    Your powers of persuasion will set them all free,
    So oh Lord, won’t you burn me a Knoppix CD ?
    (Missquoting Janis Joplin)

      If you provide accessor/mutator functions to get at your variables, inheritance will work
      That would mean the function-with-local-variable solution. Aren't local variables initialized each time the sub is called?

      I forgot to mention that this list is private and constant class data, which is only used in its package. They are used for steering access to a different combination of database tables for each specialized class. That db design is not my work, but I have to live with it.

      And it came to pass that in time the Great God Om spake unto Brutha, the Chosen One: "Psst!"
      (Terry Pratchett, Small Gods)

Re: Multiple Package in one file with equal named variables
by ysth (Canon) on Jan 27, 2006 at 11:03 UTC
    Don't tell anyone, but I sometimes don't indent the contents of blocks that contain whole packages:
    { package Subclass_1; use base 'Baseclass'; my @values = ( ... ); sub use_values { ... } } # end of package Subclass_1;

      Heathen! Ye shall surely burn in the righteous fires of perltidy, forsooth. Verily. Yadda yadda.

      :)

Re: Multiple Package in one file with equal named variables
by Roy Johnson (Monsignor) on Jan 27, 2006 at 15:56 UTC
    Though I think it's better to put each package into its own lexical scope, as long as each package defines a new lexical @values, what you've written will work. Each newly-declared one will mask the previous one, but each function will refer to the proper incarnation.

    You'll get warnings about "masks earlier declaration", but you intend to do that.

    Example code:


    Caution: Contents may have been coded under pressure.
      You'll get warnings about "masks earlier declaration", but you intend to do that.
      Yes, I do. But I do not like the warnings, as they possibly hide the important ones and you can't find the forest amongst the trees.

      And it came to pass that in time the Great God Om spake unto Brutha, the Chosen One: "Psst!"
      (Terry Pratchett, Small Gods)

        The usual way of dealing with warnings for things that you intend to do is to turn off warnings around the offending statement. Often that's done for a lexical scope, but since you don't want to introduce multiple lexical scopes, you'd do:
        no warnings 'misc'; my @values = (...); use warnings 'misc';
        At this point, you're probably at the point that wrapping each package in its own lexical scope looks like the Right Thing To Do. It is.

        For reference, perldoc perllexwarn shows the various categories of warnings you can turn on and off, and perldoc perldiag lists some of the warning messages and which category they fall into. (I found it odd that the "masks earlier declaration" didn't fall under the "redefine" category, and instead was thrown into "misc".)


        Caution: Contents may have been coded under pressure.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://525933]
Approved by PodMaster
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (8)
As of 2024-04-25 11:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found