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

Given the code
package Frooble; use base qw(Class::Accessor); __PACKAGE__->mk_accessors(qw(name)); use overload '""' => \&as_string; sub as_string { shift->name }; 1;
is there a way (short of sub-classing and overriding the as_string method) to remove the stringified form of Frooble? I.e. to cause
$froob = Frooble->new; $froob->name("Blortz"); print "$froob\n";
to print 'Frooble=HASH(0x12345678)' instead of 'Blortz'?

Using raw object refs is useful for several reasons, and if 'name' is not unique across instances, the stringified form cannot be used as a hash ref without clobberage.

Scalar::Util::refaddr doesn't work, since that returns just the memory location without the fancy Frooble=HASH gubbins.

Retitled by davido from 'Destringify' per consideration.

Retitled by davido from 'How to subclass without inheriting string overload?' per author request.

Replies are listed 'Best First'.
Re: Removing overloaded string operator
by BrowserUk (Patriarch) on Feb 01, 2005 at 22:22 UTC
    print overload::StrVal $frooble;

    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.
      An interesting property about this line of code that I noticed is if you do the following

      print overload::StrVal $froob."";

      it will take you back to square one printing out the value instead of the desired Frooble=Hash()

      Although this is minor I thought it would be relevant to this discussion, because as some point some bonehead (me) is bound to do it and claim that overload isn't working properly :p
        Actually, when you look at it it isn't that surprising. Most likely the function overload::StrVal doesn't have a prototype. Therefore when you call it like that Perl parses it as a list operator (Update: The anonymous reply below is correct - the type of operator doesn't matter). That is to say, it is equivalent to
        print overload::StrVal($froob . "");
        In other words, its taking the string value of $froob (which happens to be the return value of an overloaded stringification), appending a blank to it, and then calling StrVal, which does nothing since its argument is an ordinary string.
Re: Removing overloaded string operator
by Tanktalus (Canon) on Feb 01, 2005 at 22:16 UTC

    According to the overload documentation, "no overload ..." works. So you could do something dangerous like:

    eval q[package Frooble; no overload '""';];

      I thought of that, but that's akin to overriding the as_string method, and would have a global effect (i.e. all string-forms of Frooble would then revert back to Frooble=HASH() form).

      What I was after was something like

      # prints "Blortz", i.e. the instance name print "$frooble"; # prints "Frooble=HASH(..)" print UNIVERSAL::as_string($frooble);
      but unless I'm missing something (not unusual ;) ) nothing like that exists.
Re: Removing overloaded string operator
by ambrus (Abbot) on Feb 02, 2005 at 16:51 UTC

    You can rebless the object to an empty package, stringify, then rebless it to the original package. That works, but is ugly.