Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Moose stringification overloading isn't working

by dd-b (Monk)
on Feb 09, 2013 at 22:05 UTC ( #1017992=perlquestion: print w/ replies, xml ) Need Help??
dd-b has asked for the wisdom of the Perl Monks concerning the following question:

I've got a simple case working exactly as I expect and as documented, but a more complicated case NOT working. The main difference is that in the more complicated case, I'm accessing a child class of where I did the overload.

In the parent class I do:

use overload '""' => \&_stringify; sub _stringify { my $this = shift; # Actually operator arg, NOT a "this" $this->row->ID; };

I use it like this:

$logger->trace("Zep is " . ref($zep) . " stringifies as $zep" . " but +_stringify returns " . $zep->_stringify );

The resulting log line comes out like this: 20130209 15:27:30.041 TRACE 158 6070: Zep is OT::Zeppelin::AddVendorKey stringifies as OT::Zeppelin::AddVendorKey=HASH(0x378d480) but _stringify returns OT::DB::Result::Upload|upload|upload_id=1

OT::Zeppelin::AddVendorKey is a direct child of OT::Zeppelin, which is where the operator overload was done.

My head hurts, and the wall seems to still be fine. Any ideas?

Comment on Moose stringification overloading isn't working
Select or Download Code
Replies are listed 'Best First'.
Re: Moose stringification overloading isn't working
by moritz (Cardinal) on Feb 10, 2013 at 09:13 UTC

    You didn't post code that would let me reproduce your problem, so I can only guess.

    One guess is that you wrote another sub _stringify in a child class, and expected it to be called by the string overloading.

    It won't, of course, because you gave overload a reference to this one subroutine. If you want that kind of polymorphism, use

    use overload '""' => sub { shift->_stringify() };

    If you don't, make sure to do an apple-to-apple comparison by writing $logger->trace("Zep is " . ref($zep) . " stringifies as $zep" . " but _stringify returns " . OT::Zeppelin::_stringify($zep) );

    You can solve any problem in computer science with another layer of indirection, except the problem of too many layers of indirection.
Re: Moose stringification overloading isn't working
by tobyink (Abbot) on Feb 10, 2013 at 08:54 UTC

    You're not using something like namespace::autoclean are you? It breaks overloading. Try namespace::sweep instead.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Re: Moose stringification overloading isn't working
by Anonymous Monk on Feb 09, 2013 at 23:48 UTC
      Drat. Does that mean the concept and execution seems sound and you need more detail, or just that you didn't look at it because it wasn't a self-contained bagged sample?

      As I said, the small sample I built worked, so I'd have to chase it up the tree. Which I will if necessary, if there's nothing obviously wrong with the approach.

        It means code is clearer than words :) and your question is unclear (to me)

        If I had the same question, first thing I would do is try to replicate it in a short self contained example, and then I'd either have a test case, or I'd figure out where I'm confused, or have some code to show what I'm trying to accomplish

        Code can be much clearer than English

Re: Moose stringification overloading isn't working
by Anonymous Monk on Feb 10, 2013 at 07:29 UTC

    Your output has two different classes in it:

    Zep is              OT::Zeppelin::AddVendorKey 
    stringifies as      OT::Zeppelin::AddVendorKey….
    _stringify returns  OT::DB::Result::Upload...

    So it looks like the line $this->row->ID can return two different objects.

    The 'use overload' docs say:

    The subroutines for '""' , '0+' , and 'bool' can return any arbitrary Perl *value*. If the corresponding operation for this *value* is overloaded too, the operation will be called again with this *value*.
    As a special case if the overload returns the object itself then it will be used directly. An overloaded conversion returning the object is probably a bug, because you're likely to get something that looks like YourPackage=HASH(0x8172b34) .

    Based on the order of the output, I would say that $this->row->ID is returning $this in some cases, and in other cases it is returning an object of the class OT::DB::Result::Upload, and that class has also overloaded '""'.

    Here is a simple example of that:

    use strict; use warnings; use 5.012; ############## { package Point; use Moose; # automatically turns on strict and warnings has 'x' => (is => 'rw', isa => 'Int'); has 'y' => (is => 'rw', isa => 'Int'); use overload '""' => \&_stringify; sub _stringify { state $count; my ($rhs, $_lhs, $swap) = @_; $count++; if ($count < 2) { return $rhs; } else { return D->new; } } } ################ { package Point3D; use Moose; extends 'Point'; has 'z' => (is => 'rw', isa => 'Int'); } ############### { package D; use Moose; use overload '""' => sub { my $class = ref shift; return "$class|hello" }; } ############### my $p3d = Point3D->new(x=>10, y=>20); say "$p3d"; say $p3d->_stringify; --output:-- Point3D=HASH(0x100bc5078) D|hello
      What happens if you use double quotes twice? And what happens if you call _stringify() twice? Any difference?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1017992]
Approved by Old_Gray_Bear
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (7)
As of 2016-05-31 06:22 GMT
Find Nodes?
    Voting Booth?