in reply to Printing to stdout an array of strings and scalar references
"I am looking for any suggestions ... that might lead to a more elegant solution."
One of the benefits of using lexical variables is that you can control their scope. Declaring all your variables at the start of runtime, and giving them file-scope, defeats this. You should use the smallest scope possible. You should generally also pass variables to your subroutines: there are exceptions to this such as in the code below; although, do note the anonymous block limiting the scope of the variables not passed in the function call (see also state for an alternative way to handle this).
Using an arrayref, as you've shown, is not something I would do. Using one of the string formatting functions (sprintf in the code below) would be a better choice. Adding a newline to each line of output, actually creates something more like a log than a progress indicator. Starting each output line with a carriage return (\r) is not doing what I think you hoped it would; the usual way to handle this is to use backspaces (\b) and then write the new indicator lines, effectively overwriting the previous indicator line.
Also note that writing lines without a terminal newline can cause buffering problems. I've set the special variable "$|" to overcome this; and localised that change so that it doesn't affect other I/O.
Here's example code implementing those techniques.
#!/usr/bin/env perl use strict; use warnings; my @files = map { "file_$_" } 5 .. 14; for (0 .. $#files) { show_progress(\@files, $_); # Process $files->[$_] here. For testing: sleep 1; } show_done(); { my ($prog_fmt, $last_msg_len); BEGIN { $prog_fmt = 'Processing "%s" (%d of %d) ...'; $last_msg_len = 0; } sub show_progress { my ($files, $index) = @_; local $| = 1; my $clear = "\b" x $last_msg_len; my $msg = sprintf $prog_fmt, $files->[$index], 1+$index, 0+@$f +iles; $last_msg_len = length $msg; print $clear, $msg; return; } } sub show_done { print "\nProcessing completed.\n"; return; }
The first line of output looks like this:
Processing "file_5" (1 of 10) ...
That line is continually overwritten. The final output looks like this:
Processing "file_14" (10 of 10) ... Processing completed.
— Ken
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Printing to stdout an array of strings and scalar references
by Anonymous Monk on Oct 25, 2017 at 02:39 UTC | |
by kcott (Archbishop) on Oct 25, 2017 at 07:10 UTC |