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

Here is a program to share an variable $f among packages. It works fine.But i want to share an array among packages in this way. So suggest me some code.

package P; use strict; use vars qw($f); # NOTE: *f is a shared typeglob sub foo { print $f,"\n"; $f = "world"; } package main; use strict; use vars qw($f); # NOTE: *f shared with package P *P::f = *f; # make P::f an alias of main::f $f = "howdy"; P::foo(); # after this call, $f is changed! print $f,"\n"; __END__ ouput: howdy world

Replies are listed 'Best First'.
Re: Suggest me some code to share an array among packages???
by shmem (Chancellor) on Sep 04, 2006 at 10:48 UTC
    Yes, you can. The typeglob *f in the code you've posted (which comes from this node) holds a slot for an array also. Changing all instances of $f to @f should do. <update>.. and use @f as array..</update>

    Please read perlref, read the caveat at the bottom of the code snippet's node, read e.g. Of Symbol Tables and Globs, do a Super Search on glob, to get an idea of what this is all about.

    It's generally a better idea not to share, and if you absolutely must do it, don't use typeglobs. Instead, access shared variables from other packages qualifying them with their full package name, i.e. access @shared_array in package Foo as @Foo::shared_array from outside.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Suggest me some code to share an array among packages???
by gellyfish (Monsignor) on Sep 04, 2006 at 10:11 UTC

    What happened when you tried it?

    /J\

Re: Suggest me some code to share an array among packages???
by TGI (Parson) on Sep 04, 2006 at 20:38 UTC

    Its best to avoid global data and mixing namespaces. But, if you must share your variables like this use Perl's Exporter facility, rather than hand coding your own system.

    I've included code that shows how to share a scalar, but an array or hash would work identically. I also didn't use strict, which all production code should do. Nothing I did here will fail under strictures.

    Shared variable module

    package SharedVariables; use base Exporter; # Default export @EXPORT = qw( $scalar1 $scalar2 @array1 ); # Possible to export these @EXPORT_OK = qw( $scalar1 $scalar2 @array1 @array2 ); # Named groups to export %EXPORT_TAGS = ( scalars => [ qw( $scalar1 $scalar2 ) ], arrays => [ qw( @array1 @array2 ) ], ); 1;

    Recieving module: Foo

    package Foo; use SharedVariables; sub Print { print "Foo Scalar1 $scalar1\n"; } sub Set { $scalar1 = 'Foo'; print "Set Foo\n"; } 1;

    Recieving Module: Bar

    package Bar; use SharedVariables qw(:scalars); sub Print { print "Bar Scalar1 $scalar1\n"; } sub Set { $scalar1 = 'Bar'; print "Set Bar\n"; } 1;

    Main program

    use SharedVariables qw(:DEFAULT); use Foo; use Bar; $scalar1 = 'Initialized'; print "Main Scalar1 $scalar1\n"; Foo::Print; Foo::Set; Foo::Print; Bar::Print; Bar::Set; Bar::Print; $scalar1 = 'Main'; Foo::Print; Bar::Print; __END__ C:\temp> test.pl Main Scalar1 Initialized Foo Scalar1 Initialized Set Foo Foo Scalar1 Foo Bar Scalar1 Foo Set Bar Bar Scalar1 Bar Foo Scalar1 Main Bar Scalar1 Main


    TGI says moo