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

I have a main script that posts info to a web page. I want to have a way to add other fields to the display, and make it modular - so I want to have a directory of small scripts, each of which knows how to make it's own flavor of output.

The main script would then get a list of scripts in the directory, and then run a specific method from each. E.g. the directory contains (x.pl. y.pl. z.pl), and I then want to run x::display(), y::display(), ...

I can certainly get the list of file names, but an most sure how to then run methods on them. I do not want to run the entire file (x.pl), as some of it is for data update, which will also do a similar thing but is cron driven, not web driven.

Must be simple, but .. not obvious to me!

Thanks, Gregory

My code looks like this; but the subroutine call won't work. ------------------------------------------ for my $file (glob "$Sources/*.pl") { $file =~ s/(.*).pl/$1/; my $name = $file."::display"; print " Function:: ", $name, "\n"; &${name}(); } ------------------------------------------ and in Sources/data1.pl:: package Data1; my $name = "Data1"; sub update() { print "Update Data.1 source\n"; } sub display() { print "Display Data.1 source\n"; } sub setup() { print "Setup Data.1 source\n"; }

Replies are listed 'Best First'.
Re: call perl subs in another directory?
by Fletch (Bishop) on Oct 16, 2007 at 20:48 UTC
Re: call perl subs in another directory?
by gamache (Friar) on Oct 16, 2007 at 20:36 UTC
    It looks like you want to be using do. Here's a short example, in three files.

    In do-test.pl:

    #!/usr/bin/perl use strict; use warnings; while (<subdir/*.pl>) { do $_; } Foo::spew(); Bar::spew();
    In subdir/foo.pl:
    package Foo; print "Executing foo.pl\n"; sub spew { print "This is package Foo\n"; }
    In subdir/bar.pl:
    package Bar; print "Executing bar.pl\n"; sub spew { print "This is package Bar\n"; }
    Finally, the output of do-test.pl:
    Executing bar.pl Executing foo.pl This is package Foo This is package Bar
    (Edited to provide more instructive example)
      Very nice, thanks - but this assumes that I have known (fixed) files and asociated package names. I need dynamic. I need in the file loop to be able to call a display() method on each file (or package) found.
        Tricky! But there's a way (and probably more than one). do returns the value of the last evaluation in the file; this means we can stick __PACKAGE__ at the end of the file and then grab this value with do.

        In do-test2.pl:

        #!/usr/bin/perl use strict; use warnings; while (<subdir/*.pl>) { my $pkg = do $_; print "Loaded package $pkg\n"; { no strict 'refs'; &{"${pkg}::spew"}(); } }
        In subdir/foo.pl:
        package Foo; print "Executing foo.pl\n"; sub spew { print "This is package Foo\n"; } __PACKAGE__
        subdir/bar.pl is similar to subdir/foo.pl, as above.

        Output of do-test2.pl:

        Executing bar.pl Loaded package Bar This is package Bar Executing foo.pl Loaded package Foo This is package Foo
        Dynamic.