Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: Strict isn't strict enough (stop it)

by tye (Cardinal)
on Dec 31, 2011 at 17:33 UTC ( #945756=note: print w/ replies, xml ) Need Help??


in reply to Strict isn't strict enough

Doctor, it hurts when I do this.

Don't define interfaces that require using fully-qualified names. As you noted, documenting that your interface requires such just makes it a "feature" of your design instead of a bug in your bad design.

package Slave; use strict; use Exporter qw< import >; use vars qw< @EXPORT_OK $type >; @EXPORT_OK = qw< $type >; # ... 1;
use strict; use Slave qw< $typo >;
use strict; use Slave qw< $type >; print $typo;

- tye        


Comment on Re: Strict isn't strict enough (stop it)
Select or Download Code
Re^2: Strict isn't strict enough (stop it)
by davies (Vicar) on Dec 31, 2011 at 17:43 UTC

    Thank you. I had thought of using Exporter, but the docs seemed to be pretty emphatic that variable names should not be exported, so I was using full qualification instead. If it's an appropriate technique despite the docs (or, conceivably, my misunderstanding of them), then I'll go ahead.

    Regards,

    John Davies

      "Don't poke yourself in the eye."
      "Doctor, it hurts when I slice through my eye with a chainsaw."

      Although the docs you linked to are a bit over-the-top (quite an unfortunate thing in such a core module), they make a good point:

      To provide the capability to set/get class-wide settings, it is best instead to provide accessors as subroutines or class methods instead.

      The docs said, "Don't do X, do Y instead" and you used them to justify, "Since I can't do X, I'll do W" where "W" is a much worse idea than "X".

      What you are doing is equivalent to having public attributes in a class. That makes for pretty bad class design (of course, some people have a hard time even conceiving of class design without the equivalent of public attributes; for example, take a critical look at Moose ;).

      I'll let you struggle with whether you should abandon exposing global variables for your interface and replace them with global subroutines instead. There can certainly be advantages to that. But I won't try to scare you into such a decision with over-the-top proclamations. "Trust me". (:

      - tye        

      ... the docs seemed to be pretty emphatic that variable names should not be exported, so I was using full qualification instead.

      But the variables the Exporter docs warn against exporting are package variables (AFAIU, the only variables that can be exported by the module in question), i.e., global variables, which are commonly acknowledged to have the potential "horrible effects at-a-distance" also referred to in the docs.

      Your OPed question seems to boil down to "How can I use global variables without endangering my sanity?". The generally accepted short answer is "You can't!". (Remember: There is no Sanity Claus.)

        You are right in thinking that I am concerned with global variables. I don't have a problem with using global variables for things that genuinely are global. Typically I read or generate these at the start of my code and then never change them, so I'm not particularly concerned for my sanity in that regard. I intended my OP question to be along the lines of "how do I avoid typos creating global variables I didn't want". If I can't do that, I have genuine fears for my sanity. :-)

        Regards,

        John Davies

Re^2: Strict isn't strict enough (stop it)
by tobyink (Abbot) on Dec 31, 2011 at 19:50 UTC

    An alternative to having Slave.pm export the variable would be to write a get/set wrapper for $Slave::type:

    package Slave; my $type; sub type(;$) { $type = shift if @_; $type } 1; package main; use strict; use Slave; Slave::type("FOO"); print Slave::type . "\n"; Slave::tpye("BAR"); # dies

    Or, if you're on Perl 5.6+ and don't care about supporting archaic versions of Perl (and you should rarely care about such things)...

    package Slave; my $type; sub type(;$) :lvalue { $type = shift if @_; $type } 1; package main; use strict; use Slave; Slave::type = "FOO"; print Slave::type . "\n"; Slave::tpye = "BAR"; # dies

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://945756]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (3)
As of 2014-08-30 05:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (291 votes), past polls