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

I want to include a file in a script. With "do 'FILE'" and "eval 'cat FILE'" the file is evaluated, but the code in the included file is not handled as code of the script. Furthermore I can't see the symbols ("my"/"our") in the included file. I'm searching for a way to include files as in C with #include. Thank you in forward, jds00.

Replies are listed 'Best First'.
Re: #include files
by broquaint (Abbot) on Oct 24, 2003 at 08:57 UTC
    If you're not adverse to some simple source filtering then Filter::Include is the module for you. However, if you are adverse to source filtering there's always the C preprocessor flag -P which will work in a similar fashion (see. perlrun for more info).

    And the reason you can't see my variables from the included script is because my declares a lexical variable which will falls out of scope at the end of a file (as lexical variables are declared into the surrounding file scope by default). So your alternatives are to either export your variables by implementing import() and turning your file into a module (perhaps not ideal for your situation), or using package variables which are visible throughout the execution of a program.

    HTH

    _________
    broquaint

      Filter::Include was the solution, thank you for that advice (and for your authorship). My intention was to write tests for a module. The test routines directly use not explicitly exported symbols in the module. I split the module and the tests in separate files, so I had to fully qualify the not explicitly exported symbols - very uncomfortable and not adequate for a module that knows so much about the the other. A workaround was "BEGIN { `cat x-module x-test>x`}; use x", but that was very ugly. "use Filter::Include; include "x-test" is much nicer. But there keeps one problem: Line numbering isn't considered; the including file and the included file are handled as one big file, so line numbers after the first inclusion are wrong. Bye, jds00.
        Thanks for the heads up on line numbering. As of version 1.4 that should be corrected thanks to the #line directive (although you'll also need Module::Locate, but it's dependencies are few and common).
        HTH

        _________
        broquaint

Re: #include files
by hmerrill (Friar) on Oct 24, 2003 at 13:32 UTC
    I might be misinterpretting, but sounds to me like you need to use the perl 'use' function. Typically, you would put code you want to 'include' into a perl module, and then in the script in which you want to 'use' that module, you would do something like:
    use My_Module;
    Doing
    perldoc perl
    and looking for 'module' shows these perldocs are available:
    perlmod Perl modules: how they work perlmodlib Perl modules: how to write and use perlmodstyle Perl modules: how to write modules with + style perlmodinstall Perl modules: how to install from CPAN perlnewmod Perl modules: preparing a new module fo +r distribution
    My guess is you want the 'perlmodlib' - how to write and use perl modules. So, at a command prompt, do
    perldoc perlmodlib
    HTH.
Re: #include files
by skx (Parson) on Oct 24, 2003 at 13:53 UTC

     One of the perl command line flags is "-P" which instructs perl to run the C preprocessor upon the source of the script.

     So "test.pl":

    print "Before\n"; #include "test2.pl" print "After\n";

     And test2.pl:

    print "During\n";

     Will do the right thing if you run "perl -P test.pl" - producing:

    Before
    During
    After
    

     However I suspect this isn'te really what you want to do - and the replies mentioning modules are the real solution to your problem.

     (OT: Using ActivePerl 'perl -P' crashes immediately under Windows, and has as long as I can remember. Weird.)

    Steve
    ---
    steve.org.uk
Re: #include files
by perrin (Chancellor) on Oct 24, 2003 at 17:34 UTC
    You can see symbols declared with "our", since those are globals. You'll have to refer to the globals by their fully-qualified names though, since the lexical alias created by "our" will not be available.

    I'd have to say, this all sounds like a really bad idea. You are asking for trouble by doing it this way as opposed to using modules with "use" or "require." You'll end up creating all kinds of action-at-a-distance problems that will make your code much harder to debug and maintain. I would strongly advise you to use modules instead.