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

Hi all, How can we use variable, arrays, etc values from a perl module in master (main) script from where the module is being called without returning from a subroutine?

I have a script abc.pl which uses a module xyz.pm and xyz.pm parses a file qwerty.txt

abc.pl
use strict; use warning; use xyz; print @array;


xyz.pm
package xyz; use strict; use warnings; require 5.008; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw( @array ); my $file = "qwerty.txt"; open FILE, "< $file"; my @array = <FILE>;
kindly help! I know that i can do the parsing in the main file but due to some reasons I want to get values like this only.

Thanks
AvantA

Replies are listed 'Best First'.
Re: Using variables, arrays etc from a perl module in main script.
by kennethk (Abbot) on May 12, 2010 at 16:27 UTC
    You are having issues with scope. By using my to declare @array, you are essentially making it invisible outside the package. Rather, the code you've posted works as expected (I think) if you simply change that declaration to our:

    my $file = "qwerty.txt"; open FILE, "< $file"; our @array = <FILE>;

    See perlmod and perlsub for information on how scoping works.

    On a side note, there are a few things you are doing (an untested 2-argument open, @EXPORT instead of @EXPORT_OK, a bareword filehandle...) that I would consider poor form. I'll assume that's only because you are trying to make a demo script.

Re: Using variables, arrays etc from a perl module in main script.
by walkingthecow (Friar) on May 12, 2010 at 16:46 UTC
    You need to use our rather than my in the Perl module.

    my:
    • Not globally scoped (private)
    • Variable cannot be accessed in the form of $package::variable.
    our:
    • Globally scoped (public)
    • Can be accessed in the form of $module_name::variable outside of module.

    Notice above I use the scope operator. With our the scope operator is not needed. The name of variable $bar in package Foo is $Foo::bar; however, when we declare $bar with our (i.e., our $bar; ), then to access $bar outside of package Foo we do not need the scope (i.e., $Foo::bar becomes just $bar).


    abc.pl
    #!/usr/bin/perl use strict; use warnings; use xyz qw(:DEFAULT @array); print "@array\n"; sub1("Hello!");
    xyz.pm
    package xyz; use strict; use warnings; require 5.008; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(sub1); our @EXPORT_OK = qw(@array); open my $fh, '<', "qwerty.txt" or die "Cannot open file: ($!)"; our @array = <$fh>; sub sub1 { my $text = shift; print "Text: $text\n"; }
      Notice above I use the scope operator. With our the scope operator is not needed. The name of variable $bar in package Foo is $Foo::bar; however, when we declare $bar with our (i.e., our $bar; ), then to access $bar outside of package Foo we do not need the scope (i.e., $Foo::bar becomes just $bar).

      While it may simply be a language issue, the above sounds incorrect to me. While our does make @xyz::array globally accessible, it is only accessible using a fully qualified package name (@xyz::array) outside its package (xyz) unless it is exported/imported. I am uncertain what you mean by the "scope operator" - do you mean the package name with double colon?

        Sorry, let me clarify... I say scope operator for "::" because I am used to C++ terminology.

        You are correct, I should have stated that when importing variables our allows us to leave out the fully qualified package name and just use the bare $foo. However, if not importing the var we need to use FQPN (e.g., $Package::var).

        Correct me if I am wrong, but before Perl 5.6 when we used "use vars", didn't we have to use FQPN even when importing the variable? It's been a long time, but it seems that was the case.