separate require files for common routines, our, and use strict question

Discussion in 'Perl Misc' started by Bill, Jan 19, 2004.

  1. Bill

    Bill Guest

    While refactoring some perl files, I decided to put common routines in
    a common file and include it with require 'file';

    In order to keep variables declared in one module available in the
    require file, I decided to use the 'our' keyword.

    I have a question about 'use strict' syntax errors while using 'our'
    with require files that contain subroutines that refer back to the
    'our' variables.
    See below:

    ####### begin file tst1.pl ######

    #!/usr/bin/perl -w

    use strict;

    # using 'our', this is global enough to be seen by the required file
    below
    our $s;

    require 'tst2.pl';

    $s = 'world!';

    printhello();

    ####### file ends ########
    ####### begin file tst2.pl ########

    #### why can't I use strict here ????
    #use strict;

    sub printhello {
    print "Hello, $s\n";
    }

    1;

    ######### file ends #######

    So why can't I use strict in the require file here?
    Bill, Jan 19, 2004
    #1
    1. Advertising

  2. Bill

    Ben Morrow Guest

    (Bill) wrote:
    > #!/usr/bin/perl -w


    It is better to 'use warnings' than to use the -w switch.

    > use strict;
    >
    > # using 'our', this is global enough to be seen by the required file
    > below
    > our $s;
    >
    > require 'tst2.pl';
    >
    > $s = 'world!';
    >
    > printhello();
    >
    > ####### begin file tst2.pl ########
    >
    > #### why can't I use strict here ????
    > #use strict;
    >
    > sub printhello {
    > print "Hello, $s\n";
    > }
    >
    > 1;


    You have misunderstood what 'our' does. Its action is slightly
    confusing. What it does is declare the given globals *for the current
    lexical scope*. If you wish to access the same globals (without
    package qualification) from a different lexical scope, you have to
    declare them there as well.

    So. A little more explanation: first of all, the issue does not depend
    on having separate files. Separate blocks will do just as well, so

    use strict;

    {
    our $x;
    }
    {
    $x = 1;
    }

    will not compile. Secondly, although the variables are only declared
    in the current lexical scope, they are global:

    use strict;
    {
    our $x = "hello world\n";
    }
    {
    our $x;
    print $x;
    }

    will print "hello world". If you had used 'my' instead of 'our' the
    two '$x's would be different variables, and nothing would be printed.

    The most important thing, though, is that you are going about this the
    wrong way entirely. The point of splitting the code out into files is
    to break it into manageble pieces; this is no use if you then produce
    hard-to-follow links between those pieces with random shared
    globals. What you should do instead is pass the required data to the
    subs as parameters: in the given example, &printhello should be
    written

    sub printhello {
    my $s = shift;
    print "Hello, $s\n";
    }

    .. As a separate issue, it would probably be a good idea if you made
    your common code into a Perl5ish module rather than a Perl4ish include
    file: it is slightly more complicated, but has many benefits in terms
    of keeping your code separate from anyone else's. See perldoc perlmod
    for starters.

    Ben

    --
    "If a book is worth reading when you are six, *
    it is worth reading when you are sixty." - C.S.Lewis
    Ben Morrow, Jan 19, 2004
    #2
    1. Advertising

  3. Bill

    Bill Guest

    Re: separate require files for common routines, our, and use strictquestion

    Ben Morrow wrote:
    > So. A little more explanation: first of all, the issue does not depend
    > on having separate files. Separate blocks will do just as well, so
    >
    > use strict;
    >
    > {
    > our $x;
    > }
    > {
    > $x = 1;
    > }
    >
    > will not compile. Secondly, although the variables are only declared
    > in the current lexical scope, they are global:
    >
    > use strict;
    > {
    > our $x = "hello world\n";
    > }
    > {
    > our $x;
    > print $x;
    > }
    >
    > will print "hello world".


    This takes some getting used to--the global value is available, but
    using the global variable is illegal under strict. Think I'll avoid
    'our' until I find a better use for it :).

    > The most important thing, though, is that you are going about this the
    > wrong way entirely. The point of splitting the code out into files is
    > to break it into manageble pieces; this is no use if you then produce
    > hard-to-follow links between those pieces with random shared
    > globals. What you should do instead is pass the required data to the
    > subs as parameters: in the given example, &printhello should be
    > written
    >
    > sub printhello {
    > my $s = shift;
    > print "Hello, $s\n";
    > }


    Yah, and change all the function calls in the refactored files. Darn :(.

    Thanks for the clarification....
    Bill, Jan 19, 2004
    #3
  4. Bill

    Anno Siegel Guest

    Re: separate require files for common routines, our, and use strictquestion

    Bill <> wrote in comp.lang.perl.misc:
    > Ben Morrow wrote:


    [...]

    > > globals. What you should do instead is pass the required data to the
    > > subs as parameters: in the given example, &printhello should be
    > > written
    > >
    > > sub printhello {
    > > my $s = shift;
    > > print "Hello, $s\n";
    > > }

    >
    > Yah, and change all the function calls in the refactored files. Darn :(.


    Well, yes. Refactoring is about design improvement, and eliminating
    globals is (almost) always a step in that direction.

    However, it should happen first (while the code is still in one file),
    to simplify the splitting.

    A good first step in splitting a source file is to add a pair of {}
    around each part while leaving them in place. (If the split-off file
    is going to be a module, make that one a BEGIN block.) That way you
    can detect (and repair) any file-global lexicals that may cross
    the gap.

    Anno
    Anno Siegel, Jan 19, 2004
    #4
  5. Bill <> wrote:
    > Ben Morrow wrote:


    >> although the variables are only declared
    >> in the current lexical scope, they are global:
    >>
    >> use strict;
    >> {
    >> our $x = "hello world\n";
    >> }
    >> {
    >> our $x;
    >> print $x;
    >> }
    >>
    >> will print "hello world".

    >
    > This takes some getting used to--the global value is available, but



    That is the semantic for all dynamic (package) variables in Perl.


    > using the global variable is illegal under strict.



    Using the _unqualified_ variable name is illegal under strict.

    You can access $x as $main::x under strict with no declarations.


    > Think I'll avoid
    > 'our' until I find a better use for it :).



    It's only use is to make "use strict" shut up when you use
    the unqualified form of variable access.


    See also:

    "Coping with Scoping":

    http://perl.plover.com/FAQs/Namespaces.html


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jan 19, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. EvgueniB
    Replies:
    1
    Views:
    605
    Anthony Borla
    Dec 15, 2003
  2. Frank Fredstone
    Replies:
    1
    Views:
    425
    Jean-Francois Briere
    Jun 27, 2006
  3. ty ty
    Replies:
    0
    Views:
    347
    ty ty
    Jun 28, 2010
  4. Dave Bakhash
    Replies:
    14
    Views:
    188
    Brian McCauley
    Jul 23, 2004
  5. Vijoy Varghese
    Replies:
    4
    Views:
    111
    Vijoy Varghese
    Jul 11, 2005
Loading...

Share This Page