Question 2: How to reload a module without having to use an eval (like eval "My::Run()")
Reloading a module will always end in a string eval, like loading a module does. Remember or read the docs:
- use Some::Module ...; is exactly equivalent to BEGIN { require Some::Module; Some::Module->import(...); }
- require Some::Module; behaves like a 50 line wrapper around do "$prefix/Some/Module.pm" searching for Some/Module.pm along @INC and updating %INC.
- do "$prefix/Some/Module.pm" behaves much like $text=readFile("$prefix/Some/Module.pm"); eval $text;, searching @INC and setting %INC (and $@ and perhaps $! on error).
So, in EVERY use and require, a string eval is hidden. And that string eval will happen unless the requested module has already been loaded. If you load or reload a module at runtime, there will always be a string eval. So a simple eval "require Some::Module" does not hurt much. Of course, you can manually search for the module and do a require "$prefix/Some/Module.pm", but it will still hide a string eval.
Another way to reload updated modules is to just re-execute your script. Store $^X, $0 and @ARGV at startup, then when you feel the need to reload modules, run something like exec { $^X } $^X,$0,@ARGV; die "Re-exec failed: $!";. This will completely restart your script, loading all modules again. Of course, there are limitations:
- Your operating system may not support exec, in that case, perl may provide a rough emulation (Windows - see exec in perlport).
- If your STDIN comes from something like a socket or a terminal, the data you have already processed is lost.
- Some operating systems do not flush output file handles on exec, so some output may be lost. Again see exec in perlport.
- If your script generates some "startup noise" (e.g. write a header to STDOUT), that will probably be repeated unless you find a way to detect a re-exec. Adding a flag to %ENV or the stored copy of @ARGV might be an idea.
- All variables are lost. You must be able to regenerate the state of your program from the available input at the time of exec. If you can't, saving essential state information to a file (JSON, Storable) before exec and reading it back after exec might be an idea.
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.