Front page | perl.beginners |
Postings from June 2023
Re: type checks
Thread Previous
|
Thread Next
From:
sisyphus
Date:
June 3, 2023 12:16
Subject:
Re: type checks
Message ID:
CADZSBj3uG42R9x1YOvDvUQYW1Sc+P=R1mTPZMAe3yk0aGq5VHQ@mail.gmail.com
On Sat, Jun 3, 2023 at 6:41 PM Claude Brown <claude.brown@gigacomm.net.au>
wrote:
> Interesting. I’d not used “B” before, so doing a little reading on that
> was fun, plus seeing how you had used it.
>
>
>
> Question: why did you have “is_ok” return 2 and 3, rather than just 1?
>
The way I've coded the "oload_*" subroutines there's a need to know whether
the second arg ($_[1]) is a Math::NumOnly object or a perl scalar.
Having is_ok return 1 for a Math::NumOnly object and a different value for
a valid perl scalar allows those subroutines to make that determination.
Of course, there's no apparent reason that we need to distinguish between
an IV (integer) scalar and an NV (float) scalar - so I could have just
returned "2" for both, rather than "2" for the IV and "3" for the NV.
(The OP's spec mentioned only integer values, and I initially considered
the possibility that there might be a need to distinguish between IVs and
NVs.)
And I must give credit where credit is due:
The B module stuff I used is stolen from:
https://metacpan.org/release/HAARG/Sub-Quote-2.006006/source/t/quotify.t
It has since occurred to me that there's a simpler solution that meets the
OP's spec - one that doesn't involve the creation of a specially designated
module.
Firstly, you just take the declaration of %flags as presented in
Math::NumOnly:
#########################
use B;
my %flags;
{
no strict 'refs';
for my $flag (qw(
SVf_IOK
SVf_NOK
SVf_POK
)) {
if (defined &{'B::'.$flag}) {
$flags{$flag} = &{'B::'.$flag};
}
}
}
#########################
However, you alter is_ok() to either return the numeric value of the scalar
(if that scalar satisfies the OP's spec); otherwise the sub croaks:
#########################
sub is_ok {
die "Undefined value encountered" unless defined $_[0];
my $val = shift;
my $flags = flags($val);
die "Bad value encountered" if $flags =~ /SVf_POK/;
return $val
if $flags =~ /SVf_IOK|SVf_NOK/;
die "Bad value encountered";
}
#########################
Then, in your perl script, instead of doing:
$z = $x + $y;
you do:
$z = is_ok($x) + is_ok($y);
For example, the following code would result is $z being set to 7:
$x = 4;
$y = 3;
$z = is_ok($x) + is_ok($y);
But the following would die:
$x = 4;
$y = '3';
$z = is_ok($x) + is_ok($y);
Similarly, instead of doing:
$x += $y;
you would do:
is_ok($x) += is_ok($y);
and $x would be set to $x * $y if both $x and $y meet the spec; otherwise
the script dies.
Cheers,
Rob
Thread Previous
|
Thread Next