rementis has asked for the wisdom of the Perl Monks concerning the following question:
I have a perl script which presents the user with a menu. Every few minutes the user will select an option, a subroutine is called, and then back to the menu. This is all well and good and works fine. I do, however, want to occasionally (maybe once every 5 minutes for example) run a subroutine without any input from the user.
I have looked at a few different timers/schedulers in cpan but I can't seem to find anything that fits this situation in a elegant fashion. I now turn to you all-knowing purveyors of wisdom!
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Run subroutine occasionally
by tybalt89 (Monsignor) on Mar 01, 2022 at 02:12 UTC | |
Just for fun (and because I haven't done a ReadKey in a while), here's my guess at a structure for what you are asking.
Of course, replace the sleeps with your subs, and more work would be required if you have more than 9 menu items. | [reply] [d/l] |
|
Re: Run subroutine occasionally
by tybalt89 (Monsignor) on Feb 28, 2022 at 22:56 UTC | |
perl/Tk
| [reply] |
|
Re: Run subroutine occasionally
by haukex (Archbishop) on Feb 28, 2022 at 22:59 UTC | |
You haven't told | [reply] [d/l] |
|
Re: Run subroutine occasionally
by Marshall (Canon) on Mar 01, 2022 at 00:11 UTC | |
runs someSub repeatedly. Of course, sub someSub{} should run "quickly" or the GUI will "freeze". Update: I re-read the question and perhaps I made an incorrect about this being a Tk GUI? If so, the OP needs to clarify. Update with Code for a GUI:
| [reply] [d/l] [select] |
|
Re: Run subroutine occasionally
by stevieb (Canon) on Mar 01, 2022 at 18:59 UTC | |
My Async::Event::Interval does this. It takes a callback as a parameter, and runs it at a given interval (in seconds). The callback is run in a separate process. Example:
Output:
An interval (first parameter to the new() method) of 0 (zero) will only run the routine once, but you can run it again at any time by calling $delayed_event->start if $delayed_event->waiting;. Floating point intervals are also supported if one needs such granularity. | [reply] [d/l] [select] |
|
Re: Run subroutine occasionally
by cavac (Prior) on Mar 02, 2022 at 11:45 UTC | |
You have not told us any details, so it's hard to guess what user interface you are using and what you are trying to do. If you want to make sure your "subroutine" doesn't block the UI, running it in a different program altogether with interprocess messaging might be an option. This would also allow for the cyclic function to continue running without the UI open. All this depends on your requirements and all the details you haven't provided, though. As for me, i usually use Net::Clacks for that stuff (of course, as the author of that module, i'm a bit biased). There are examples of a simple chat system, complete with chatbot and clock bot, if you are interested. Explanation is provided in this (slightly outdated) post: Interprocess messaging with Net::Clacks
perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'
| [reply] [d/l] |
|
Re: Run subroutine occasionally
by marioroy (Prior) on Mar 02, 2022 at 19:56 UTC | |
The yield function in MCE::Child (ditto for MCE::Hobo) retains interval periods; i.e. do something at/near every N fractional seconds. It works quite well, even among many workers.
Demonstration Notice the output for the next demonstration where the child displays output every 0.2 seconds, even simulating work. It does a delta behind the scene from the last yield statement in order to retain near/exact intervals.
Output
| [reply] [d/l] [select] |
by marioroy (Prior) on Mar 03, 2022 at 03:19 UTC | |
The following is a demonstration spawning 2 child processes. Yield is an exclusive action causing other worker(s) to wait till the next interval period, as seen in the output. Demonstration 2
Output
| [reply] [d/l] [select] |