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