in reply to Re^5: Why does sv_2nv on non-number look like an NV
in thread Why does sv_2nv on non-number look like an NV

I don't mind an error if the SV does not contain anything that can be reasonably converted to a number so long as I can catch that. I want an NV when it is a convertable number and not otherwise.

  • Comment on Re^6: Why does sv_2nv on non-number look like an NV

Replies are listed 'Best First'.
Re^7: Why does sv_2nv on non-number look like an NV
by ikegami (Patriarch) on Nov 26, 2009 at 16:24 UTC

    Why?

    If you needed an NV, you'd use

    NV num; if (!looks_like_number(sv)) croak("Not a number"); num = SvNV(sv);

    Put you said you didn't ("and not [an NV] otherwise"). If you simply needed a number when possible, you already have tat. Useless numifying is useless. If it's not useless, it's because you have code that treats PV 1.2 different than NV 1.2, and that's a bug. Perl has an example of that (bitwise ops), and it has caused many headaches.

    Update: Added code.

      I don't /need/ an NV or anything else in particular. In the API this code is in the caller asks for a particular type and the API attempts to do the cast but there are different return states for it could be cast and it was cast. See DBI.xs and search for sql_type_cast_svpv.

      The purpose of the API is to be able to return a state indicating whether the sv_2nv works or not (I've removed some code to try and keep to the relevant bits and commented with "mje" tag). As it stands the other types (I removed but are visible at the svn url in previous reply) of SQL_INTEGER and SQL_NUMERIC happily return 1 or 2 if the conversion does not work but SQL_DOUBLE does not.

      /* Convert a simple string representation of a value into a more speci +fic * perl type based on an sql_type value. * The semantics of SQL standard TYPE values are interpreted _very_ lo +osely * on the basis of "be liberal in what you accept and let's throw in s +ome * extra semantics while we're here" :) * Returns: * -2: sql_type isn't handled, value unchanged * -1: sv is undef, value unchanged * 0: sv couldn't be cast cleanly and DBIstcf_STRICT was used * 1: sv couldn't be cast cleanly and DBIstcf_STRICT was not used * 2: sv was cast ok */ int sql_type_cast_svpv(pTHX_ SV *sv, int sql_type, U32 flags, void *v) { int cast_ok = 0; switch(sql_type) { default: return -2; /* not a recognised SQL TYPE, value unchanged */ case SQL_DOUBLE: { /* mje - I don't understand why sv_2nv returns 0 in the follow +ing when sv is "aa" */ sv_2nv(sv); /* SvNOK should be set but won't if sv is not numeric (in whic +h * case perl would have warn'd already if -w or warnings are i +n effect) */ /* mje it is true perl warns if sv is "aa" and warnings enable +d so it knew it was not a number so why is cast_ok = 512 */ cast_ok = SvNOK(sv); break; } } if (cast_ok) return 2; /* mje always getting here but wanted 0 or 1 dependi +ng on DBIstcf_STRICT */ else if (flags & DBIstcf_STRICT) return 0; else return 1; }

      UPDATE As it turns out this problem went away in Perl 5.10.1 as SvNOK no longer returns a true value. I think the following change in the changelog for 5.10.1 might be the relevant one:

      The public IV and NV flags are now not set if the string value has trailing "garbage". This behaviour is consistent with not setting the public IV or NV flags if the value is out of range for the type.