Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

comment on

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

You seem to have quite a number of issues here. The most important one that's keeping you from getting where you want is that your actuall wishes and your statement of your wishes don't match. You asked for a method "...that references (blessed things) refer to objects which act just like numbers or strings."

Then you get that "asdf" is a valid number, and call it a problem. That's what you asked for: perl -le 'print "asdf"+42;'.

Then, you make a mad rush though different bits of perl, and point out problems, without an understanding of the features, and why the problems aren't problems. You're misenterpreting the stuff about NaN and perl's arithmetic. That isn't refering to strings (since all strings are numbers -- some are just more numeric numbers then others) -- it's refering to a special sort of thing, which you get out of some sorts of strange math, but isn't a number -- generally, things that mathematicians prefer to call "undefined forms". perl -le 'print sin(9**9**9)' is a good example of a nan -- the sine of infinity is undefined. A NaN is, indeed, not equal to any other thing, even another NaN: <perl -le 'print sin(9**9**9)==sin(9**9**9)'

The problem you're having with overload is simple. The error message says almost everything you need to know. Read the defintion of fallback in overload as well. Figure it out yet? Your class doesn't specify any way of handling +. Not only that, it doesn't tell overload to try to autogenerate a way to handle it (using 0+ and normal addition). Try adding fallback=>1 in your use overload line. (Note: To be fair, I'm not clear on why it doesn't work under fallback=undef mode either.)

Your problem with looks_like_number is another one where you don't take into account perl's normal rules for numberhood. All references are numbers. Not only that, they're all nonzero numbers. perl -le 'my $a=[]; print "".$a, " == ", 0+$a;'.

So, what is it you really want? You want a function, is_numeric, taking a single argument. If that argument is undef, then I assume it's not supposed to be considered numeric:

sub is_numeric { local $_=shift; return if not defined $_; }
If it's not a reference, then Scalar::Util::looks_like_number is good.
use Scalar::Util 'looks_like_number'; sub is_numeric { local $_=shift; if (!ref $_) { return looks_like_number($_); } }
Unblessed references are not numbers (says you).
use Scalar::Util 'looks_like_number', 'blessed'; sub is_numeric { local $_=shift; if (!ref $_) { return looks_like_number($_); } if (!blessed $_) { return; } }
References into packages that don't use overload are not numbers (says you).
use Scalar::Util 'looks_like_number', 'blessed'; require overload; sub is_numeric { local $_=shift; if (!ref $_) { return looks_like_number($_); } if (!blessed $_) { return; } if (!overload::Overloaded $_) { return; } }
Now, you have to figure out somehow if a package which does implement overloading is numeric or not... but you haven't given a definition anywhere that I can see as to what that means. That's quite a problem... because the point of overload is to make things that don't act quite like numbers or quite like strings. There may be perfectly valid reasons why $a != $a, or where $a - $a != 0, or anything else that a poor mathematician would take as completely axiomatic.

Have you considered asking it?

<code> use Scalar::Util 'looks_like_number', 'blessed'; require overload; sub is_numeric { local $_=shift; if (!defined $_) { return; } if (!ref $_) { return looks_like_number($_); } if (!blessed $_) { return; } if (!overload::Overloaded $_) { return; } if ($_->can('is_numeric')) { return $_->is_numeric; } # or just return; if it should be false per default return 1; }

Update: changed ref $_ to !ref $_, thanks, dragonchild, for the /msg.


Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).


In reply to Re: Detecting if a scalar has a number or string by theorbtwo
in thread 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 making s'mores by the fire in the courtyard of the Monastery: (7)
As of 2024-04-19 10:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found