Using the B module to access a variable's flags is annoyingly clunky.
It's much simpler using Inline::C (or  XS), which is my usual (and
preferred) method:

################################
# Filename: try_inline.pl
use strict;
use warnings;

use Inline C => Config =>
  BUILD_NOISY => 1,
;

use Inline C => <<'EOC';

SV* is_ok(SV* val) {
  if(SvPOK(val)) croak("String value encountered");
  if(SvIOK(val)) {
    IV iv = SvIVX(val);
    if(SvIsUV(val)) return newSVuv(iv);
    return newSViv(iv);
  }
  if(SvNOK(val)) {
    NV nv = SvNVX(val);
    return newSVnv(nv);
  }
  croak("Bad value encountered");
}

EOC

my $x = -4;
my $y = 3;
my $z = is_ok($x) + is_ok($y);
print $z, "\n";

my $mul = 11;
is_ok($x);
$x *= is_ok($mul);
print $x, "\n";

$mul = is_ok(3) / is_ok(19);
print $mul, "\n";

$mul *= is_ok(10.1);
print $mul, "\n";

my $uv_max = is_ok(~0);
print $uv_max, "\n";

my $sqrt2 = sqrt(is_ok(2));
print $sqrt2, "\n";

my $nok = sqrt(is_ok('4.0')); # croaks
print $nok, "\n";
################################

Outputs:
-1
-44
0.157894736842105
1.59473684210526
18446744073709551615
1.4142135623731
String value encountered at try_inline.pl line 49.

Cheers,
Rob

Reply via email to