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