http://www.perlmonks.org?node_id=888742

perl5ever has asked for the wisdom of the Perl Monks concerning the following question:

With a Moose object I am passing the value of an object attribute to the execute method of a DBI statement handle, i.e. something like:

$sth = $dbh->prepare(...); $sth->execute($obj->now);
where $obj is a Moose object. I've been told by my DBAs that the bind parameter is being treated as a string instead of a number which is causing my query to run slowly. I could fix this by writing:
$sth->execute(0+$obj->now);
However, I'm using $obj->now in many places.

Question: How can I declare the 'now' attribute of $obj so that on gets it will ensure that the value returned is a number (or undef). Currently, 'now' is simply defined as:

has now => ( is => 'rw' );

Replies are listed 'Best First'.
Re: Moose - ensuring a getter returns a number
by Fletch (Bishop) on Feb 17, 2011 at 16:03 UTC

    Maybe use around?

    around 'now' => sub { my $orig = shift; my $self = shift; return $self->$orig( @_ ) + 0; }

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      Thanks for the idea.

      Is there anything that can be done with Moose type constraints?

        Not likely, since Perl is so permissive about what is a number and what is a string, the Moose type constraint for numbers allows them to also be strings as well.

        The solution with the around is actually pretty good, or as another responder points out, make sure that the value is a number before it is actually added to your data object.

        -stvn
Re: Moose - ensuring a getter returns a number
by ikegami (Patriarch) on Feb 17, 2011 at 19:02 UTC

    The idea of solving a problem with your database code in your data class feels wrong to me. The fact that your database code is "in many places" is your real problem.

    A good solution would be to numify the value before placing it in the object in the first place.

    There are some more hackish solutions too:

    • Coerce the value to a number when adding it to the object.
    • Provide a getter that numifies and call it something other than now. (Requires changing DB code.)
    • Provide a getter that numifies and call it now.