Sharing variables between modules

Discussion in 'Perl Misc' started by Tomek, Nov 10, 2006.

  1. Tomek

    Tomek Guest

    Hello!
    I am using Perl 5.8.8 on FreeBSD. I have to admit that I already lost 2
    hours on something what should be obvious, but for me it isn't :(
    I have 2 files, 1st is a parenting script, and 2nd is an included module.
    I want to read from 2nd module a variable set in parenting script.

    I have tried:

    File 'a':

    #!/usr/local/bin/perl
    use b;
    our $a='a';
    $b::a=$a;

    File 'b.pm':

    package b;
    print $a;

    Executing 'a' prints just nothing :(
    -----------------------------------------------
    I also tried the second variant:
    File 'a':

    #!/usr/local/bin/perl
    use b;
    our $a='a';

    File 'b.pm':

    package b;
    use base 'Exporter';
    @EXPORT=qw{$a};
    our $a;
    print $a;

    Effect is the same :( No data printed :( I am now clueless, what am I
    doing wrong ?

    Regards, Tomasz Kraus
     
    Tomek, Nov 10, 2006
    #1
    1. Advertising

  2. Tomek

    Guest

    Tomek wrote:
    > Executing 'a' prints just nothing :(


    That's because (among other reasons) 'a' has no print command.

    I don't think you're clear on what modules are or what they do.
    use()ing a module isn't the same thing as inserting and executing the
    code. You don't export variables from modules; you export subroutines.
    You call the subroutine and pass data to it. For example:

    #!/usr/bin/perl
    use strict; use warnings;
    use b qw{ print_stuff }; #this is a subroutine we'll call

    my ($one, $two, $three) = (1,2,3);
    print "In the parent program: $one $two $three \n";
    print_stuff($one, $two, $three); #call the module's sub, pass data
    __END__

    The 'b' module looks like this:

    sub print_stuff {
    my ($foo, $bar, $baz) = @_;
    print "Module got this info: $foo $bar $baz \n"
    }
    1;


    --
    The best way to get a good answer is to ask a good question.
    David Filmer (http://DavidFilmer.com)
     
    , Nov 10, 2006
    #2
    1. Advertising

  3. On 11/10/2006 01:43 PM, Tomek wrote:
    > Hello!
    > I am using Perl 5.8.8 on FreeBSD. I have to admit that I already lost 2
    > hours on something what should be obvious, but for me it isn't :(
    > I have 2 files, 1st is a parenting script, and 2nd is an included
    > module. I want to read from 2nd module a variable set in parenting script.
    >
    > I have tried:
    >
    > File 'a':
    >
    > #!/usr/local/bin/perl
    > use b;
    > our $a='a';
    > $b::a=$a;
    >
    > File 'b.pm':
    >
    > package b;
    > print $a;
    >
    > Executing 'a' prints just nothing :(
    > -----------------------------------------------
    > I also tried the second variant:
    > File 'a':
    >
    > #!/usr/local/bin/perl
    > use b;
    > our $a='a';
    >
    > File 'b.pm':
    >
    > package b;
    > use base 'Exporter';
    > @EXPORT=qw{$a};
    > our $a;
    > print $a;
    >
    > Effect is the same :( No data printed :( I am now clueless, what am I
    > doing wrong ?
    >
    > Regards, Tomasz Kraus


    Shouldn't that be the other way around? The module that you're use-ing
    defines the variables, and the other module prints those values.



    --
     
    Mumia W. (reading news), Nov 10, 2006
    #3
  4. Tomek

    Guest

    Mumia W. (reading news) wrote:
    > Shouldn't that be the other way around? The module that you're use-ing
    > defines the variables, and the other module prints those values.


    I think the OP is confusing use() and do().

    --
    The best way to get a good answer is to ask a good question.
    David Filmer (http://DavidFilmer.com)
     
    , Nov 10, 2006
    #4
  5. Tomek

    Ben Morrow Guest

    Quoth Tomek <>:
    > Hello!
    > I am using Perl 5.8.8 on FreeBSD. I have to admit that I already lost 2
    > hours on something what should be obvious, but for me it isn't :(
    > I have 2 files, 1st is a parenting script, and 2nd is an included module.
    > I want to read from 2nd module a variable set in parenting script.
    >
    > I have tried:
    >
    > File 'a':
    >
    > #!/usr/local/bin/perl


    You *always* want

    use strict;
    use warnings;

    here.

    > use b;


    Don't use lowercase module names. They are reserved for pragmata
    (modules that affect how perl parses your program).

    > our $a='a';


    Don't use the variables $a and $b. They are slightly magic (they are
    used by the sort function) and don't need to be declared. This makes
    things harder to debug.

    > $b::a=$a;


    This is occuring too late. The 'print $a;' below happens as soon as the
    'use b;' line is compiled, which is before any of the code in 'a' is
    run.

    > File 'b.pm':
    >
    > package b;


    You need

    use strict;
    use warnings;

    here, as well, as their effects are limited to the lexical scope they
    are used in: in this case, the file.

    > print $a;


    If you'd used warn instead of print here, it would have been clear that
    the statement was in fact being executed but the variable was not set
    yet.

    If you really want to do something like this, you want

    #!/usr/bin/perl

    use warnings;
    use strict;

    # The BEGIN makes the assignment happen at compile time.
    # Note that this must also come *before* the use Foo line.

    BEGIN { $Foo::foo = 'foo' }

    use Foo;

    __END__

    package Foo;

    use warnings;
    use strict;

    print $foo;

    1;

    > I also tried the second variant:
    > File 'a':
    >
    > #!/usr/local/bin/perl
    > use b;
    > our $a='a';


    What is the 'our' there for? Do you know what it does?

    > File 'b.pm':
    >
    > package b;
    > use base 'Exporter';
    > @EXPORT=qw{$a};
    > our $a;
    > print $a;


    Here, again, $b::a is being set too late, after the print command has
    already happened.

    What are you actually trying to acheive here? Doing real work (as
    opposed to initialisation) in the body of a module is generally
    considered bad practice: it is much better to export subs from the
    module. If your intention was that $a be some sort of setting for your
    module, then it is usual *not* to export it but to set it by its full
    name in the calling program. If the module's actual work were to be put
    in a sub, then you can set the variable before you call the sub,
    something like

    package Foo;

    use strict;
    use warnings;

    # 'use base' does some odd things to make 'fields' module work.
    # It's generally considered better not to use it for Exporter.

    require Exporter;
    our @ISA = 'Exporter';

    # Putting stuff in @EXPORT is usually considered bad style, as
    # @EXPORT_OK makes it clearer where things are imported from.

    our @EXPORT_OK = qw/do_stuff/;

    # It's usual to use Titlecase for package globals, so they stand out
    # in the code. This is similar to using ALL_CAPS for constants.

    our $Setting;

    sub do_stuff {
    warn $Setting;
    }

    1;
    __END__

    #!/usr/bin/perl

    use strict;
    use warnings;

    use Foo qw/do_stuff/;

    $Foo::Setting = 'foo';
    do_stuff;

    __END__

    Ben

    --
    Like all men in Babylon I have been a proconsul; like all, a slave ... During
    one lunar year, I have been declared invisible; I shrieked and was not heard,
    I stole my bread and was not decapitated.
    ~ ~ Jorge Luis Borges, 'The Babylon Lottery'
     
    Ben Morrow, Nov 10, 2006
    #5
  6. Tomek

    Ben Morrow Guest

    Quoth :
    > Tomek wrote:
    > > Executing 'a' prints just nothing :(

    >
    > That's because (among other reasons) 'a' has no print command.


    This is not the problem. The print statement is executed, just earlier
    than the OP thought.

    > I don't think you're clear on what modules are or what they do.
    > use()ing a module isn't the same thing as inserting and executing the
    > code. You don't export variables from modules; you export subroutines.


    While it is not common, you most certainly *can* export variables from
    modules. The 'vars' module, for instance, exists solely to export
    variables. Other examples are the Socket module, which exports $LF, $CR,
    and $CRLF, and the FindBin module, which exports $Bin.

    You are correct, of course, that it is generally better practice to
    export subs and pass arguments to them, but TMTOWTDI :).

    Ben

    --
    We do not stop playing because we grow old;
    we grow old because we stop playing.
     
    Ben Morrow, Nov 10, 2006
    #6
    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. =?Utf-8?B?QXNoYSBHaWxs?=

    Sharing variables between pages...

    =?Utf-8?B?QXNoYSBHaWxs?=, Jun 9, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    1,918
    Pete Wright
    Jun 9, 2004
  2. darrel
    Replies:
    3
    Views:
    389
    Kyril Magnos
    Jul 15, 2004
  3. W Akthar
    Replies:
    4
    Views:
    546
    Kevin Spencer
    Nov 4, 2004
  4. tfsmag

    sharing variables between methods

    tfsmag, Jun 16, 2005, in forum: ASP .Net
    Replies:
    6
    Views:
    479
    Scott Allen
    Jun 17, 2005
  5. Bart Ogryczak

    sharing persisten cache between modules

    Bart Ogryczak, Oct 23, 2006, in forum: Python
    Replies:
    7
    Views:
    252
    Steve Holden
    Oct 24, 2006
Loading...

Share This Page