Elegant ways to convert '' or 'number' to a number

Discussion in 'Perl Misc' started by Tim McDaniel, Feb 14, 2012.

  1. Tim McDaniel

    Tim McDaniel Guest

    So a cow-orker has the result of a database query. It's being
    returned as a string: it contains an integer or it's a null string.
    (Yes, we're certain.) He wants to use it in a numeric context, but is
    getting
    Argument "" isn't numeric in numeric eq (==) at FILE line NUMBER.
    warnings (as we have "use warnings" on). I had had the impression
    that "+ 0" would do the conversion and avoid a warning, but that's not
    the case.

    Is there an elegant idiom for converting such a string to a number
    without producing a warning if it happens to be a null string?

    * $t = $t ? 0+$t : 0;
    is not what I would call "elegant", especially in this case, where
    it's not $t but $alonghashtablename{AVERYLONGHASHINDEXNAME}.

    * $t = "0$t" + 0;
    isn't so elegant either (though at least it does not convert to
    octal, as I first wondered).

    * $t ||= 0;
    doesn't give you a number per se, but at least the string converts
    to a number in numeric contexts without a warning.

    * ($t ||= 0) += 0;
    Its main virtue is that it converts it to a number and only uses $t
    once.

    I'm thinking that
    { no warnings 'numeric'; $t += 0; }
    is the best choice. It has the great virtue of being abundantly clear
    on what they want, as opposed to a person reading having to figure out
    some hack that happens to do it without a warning.

    I should note that we're using 5.8.8 and NO I have no way whatsoever
    of changing that.

    --
    Tim McDaniel,
    Tim McDaniel, Feb 14, 2012
    #1
    1. Advertising

  2. Tim McDaniel

    J. Gleixner Guest

    On 02/14/12 15:37, Tim McDaniel wrote:
    > So a cow-orker has the result of a database query.



    I didn't know cows used databases.. :)

    > It's being
    > returned as a string: it contains an integer or it's a null string.
    > (Yes, we're certain.) He wants to use it in a numeric context, but is
    > getting
    > Argument "" isn't numeric in numeric eq (==) at FILE line NUMBER.
    > warnings (as we have "use warnings" on). I had had the impression
    > that "+ 0" would do the conversion and avoid a warning, but that's not
    > the case.


    If you need to have warnings enabled, for some reason, then it might
    be cleaner to fix the source of the problem. e.g. the SQL ...
    ISNULL or NVL or IFNULL or ....

    I generally don't 'use warnings' in production, because of these and the
    uninitialized warnings. Just lazy, I guess.

    Another solution, don't try to modify the value, just shortcut it and
    only let it try the numeric test, it if it's defined:

    if( defined $val && $val == 1234 )

    That won't help when printing $val though..
    J. Gleixner, Feb 14, 2012
    #2
    1. Advertising

  3. Tim McDaniel

    Tim McDaniel Guest

    In article <>,
    Ben Morrow <> wrote:
    >
    >Quoth :
    >> Is there an elegant idiom for converting such a string to a number
    >> without producing a warning if it happens to be a null string?

    >
    >By 'null string' you mean an empty string, not undef, right?


    Yes. I agree with Cerebron on dragons: the concepts ought to be kept
    rigidly distinct.

    --
    Tim McDaniel,
    Tim McDaniel, Feb 15, 2012
    #3
  4. (Tim McDaniel) writes:
    > In article <>,
    > Ben Morrow <> wrote:
    >>
    >>Quoth :
    >>> Is there an elegant idiom for converting such a string to a number
    >>> without producing a warning if it happens to be a null string?

    >>
    >>By 'null string' you mean an empty string, not undef, right?

    >
    > Yes. I agree with Cerebron on dragons: the concepts ought to be kept
    > rigidly distinct.


    They are not different concepts and Perl and have never been different
    concepts in Perl: Perl is one of those 'messy' languages designed
    around the idea that automatic conversions are a good thing because
    they reduce the amount of boilerplate code people need to write (and
    other people need to read). Other languages have been designed in
    different ways and might be more suitable who consider those different
    ways essential.
    Rainer Weikusat, Feb 15, 2012
    #4
  5. Tim McDaniel

    Tim McDaniel Guest

    In article <>,
    Rainer Weikusat <> wrote:
    > (Tim McDaniel) writes:
    >> In article <>,
    >> Ben Morrow <> wrote:
    >>>
    >>>Quoth :
    >>>> Is there an elegant idiom for converting such a string to a
    >>>> number without producing a warning if it happens to be a null
    >>>> string?
    >>>
    >>>By 'null string' you mean an empty string, not undef, right?

    >>
    >> Yes. I agree with Cerebron on dragons: the concepts ought to be
    >> kept rigidly distinct.

    >
    >They are not different concepts and Perl and have never been
    >different concepts in Perl


    They can be distinguished via defined(). They cause different
    warnings (uninitialized value).

    More fundamentally, I do consider it worthwhile to distinguish between
    different values of missing data.

    --
    Tim McDaniel,
    Tim McDaniel, Feb 15, 2012
    #5
  6. (Tim McDaniel) writes:
    > In article <>,
    > Rainer Weikusat <> wrote:
    >> (Tim McDaniel) writes:
    >>> In article <>,
    >>> Ben Morrow <> wrote:
    >>>>
    >>>>Quoth :
    >>>>> Is there an elegant idiom for converting such a string to a
    >>>>> number without producing a warning if it happens to be a null
    >>>>> string?
    >>>>
    >>>>By 'null string' you mean an empty string, not undef, right?
    >>>
    >>> Yes. I agree with Cerebron on dragons: the concepts ought to be
    >>> kept rigidly distinct.

    >>
    >>They are not different concepts and Perl and have never been
    >>different concepts in Perl

    >
    > They can be distinguished via defined(). They cause different
    > warnings (uninitialized value).


    They are not disinguishable for their 'string value' because automatic
    conversions are done by Perl as required, as I already wrote. Provided
    run-time warnings are enabled, some pretty random looking subset of
    the situations where such an automatic conversion takes places cause
    some text to be printed. That's an optional feature some people
    consider to be useful (primarily for others, as it seems ...).

    > More fundamentally, I do consider it worthwhile to distinguish between
    > different values of missing data.


    http://en.wikipedia.org/wiki/Law_of_excluded_middle
    Rainer Weikusat, Feb 15, 2012
    #6
  7. Tim McDaniel

    Tim McDaniel Guest

    In article <>,
    Rainer Weikusat <> wrote:
    > (Tim McDaniel) writes:
    >> In article <>,
    >> Rainer Weikusat <> wrote:
    >>> (Tim McDaniel) writes:
    >>>> In article <>,
    >>>> Ben Morrow <> wrote:
    >>>>>
    >>>>>Quoth :
    >>>>>> Is there an elegant idiom for converting such a string to a
    >>>>>> number without producing a warning if it happens to be a null
    >>>>>> string?
    >>>>>
    >>>>>By 'null string' you mean an empty string, not undef, right?
    >>>>
    >>>> Yes. I agree with Cerebron on dragons: the concepts ought to be
    >>>> kept rigidly distinct.
    >>>
    >>>They are not different concepts and Perl and have never been
    >>>different concepts in Perl

    >>
    >> They can be distinguished via defined(). They cause different
    >> warnings (uninitialized value).

    >
    >They are not disinguishable for their 'string value' because
    >automatic conversions are done by Perl as required


    Nevertheless, they are different concepts, although there is only one
    place (defined()) where code can tell the difference, so far as I
    know.

    --
    Tim McDaniel,
    Tim McDaniel, Feb 15, 2012
    #7
  8. Tim McDaniel

    ccc31807 Guest

    On Feb 14, 4:37 pm, (Tim McDaniel) wrote:
    > So a cow-orker has the result of a database query.  It's being
    > returned as a string: it contains an integer or it's a null string.
    > (Yes, we're certain.)  He wants to use it in a numeric context,
    > Is there an elegant idiom for converting such a string to a number
    > without producing a warning if it happens to be a null string?


    What's wrong with using int(), or sprintf()?

    I had a similar problem, but the reverse. I used person ID numbers as
    keys in a hash table, and manipulated the values in various ways,
    which included Microsoft Excel. I kept getting aggravating errors over
    a long time, and after one experience went through the results line by
    line and discovered that sometimes ID numbers with leading zeros were
    treated like real numbers, and a value like '4321' does not match a
    hash key like '0004321'.

    I started using sprintf() when in doubt, and it solved the problem. I
    just convert whatever the value is into a string, and it preserves the
    leading zeros.

    If you want to reverse the process, int() would probably work and be
    less verbose than sprint().

    CC.

    CC.
    ccc31807, Feb 15, 2012
    #8
  9. On 14 Feb 2012 (Tim McDaniel) wrote in
    news:jhek67$dpd$:

    > So a cow-orker has the result of a database query. It's being
    > returned as a string: it contains an integer or it's a null
    > string.


    Has he though of changing the query. You don't say what DB he's using
    but the following should work in MSSQL and I would expect similar to
    be possible in other DBMSs.

    Instead of
    "SELECT
    column
    from table"

    use

    "SELECT
    case
    when column is null then 0
    else column
    end
    from table"
    Graham Drabble, Feb 15, 2012
    #9
  10. Tim McDaniel

    Tim McDaniel Guest

    In article <>,
    ccc31807 <> wrote:
    >On Feb 14, 4:37 pm, (Tim McDaniel) wrote:
    >> So a cow-orker has the result of a database query. It's being
    >> returned as a string: it contains an integer or it's a null string.
    >> (Yes, we're certain.) He wants to use it in a numeric context,
    >> Is there an elegant idiom for converting such a string to a number
    >> without producing a warning if it happens to be a null string?

    >
    >What's wrong with using int(),


    The part about "without producing a warning if it happens to be a null string".

    $ perl -e 'use warnings; int("")'
    Argument "" isn't numeric in int at -e line 1.

    Since it does happen to be an integer or the null string, I think "0+"
    is equivalent to int().

    > or sprintf()?


    Not sure what you mean in this case. Do you mean this?

    $ perl -e 'use warnings; my $x = sprintf("%d", ""); print "[$x]\n"'
    Argument "" isn't numeric in sprintf at -e line 1.
    [0]

    --
    Tim McDaniel,
    Tim McDaniel, Feb 15, 2012
    #10
  11. (Tim McDaniel) writes:
    > Rainer Weikusat <> wrote:
    >> (Tim McDaniel) writes:
    >>> Rainer Weikusat <> wrote:
    >>>> (Tim McDaniel) writes:


    [...]

    >>>>>>By 'null string' you mean an empty string, not undef, right?
    >>>>>
    >>>>> Yes. I agree with Cerebron on dragons: the concepts ought to be
    >>>>> kept rigidly distinct.
    >>>>
    >>>>They are not different concepts and Perl and have never been
    >>>>different concepts in Perl
    >>>
    >>> They can be distinguished via defined(). They cause different
    >>> warnings (uninitialized value).

    >>
    >>They are not disinguishable for their 'string value' because
    >>automatic conversions are done by Perl as required

    >
    > Nevertheless, they are different concepts, although there is only one
    > place (defined()) where code can tell the difference, so far as I
    > know.


    They are 'something different' at the perl implementation level. If
    they are also 'something different' for a particular application of
    Perl to some problem depends on the problem: Values usually have types
    and such a type is the set of all valid values for a particular
    'thing'. If this set includes some kind of 'null value', something
    which is technically legitimate but no operations save than comparing
    it to other valid values may be used on it and the result will always
    be "it's differen", Perl default-value scalars can be used to
    represent this 'null value'. An example of that would be DBI which
    represents the SQL concept of 'the null value' in this way. OTOH, if
    I'm dealing with the values from the mod 256 factor ring, treating the
    same default value scalar as a variable which is automatically
    initialized to a value of 0 will often be more convenient, no matter
    how thoroughly the very idea combs zealous beancounters against the
    grain (I have no idea if this works in English, just some web-research
    based hopes that it does).
    Rainer Weikusat, Feb 16, 2012
    #11
  12. Tim McDaniel

    ccc31807 Guest

    On Feb 15, 6:10 pm, (Tim McDaniel) wrote:
    > >What's wrong with using int(),

    >
    > The part about "without producing a warning if it happens to be a null string".


    Sorry, I guess I didn't notice that.

    Here is a common idiom that I employ a lot:

    $x ||= 0;

    Obviously, this only applies when $x does not contain any value.

    When validating data, for example, ensuring that a field contains
    something similar to an email address, I do this a lot:

    $x ||- '';

    or

    $x = '' unless $x =~ /\w+\@.\w+/;

    Finally, if you automate your scripts, perhaps by using a cron job or
    a scheduled task, no one sees the warnings. In many (most?) of my
    production scripts, I don't disable warnings. My users never see the
    warnings, but only the output -- however, when I run the scripts in
    real time, I see the warnings, and somehow that reassures me that
    everything's right with the world.

    CC.
    ccc31807, Feb 16, 2012
    #12
  13. ccc31807 <> writes:

    [...]


    > Finally, if you automate your scripts, perhaps by using a cron job or
    > a scheduled task, no one sees the warnings.


    FYI: Usually, cron will mail the stdout and stderr output of a cronjob to
    the user whose cronjob it was.
    Rainer Weikusat, Feb 16, 2012
    #13
  14. Tim McDaniel

    Tim McDaniel Guest

    In article <>,
    Rainer Weikusat <> wrote:
    >If they are also 'something different' for a particular application
    >of Perl to some problem depends on the problem


    Hm. I think I agree with your point. Perhaps I might put it that,
    from the point of view of "duck typing", what matter is what you want
    to do with it and what the language conveniently allows.

    I'm not sure whether it's my FORTRAN and C background, or my general
    anal-retentiveness, that makes me focus too much on types and to look
    with suspicion on Perl's builtin conversions, instead of relaxing and
    letting Perl deal with it -- in the case I was asking about, letting
    the "==" operator handle the conversion.

    >no matter how thoroughly the very idea combs zealous beancounters
    >against the grain (I have no idea if this works in English, just some
    >web-research based hopes that it does).


    "Beancounter", as I've heard it, refers specifically to accountants,
    and that word doesn't have connotations that work here. I'd say
    "no matter how thoroughly the very idea rubs pedants the wrong way".

    --
    Tim McDaniel,
    Tim McDaniel, Feb 16, 2012
    #14
  15. On 2012-02-16 20:21, Rainer Weikusat <> wrote:
    > ccc31807 <> writes:
    >> Finally, if you automate your scripts, perhaps by using a cron job or
    >> a scheduled task, no one sees the warnings.

    >
    > FYI: Usually, cron will mail the stdout and stderr output of a cronjob to
    > the user whose cronjob it was.


    Right. And getting a mail with a warning every 10 minutes should be
    enough enough motivation to fix the problem fast (of course some people
    would rather implement a mail filter to automatically delete all mails
    from cron ...)

    hp

    --
    _ | Peter J. Holzer | Deprecating human carelessness and
    |_|_) | Sysadmin WSR | ignorance has no successful track record.
    | | | |
    __/ | http://www.hjp.at/ | -- Bill Code on
    Peter J. Holzer, Feb 17, 2012
    #15
  16. On 2012-02-15 22:52, Graham Drabble <> wrote:
    > On 14 Feb 2012 (Tim McDaniel) wrote in
    > news:jhek67$dpd$:
    >> So a cow-orker has the result of a database query. It's being
    >> returned as a string: it contains an integer or it's a null
    >> string.

    >
    > Has he though of changing the query. You don't say what DB he's using
    > but the following should work in MSSQL and I would expect similar to
    > be possible in other DBMSs.
    >
    > Instead of
    > "SELECT
    > column
    > from table"
    >
    > use
    >
    > "SELECT
    > case
    > when column is null then 0
    > else column
    > end
    > from table"


    Tim already wrote (unless I misunderstood him), that the value is
    actually "", not undef. DBI always returns undef for NULL, so that
    wouldn't help. (This also means that the column has almost certainly a
    varchar type, not a number type, which hints at a deeper database design
    problem - but unfortunately we often have to live with databases as they
    are and can't fix them).

    Somethingh like

    SELECT
    case column
    when '' then 0
    else column
    end
    from table

    should work, though.

    hp


    --
    _ | Peter J. Holzer | Deprecating human carelessness and
    |_|_) | Sysadmin WSR | ignorance has no successful track record.
    | | | |
    __/ | http://www.hjp.at/ | -- Bill Code on
    Peter J. Holzer, Feb 17, 2012
    #16
  17. On 2012-02-16 09:30, Shmuel Metz <> wrote:
    > In <>, on 02/15/2012
    > at 03:25 PM, Rainer Weikusat <> said:
    >>They are not different concepts and Perl and have never been
    >>different concepts in Perl:

    >
    > Nonsense; interpolating an empty string does not produce a warning.
    > There are certainly cases where you can ignore the difference, but the
    > difference is nonetheless real.


    More importantly: If Larry had intended undef to to conceptually the
    same as an empty string he wouldn't have bothered to implement undef
    at all. Why implement a special value with a special keyword if it's
    just the same as an empty string? So Larry considered it important to be
    able to distinguish between undef (no value, missing value, unknown
    value, ...) and the empty string or 0, even if he provided for automatic
    conversion.

    hp


    --
    _ | Peter J. Holzer | Deprecating human carelessness and
    |_|_) | Sysadmin WSR | ignorance has no successful track record.
    | | | |
    __/ | http://www.hjp.at/ | -- Bill Code on
    Peter J. Holzer, Feb 17, 2012
    #17
  18. On 2012-02-15 22:17, ccc31807 <> wrote:
    > On Feb 14, 4:37 pm, (Tim McDaniel) wrote:
    >> So a cow-orker has the result of a database query.  It's being
    >> returned as a string: it contains an integer or it's a null string.
    >> (Yes, we're certain.)  He wants to use it in a numeric context,
    >> Is there an elegant idiom for converting such a string to a number
    >> without producing a warning if it happens to be a null string?

    >
    > What's wrong with using int(), or sprintf()?
    >
    > I had a similar problem, but the reverse. I used person ID numbers as
    > keys in a hash table, and manipulated the values in various ways,
    > which included Microsoft Excel. I kept getting aggravating errors over
    > a long time, and after one experience went through the results line by
    > line and discovered that sometimes ID numbers with leading zeros were
    > treated like real numbers, and a value like '4321' does not match a
    > hash key like '0004321'.


    Well, you have to know your data: Perl itself won't convert a string
    '0004321' into the number 4321 unless you force it to. Contrary to what
    Rainer probably thinks numbers and strings aren't the same in Perl and
    if you keep a mental model of what your values actually are it isn't
    actually that hard to prevent accidental type conversions.


    > I started using sprintf() when in doubt, and it solved the problem. I
    > just convert whatever the value is into a string, and it preserves the
    > leading zeros.


    You haven't shown the sprintf invokation you use but I don't think so.
    It may *add* leading zeros if they got lost, but it cannot preserve
    them.

    hp


    --
    _ | Peter J. Holzer | Deprecating human carelessness and
    |_|_) | Sysadmin WSR | ignorance has no successful track record.
    | | | |
    __/ | http://www.hjp.at/ | -- Bill Code on
    Peter J. Holzer, Feb 17, 2012
    #18
  19. Tim McDaniel

    Tim McDaniel Guest

    In article <>,
    Peter J. Holzer <> wrote:
    >Tim already wrote (unless I misunderstood him), that the value is
    >actually "", not undef. DBI always returns undef for NULL, so that
    >wouldn't help. (This also means that the column has almost certainly
    >a varchar type, not a number type, which hints at a deeper database
    >design problem - but unfortunately we often have to live with
    >databases as they are and can't fix them).


    In particular, this is Oracle. As I understand it, it implements
    varchar NULL as a null string. It may be DBI, or the database
    wrappers we've put around it, or other functions around them, but my
    cow-orker reported that it was indeed a null string when he got it.

    --
    Tim McDaniel,
    Tim McDaniel, Feb 17, 2012
    #19
  20. "Peter J. Holzer" <> writes:

    [...]

    > Contrary to what Rainer probably thinks numbers and strings aren't
    > the same in Perl


    Assumptions you make about other people's thoughts are YOUR thoughts.
    Rainer Weikusat, Feb 17, 2012
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. makok
    Replies:
    1
    Views:
    6,748
    Anders Hellerup Madsen
    Feb 23, 2004
  2. Peter Ammon

    Number of ways to create an object

    Peter Ammon, Jan 29, 2004, in forum: C++
    Replies:
    22
    Views:
    910
    Jack Klein
    Jan 30, 2004
  3. Hank
    Replies:
    5
    Views:
    464
    Bengt Richter
    Nov 18, 2003
  4. Replies:
    12
    Views:
    529
    Keith Thompson
    Mar 10, 2006
  5. Andrew
    Replies:
    23
    Views:
    275
    Tad McClellan
    May 9, 2004
Loading...

Share This Page