http://qs321.pair.com?node_id=1056913

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

While trying to clear up a few older bugs in a module I'm planning to take over, I found one I can't seem to wrap my head around. Take this:

use Tie::Scalar; tie (my $SLEEP_TIME, 'Tie::StdScalar', 0.25); select (undef, undef, undef, $SLEEP_TIME);

Tie::StdScalar is part of Tie::Scalar and does virtually nothing so parsing that mentally should result in a .25s sleep and then exit. But it doesn't. The code blocks as if $SLEEP_TIME was undefined. However, this...

use Tie::Scalar; tie (my $SLEEP_TIME, 'Tie::StdScalar', 0.25); print $SLEEP_TIME; select (undef, undef, undef, $SLEEP_TIME);

...works exactly as expected. The value of $SLEEP_TIME is printed and then select(...) sleeps a quarter second. According to Devel::Trace, my first example never calls the tied scalar's FETCH method but in my second example, it's correctly called twice: once for the print and again in the select statement.

I only have perl v5.16.3 installed so I'm not sure if this is a newly introduced bug or an old one. Before I bother fending off the dragons that inhabit p5p, anyone else have an idea or see this same behavior with newer/older versions of perl?

Update: Reported as RT#120102.

Replies are listed 'Best First'.
Re: tie(...) bug or select(...) bug?
by dave_the_m (Monsignor) on Oct 04, 2013 at 19:42 UTC
    It's a bug in select(), and is still present in blead. Looks like select() isn't calling get magic on the timeout arg.

    Here's another example of using a magic var which fails unless its magic value has been previously retrieved (using the commented-out line):

    "5" =~ /(\d)/; #$x = $1; select (undef, undef, undef, $1);
    You may want to perlbug this.

    Dave.

Re: tie(...) bug or select(...) bug (neither)?
by Anonymous Monk on Oct 04, 2013 at 18:32 UTC

    neither, read select, int $SLEEP_TIME is zero, which means block

      Yeah... not true and not the issue here. I could put tie(my $SLEEP_TIME, 'Tie::StdScalar', 5); and my first example would still block indefinitely. select(...) isn't correctly working with tie()'s magic to get the right value of $SLEEP_TIME and instead figures it's undef which is supposed to block. That's the bug I think I'm seeing.