I think the core issue is that Perl is not capable of losslessly representing all numbers that could come from a SQL database without using the string representation (or BigInt/BigRat/etc), and so using strings is a safe solution.

That being said, I think the best solution is for DBIx::Class to conditionally return as numbers. Return a result $x as a Perl number if and only if both "(0+$x) eq $x" is true and $x is logically a number to the database.

Optionally auto-promote $x to a Math::BigInt/Rat/etc only when "(0+$x) ne $x".

Under this system, you get the most accurate semantics and performance without loss of precision. (I assume the JSON modules deal with Math::BigInt/etc correctly.)

How does that work for people?

-- Darren Duncan

On 2015-02-25 3:30 PM, Augustus Saunders wrote:
Seems a little backwards to create a helper to work around a core defect. This 
is something that should work transparently, and is very simple to do so.

Augustus


On Feb 25, 2015, at 2:53 PM, Dmitry L. <dim0...@gmail.com> wrote:

Use DBIx::Class::Helper::Row::NumifyGet Luke

On 26 February 2015 at 01:43, Lasse Makholm <la...@unity3d.com> wrote:


On Wed, Feb 25, 2015 at 10:59 PM, Darren Duncan <dar...@darrenduncan.net>
wrote:

Augustus, what is the problem with DBIC stringifying numeric values?  That
ensures full precision and in particular when you want to use them as
numbers you can just do so, Perl does that automatically. -- Darren Duncan


One example of it being a problem is when converting row objects to JSON.
Javascripts === operator, for example, evaluates to false for for 42 ===
"42".

/L




On 2015-02-25 1:15 PM, Augustus Saunders wrote:

For reasons unknown to us, DBIx is stringifying numeric values somewhere
along the way. In order to ensure they come out numeric, we made this small
patch:

--- a/lib/perl5/DBIx/Class/Row.pm
+++ b/lib/perl5/DBIx/Class/Row.pm
@@ -661,10 +661,15 @@ To retrieve all loaded column values as a hash, use
L</get_columns>.
  sub get_column {
    my ($self, $column) = @_;
    $self->throw_exception( "Can't fetch data as class method" ) unless
ref $self;
-  return $self->{_column_data}{$column} if exists
$self->{_column_data}{$column};
+  if (exists $self->{_column_data}{$column}) {
+    return 0 + $self->{_column_data}{$column} if
$self->_is_column_numeric($column);
+    return $self->{_column_data}{$column};
+  }
    if (exists $self->{_inflated_column}{$column}) {
-    return $self->store_column($column,
+    my $ret = $self->store_column($column,
        $self->_deflated_column($column,
$self->{_inflated_column}{$column}));
+    return 0 + $ret if $self->_is_column_numeric($column);
+    return $ret;
    }
    $self->throw_exception( "No such column '${column}'" ) unless
$self->has_column($column);
    return undef;

If there's a better way to do this, or some way to prevent DBIx from
stringifying the values in the first place, that would be nice to know too.
Thanks-

Augustus


_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk

Reply via email to