in reply to Way of the Spinner (repost)

My personal favorite (which is basically a cleaner implementation of what you have above) is
use Tie::Cycle; tie my $spinner, 'Tie::Cycle', [map "\b$_",qw(\ | / -)]; print $spinner while (1);
Please do a super search on "spinner". You will find a variety of solutions. :-)

Its your call as to whether yours or mine or anyone elses is better. Probably depends on the circumstances. IMO however its hard to improve on the Tie::Cycle version, if only because it generalizes the entire thing to about as abstract a level as can be done, which of course maximizes the possibility of code reuse.

Cheers,

--- demerphq
my friends call me, usually because I'm late....

Replies are listed 'Best First'.
Re: Re: Way of the Spinner (repost)
by TheDamian (Vicar) on Jan 18, 2003 at 19:06 UTC
    Or if, like most geeks, you have an aversion to a visible tie, you can make the interface much cleaner with:
    use Attribute::Handlers; use Tie::Cycle; sub UNIVERSAL::Spinner : ATTR(SCALAR) { tie ${$_[2]}, 'Tie::Cycle', [map $_."\b" x length, @{$_[4]||[qw(\ | / -)]}] }

    And then whip up custom spinners very elegantly, as the need arises:

    $|=1; my $spinner : Spinner; print $spinner for (1..10000); my $morse_blinker : Spinner( qw(! : .) ); print $morse_blinker for (1..10000); my $wobbler : Spinner( "\)", "\(" ); print $wobbler for (1..10000); my $flexer : Spinner( '< ', ' >' ); print $flexer for (1..10000);
      TheDamian that was exactly what I ultimately wanted to achieve but had no idea how. A definate ++ to you. The Attribute::Handlers is a new module to me so I'll go and look it up.

      Thanks

      !unlike
      "The price if ignorance, which is of course that you must learn from those who know." Scorates (paraphrased)
      Cool!

      Although I admit until now ive been one of those geeks that doesnt mind the explicit Tie.

      :-)

      --- demerphq
      my friends call me, usually because I'm late....

Re: Re: Way of the Spinner (repost)
by HamNRye (Monk) on Jan 17, 2003 at 22:07 UTC

    Any way to keep this from spinning like a top?? Tried it out and on my 2.4GHZ system, it is almost a white circle.

    ~Hammy

      You can use the select() function to do short sleeps. If your system doesn't support a four-argument select(), you can use the Time::HiRes module. For the select function, the last argument reflects the time to sleep. This comes right out of O'Reilly's Perl Cookbook:
      while (<>) { select(undef, undef, undef, 0.25); print; }
      Using Time::HiRes, we'd write it as:
      use Time::HiRes qw(sleep); while (<>) { sleep(0.25); print; }
      Funny thing is that I used nearly the same method of making a spinner a while back...and I had the exact same question about slowing it down. Hope this helps!
        Oops. I Posted the above about the select() function Anonymously. So if it doesn't work, you now know who to flame :) Joe
      Funny you ask that. My origianl version was something like the following (adjust $delay according to the speed of your system)
      use Tie::Cycle; my $delay=100; tie my $spinner, 'Tie::Cycle', [map {("\b$_") x $delay} qw(\ | / -)];
      which is an approach I prefer to sleeping, as normally you put a spinner in a time sensitive loop so that you know its doing something... Also when ive used this the actual work happening in the loop is complicated (ie slow enough) that the spinner turns at a reasonable speed. In fact from a diagnostic POV its probably better to let it spin freely with no delay at all. That way you can observe the underlying task slow down or speed up (for whatever reason). For example you might use it when reading a file into a hash. When the hash starts having to resize itself you can observe the spinner stop briefly. Or when doing a massive DB update you can see the load on your network and DB server....

      Cheers,

      --- demerphq
      my friends call me, usually because I'm late....