in reply to Higher resolution $^T?

Interestingly, you can assign to $^T...

perl -le'$^T=42;print($^T)'

I've tested this in Perl 5.6.2, 5.8.9, and 5.20.0 with the same results. However, $^T is quite magic. You can assign a floating point number to it, but it will be rounded to an integer:

perl -le'$^T=42.3;print($^T)'

What's happening there? Well, the floating point number is actually stored correctly in Perl's SV structure. However any fetch will just get the integer instead.

perl -MDevel::Peek -le'$^T=42.3;Dump($^T)'

So even if you wrote a module to capture a more precise time, it couldn't be stored in $^T because that scalar is too magic.

use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

Replies are listed 'Best First'.
Re^2: Higher resolution $^T?
by ikegami (Patriarch) on Jun 23, 2014 at 02:17 UTC

    So even if you wrote a module to capture a more precise time, it couldn't be stored in $^T because that scalar is too magic.

    If something were to replace $^T, it would also replace the magic.

    >perl -E"undef(*^T); $^T = 1400000000.123; say $^T;" 1400000000.123

    Well, the floating point number is actually stored correctly in Perl's SV structure.

    When assigning to a variable with set magic, the value is assigned as normal, then the magic handler is called.

    When fetching from a magical variable with get magic, the magic handler is called to replace the value of the variable, then the fetch happens as normal.

    This means you see the value assigned to the scalar in the scalar, but that value is meaningless because it gets clobbered when you read from the scalar.

    The magic behind $^T is equivalent to the following:

    use Variable::Magic qw( cast wizard ); # The C var $^T mirrors is named PL_basetime # An IV (signed integer) on all systems except OS/2 and VMS. my $PL_basetime; cast($^T, wizard( # Copies into $^T before fetching from it. get => sub { ${ $_[0] } = $PL_basetime; }, # Copies from $^T after assigning to it. set => sub { $PL_basetime = ${ $_[0] }; }, ));

      But now you also kill the magic of -M and friends:

      $ perl -wE'say $^T;say -M ".";sleep 1;say -M ".";$^T=time;say -M ".";u +ndef*^T;$^T=1400000000.123;say -M "."' 1403502321 0.450798611111111111 0.450798611111111111 0.450810185185185185 0.450810185185185185

      Note that the last -M uses what was last stored in $^T before it was undef'd and not the value you put in it.


      Enjoy, Have FUN! H.Merijn