Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

I'm trying to come up with some code to detect if a scalar variable contains a number or string. The difficulty is that I want to detect objects which have the appropriate conversion and comparison operators overloaded.

The reason is that it's common to insist that certain values be strings or numbers, but checks for them that rule out references will rule out objects that have numberlike or stringlike behaviour (such as BigInts or custom classes). So I want to know that references (blessed things) refer to objects which act just like numbers or strings.

This turns out to be not-so-simple for the case of numbers.

According to the perlfunc manpage on sort, I should be able to use <=> to compare things, and if it's NaN, it turns out undefined. I think the page is outdated. The following turns out true in ActiveState Perl Build 810 (Perl 5.8.4):

$a = 'string'; if (defined ($a <=> $a)) { print "Oops"; }

The == operator also seems to work for NaNs (Not-a-Numbers) when it's not supposed to.

I do know there's been discussions/complaints in the past about how bad it is when Perl distinquishes between == and eq (and found this frustrating when I was a Perl newbie...) but the docs should have been updated if this was changed. Was it changed???

Furthermore, I seem to have run into the following hiccup from overload:

package Foo; use overload '0+' => \&as_num; sub new { my $class = shift; my $self = { value => shift }; bless $self, $class; } sub as_num { my $self = shift; return $self->{value}; } package main; my $x = new Foo(3); my $z = (0+$x); # $x+0 also produces error

I run this and get the following error: "Operation `+': no method found, left argument has no overloaded magic, right argument in overloaded package Foo at bug.pl line 22."

This is based on a section from the cookbook in the overload manpage!

So my attempts to detect if 0+$num do not work.

To add to this, it seems that the looks_like_number function in the Scalar::Util module is broken, in that it says some references are numbers:

use Scalar::Util 'looks_like_number'; my $a = [ ]; my $h = { }; print looks_like_number($a), "\n"; print looks_like_number($h), "\n";

The code I was experimenting with was the following:

sub _numberlike { return 1, unless defined $_[0]; # L<perlfunc> manpage notes that NaN != NaN, so we can verify that # numeric conversion function works properly along with the # comparison operator. no warnings; return 1 if ((!ref $_[0]) || blessed($_[0])) && eval { ((0+$_[0]) == (0+$_[0])) && (($_[0] <=> $_[0])==0) }; return; }

In case you're interested, the "stringlike" function I have (which seems to work) is:

sub _stringlike { return 1 unless defined $_[0] && ref $_[0]; return 1 if (blessed $_[0]) && eval { (("$_[0]" eq "$_[0]") && (($_[0] cmp $_[0])==0)) }; return; }

To explain how these work, I am checking that the appropriate number/strong conversions work, and that the comparison operators work. Overload is supposed to create the less than/greater than variations from the comparison operators. For my purposes, these are all that I need to check for.

Also.... you might recognize this issue from some posts of mine on the module-authors list.


In reply to Detecting if a scalar has a number or string by rrwo

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2024-04-25 09:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found