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

I'm not really sure if that title fits, but basically I want to do this. Define a subroutine in a plain old text file, and then read that text file in by my perl code. In that text file there will be something like this:
sub some_func { print "this is a dynamic function...\n"; }

Then, basically, if I want to change the function I just have to change the text file. This will help me make a program dynamic. The program can download this text file on the internet, and bring in this new function-in-a-text-file and voila! (at least that is my grand plan).

Anyone know how to use maybe eval to read in this function and actually use it after its been eval'ed or something?

Thanks!

Justin Eltoft

"If at all god's gaze upon us falls, its with a mischievous grin, look at him" -- Dave Matthews

Replies are listed 'Best First'.
Re: dynamic sub routine definitions?
by jsprat (Curate) on Jul 17, 2002 at 02:38 UTC
    You can structure your code so that it uses more than one file. See use and require (and do, but you'll probably find use and require enough). Separating your code into logical units is actually a good practice when programming in just about any language.

    If that's not enough information for you (and it probably won't be enough), move on to perlmod and perlmodlib; then, last (but not least) try the CPAN for many examples.

Re: dynamic sub routine definitions?
by VSarkiss (Monsignor) on Jul 17, 2002 at 02:43 UTC

    Ah, a wheel waiting to be re-invented. ;-)

    The do function will do exactly what you describe: read in a file, compile it as Perl, and execute it. It's been around a while, and there are many better alternatives, such as require and use. For more information on the latter two, look at perlmod.

    However, being able to load and run a file will not make your program dynamic. You can't use stuff like this to replace an existing function definition, only to add a new one. What you want can be done, but requires more work: you need a level of indirection, so you can change the definition but keep the name. Possible, but difficult and very error-prone. Do you have a specific use in mind? (Other than "neat!" -- a valid reason, mind you.)

      Thank you both! Yes, this is actually what I want to do. I don't want to redefine a function. Just have a function that I can update and have those changes automatically show up by people running the app. So for me to change the programs behaviour a bit, I can just update this text file, and when the program is started, it checks for a newer version of this file. If there is one, it downloads it and then I can use the "require" function to just suck in that file and define whatever function it is.

      Thanks again for the help!

      Justin

      BZZZZZZZT! Please try again.

      You can't use stuff like this to replace an existing function definition, only to add a new one.

      You can too! You just have to be even neato-er.

      FILE1 ----- *{"::SomeFunc"} = sub { print "I'm neater than that!\n" } FILE2.pl -------- sub SomeFunc { print "I'm really neat\n"; } my $neato = 'FILE1'; do $neato; &SomeFunc;

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

        Please read what I wrote more carefully. The paragraph goes on to say:

        What you want can be done, but requires more work: you need a level of indirection.
        You just demonstrated my point: it can be done, but you had to go through the package hash (a level of indirection) to do it.

Re: dynamic sub routine definitions?
by bronto (Priest) on Jul 17, 2002 at 12:19 UTC

    Is it you that writes the "dynamic" code? If so, take a look at Exporter

    Ciao!
    --bronto

    Update Some sample snippets. Your "dynamic" code could look like:

    # This file is MyDynCode.pm package MyDynCode ; use strict ; use warnings ; use base 'Exporter' ; our @EXPORT = qw(dynamic) ; sub dynamic { print "runrunrunrunrun!!!" ; }

    ...and your code could import and run that function in a way like this:

    use strict ; use warnings ; my $dynapack = 'MyDynCode' ; eval "use $dynapack" ; die $@ if $@ ; dynamic() ;

    This one uses eval and use, but you could also use require and import: just change the eval and die lines with:

    require "$dynapack.pm" ; import $dynapack ;

    I hope this helps

    # Another Perl edition of a song:
    # The End, by The Beatles
    END {
      $you->take($love) eq $you->made($love) ;
    }

Re: dynamic sub routine definitions?
by Eradicatore (Monk) on Jul 17, 2002 at 03:17 UTC
    Hmm, one additional question though. Is there a way to do something like "require" but on a scalar variable? So let's say I read in this module file into $the_mod. I can't obviously just say "require $the_mod"... Thanks for any more ideas. If this isn't easy, then I'll just use it as a file, but it would be slightly nicer to do this in a variable for the way I'm setup. Thanks!

    Justin

      perldoc -f eval. Also, beware of eval'ing, use'ing, require'ing, or do'ing downloaded code, even if you think you know where it came from. There are about a billion ways to exploit a program like that.
      Hmm, one additional question though. Is there a way to do something like "require" but on a scalar variable? So let's say I read in this module file into $the_mod. I can't obviously just say "require $the_mod"
      my $mod = "Carp.pm"; require $mod; Carp::croak ("Oh yes, you can.\n");

      Abigail

        Thanks again! I wasn't clear enough though in my question. What I mean was, if I have $var set to some big long string that is really a function (not a file name) then could I then say something like "require $var"?

        Justin Eltoft

        "If at all god's gaze upon us falls, its with a mischievous grin, look at him" -- Dave Matthews