String evaluation in resultset->next

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

String evaluation in resultset->next

Christian Lackas
Hi Everybody,

I frequently use

    use overload '""' => sub { shift->toString }, fallback => 1;

for my Row classes (via a role). However, recently noticed lots of
warnings about undefined values when I used select/as in a query to only
fetch a subset of columns.

Today, I found some time to actually track this down and found that

    while (my $dp = $resultset->next) {
    }

seems to call my stringify operator (and finally toString). Please note
that this happens even with an empty while loop, so none of my code uses
$dp in a string conext.

The alternative code to fetch all rows of a resultset does not show this
behavior and no stringify is called along the way.

    for my $dp ($resultset->all) {
    }

As said, this is only an issue if next is used on a resultset that does
not provide the usual columns (my toString expects).
However, besides the warnings, I am also wondering if there is a
performance penalty by using stringify without actually needing it.
Also, I believe this next-behavior is also responsible for a 'deep
recursion' error I see in a more complex Template Toolkit usage (at
least I see similar warnings and using a for loop worked around the
issue; have not fully investigated this yet, though).

Is this behavior intentional or a bug?

Unfortunately, I was not able to find the root for it. Adding a 'print
caller' only points back to the '$resultset->next' line.
Please also note that

    my $row = $rs->next;

itself does not trigger the issue. It is somehow related to the while()
loop (which indicates it may not be an issue in DBIx::Class itself?).


Please find attached a small test you can just drop into you DBIx::Class
t folder and run with

    $ prove -Ilib t/stringify.t
    t/stringify.t .. 1/?
    #   Failed test 'Stringify called'
    #   at t/stringify.t line 12.
   
    #   Failed test 'Stringify called'
    #   at t/stringify.t line 12.
   
    #   Failed test 'Stringify called'
    #   at t/stringify.t line 12.
   
    #   Failed test 'Stringify called'
    #   at t/stringify.t line 12.
   
    #   Failed test 'Stringify called'
    #   at t/stringify.t line 12.
    # Looks like you failed 5 tests of 6.
    t/stringify.t .. Dubious, test returned 5 (wstat 1280, 0x500)
    Failed 5/6 subtests
   
    Test Summary Report
    -------------------
    t/stringify.t (Wstat: 1280 Tests: 6 Failed: 5)
      Failed tests:  1-5
      Non-zero exit status: 5
    Files=1, Tests=6,  1 wallclock secs ( 0.02 usr  0.00 sys +  0.29 cusr  0.01 csys =  0.32 CPU)
    Result: FAIL

I tested this with DBIx-Class-0.082810 and freshly updated dependencies.
On our production system we are still using 0.08204. Perl 5.18.2 and
5.16.2.

Christian

--
Dr. Christian Lackas, Managing Partner
inviCRO, LLC -- In Imaging Yours
http://www.invicro.com/  http://www.spect-ct.com/

_______________________________________________
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@...

stringify.t (507 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: String evaluation in resultset->next

Christian Lackas
* Peter Rabbitson <[hidden email]> [141118 06:25]:

Dear Peter,

thanks for your excellent response.
Was indeed overlooking that I of course do have a boolean context in the
while loop, and did not realized it is derived from my string operator,
rather than continuing to use the regular scalar bool operator.

Add an explicit bool operator did the trick.

Thanks,
 Christian

--
Dr. Christian Lackas, Managing Partner
inviCRO, LLC -- In Imaging Yours
http://www.invicro.com/  http://www.spect-ct.com/

> On 11/18/2014 10:58 AM, Christian Lackas wrote:
> >Hi Everybody,
> >
> >I frequently use
> >
> >     use overload '""' => sub { shift->toString }, fallback => 1;
> >
> >for my Row classes (via a role).
> >
> >...
> >
> >However, besides the warnings, I am also wondering if there is a
> >performance penalty by using stringify without actually needing it.
> >
>
> This part of your question deals with the main problem - you have
> defined *only* stringification in combination with fallback, so some
> things are autogenerated (including boolification as described in
> https://metacpan.org/pod/overload#Magic-Autogeneration and also the
> last sentence of https://metacpan.org/pod/overload#Minimal-Set-of-Overloaded-Operations).
> This has nothing to do with next(): consider the following
> "one-liner"
>
> ~$ perl -MScalar::Util -e '
>
>   sub refdesc ($) {
>     sprintf "%s%s(0x%x)",
>       ( defined( $_[1] = Scalar::Util::blessed $_[0]) ? "$_[1]=" : "" ),
>       Scalar::Util::reftype $_[0],
>       Scalar::Util::refaddr($_[0]),
>     ;
>   }
>
>   {
>     package One;
>     use overload
>       bool => sub { warn "Called boolification on " . ::refdesc $_[0]},
>       q("") => sub { warn "Called stringification on " . ::refdesc $_[0] },
>       fallback => 1
>     ;
>   }
>
>   {
>     package Two;
>     use overload
>       q("") => sub { warn "Called stringification on " . ::refdesc $_[0] },
>       fallback => 1
>     ;
>   }
>
>   {
>     package Three;
>     use overload
>       q("") => sub { warn "Called stringification on " . ::refdesc $_[0] },
>     ;
>   }
>
>   {
>     package Four;
>     use overload
>       q("") => sub { warn "Called stringification on " . ::refdesc $_[0] },
>       fallback => 0,
>     ;
>   }
>
>   for my $obj ( map { bless {}, $_ } qw(One Two Three Four) ) {
>     my $is_false = !$obj;
>   }
> '
>
>
> >Also, I believe this next-behavior is also responsible for a 'deep
> >recursion' error I see in a more complex Template Toolkit usage (at
> >least I see similar warnings and using a for loop worked around the
> >issue; have not fully investigated this yet, though).
>
> Note in the script above I did not write:
>   ... q("") => sub { warn "Called stringification on $_[0]" }
>
> but instead added a sub to properly format the ref without touchinbg
> the overloads.
> I am not 100% sure but you may be facing a similar issue - you are
> stringifying within your stringification sub.
>
> Cheers
>
> _______________________________________________
> 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@...

_______________________________________________
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@...
Loading...