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

Dear wise Monks,

I have been using a package I wrote like so ...

$ cat myscript.pl #!/usr/bin/perl -w use strict; ... use lib('.'); use MyModule; ... my $thingy = new MyModule ( 'thing2' ); print "yeah!\n" if $thingy->is_thing(); print "boo!\n" unless $thingy->is_thing();
I would run my script and get output of "yeah!". The code for MyModule is a file MyModule.pm. It declares an array that is global inside the module. Something like this ...
$ cat MyModule.pm package MyModule; use strict; my @things = ( 'thing1' , 'thing2' , 'thing3' , ); sub is_thing { my $self = shift; my $t = $self->{'thing'}; return grep /^$t$/, $things; } ... 1;
I decided to move the module in side my script like so I commented out the lines like so ...
#use lib('.'); #use MyModule;
... then I made a new script like so ...
$ cat myscript.pl MyModule.pm > newscript.pl $ ./newscript.pl $ boo!
Now my script behaves as if @things is empty. What did I do wrong?

Replies are listed 'Best First'.
Re: Defining a package inside my script?
by ikegami (Patriarch) on Jan 30, 2009 at 23:51 UTC

    The order in which you run things is different. Normally, the module is executed when it is loaded (by use). Now it's executed after your print statements. I wrap my inlined packages with BEGIN, which makes it more like use.

    #!/usr/bin/perl -w use strict; BEGIN { package MyModule; ... } my $thingy = new MyModule ( 'thing2' ); print "yeah!\n" if $thingy->is_thing(); print "boo!\n" unless $thingy->is_thing();
      Thanks! That does the trick!
Re: Defining a package inside my script?
by chromatic (Archbishop) on Jan 31, 2009 at 01:14 UTC

    If you're going to move the contents of modules into programs, you ought to change:

    my $thingy = new MyModule ( 'thing2' ); # do not use

    ... to:

    my $thingy = MyModule->new( 'thing2' );

    As you've seen, the order of compilation and execution often matters. When you use this syntax to call class methods, you're relying on a specific compilation order of declarations which may not be the case; it's better to disambiguate by making the invocant obvious.

Re: Defining a package inside my script?
by targetsmart (Curate) on Jan 31, 2009 at 05:32 UTC
    I know your problem is solved, but generally we use classes(oops) for re-usability and also for so many other features, so it is not generally good to define the packages inside the single perl script, which would make those packages not re-usable. Better have it in the separate file(.pm) and access it from your main script to utilize the power of oops.

    Vivek
    -- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
Re: Defining a package inside my script?
by Anonymous Monk on Jan 31, 2009 at 14:39 UTC
    __END__ $ echo BEGIN { >newfile.pl $ echo \$INC{'MyModule.pm'} = __FILE__; >>newfile.pl $ cat MyModule.pm >>newfile.pl $ echo } >>newfile.pl $ echo package main; >>newfile.pl $ cat myscript.pl >>newfile.pl $ perl newfile.pl yeah!
    I was about to automate the above procedure, but i stumbled upon Inline::Module,