http://qs321.pair.com?node_id=604621

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

I see that in modern Inside-Out class implementations, Scalar::Util::refaddr() is used to pick up an index, rather than the stringification of the reference: why is it so? To be even more agnostic about what that reference really is?

Replies are listed 'Best First'.
Re: Simple question about Inside-Out objects
by ikegami (Patriarch) on Mar 13, 2007 at 17:36 UTC

    It also won't break if the object overrides stringification/numification.

Re: Simple question about Inside-Out objects
by Anno (Deacon) on Mar 13, 2007 at 17:54 UTC
    refaddr()is used to be entirely agnostic about the bless status of an object.

    It is essential for an inside-out class that an object keep its identity whether it is unblessed, blessed or re-blessed. Not to mention possible overloading of stringification.

    Anno

      refaddr() is used to be entirely agnostic about the bless status of an object.

      Speaking of which (and I'm replying to you but ideally to all those who kindly answered my question, whom I thank), I was thinking that perhaps it would be nice if standard ref, just like so many functions, returned something different in list context, i.e. something like: REF, ADDR, BLESSED, where

      • REF would be ref()'s current output if the reference is not blessed, and if it is then the same as if it were not,
      • ADDR the same as refaddr()'s and
      • BLESSED the package the reference is blessed in, if it is, or undef otherwise.

      But I suppose that such a beast would risk of breaking too much existing code...

        Interestingly enough... UNIVERSAL::ref would allow you to override ref for some objects. There's no such thing as ref() in list context right now though.

        ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re: Simple question about Inside-Out objects
by Joost (Canon) on Mar 13, 2007 at 17:32 UTC
Re: Simple question about Inside-Out objects
by Herkum (Parson) on Mar 13, 2007 at 17:44 UTC

    In a inside-out implementation, you need to a way to identify the object that you are working with. The only difference between different objects of the same class are their addresses. by using refaddr we can uniquely identify our objects and hidden the variables in each object from each other.

    A very short example

    package Foo::Bar; use Scalar::Util qw(refaddr); my %var; sub get_var { my $self = shift; return $var{ refaddr( $self ) }; } sub set_var { my $self = shift; my $value = shift; $var{ refaddr( $self ) } = $value; return 1; } # Not completely sure that this is correct. sub new { my $class = shift; return bless \my($anon_scalar), $class; }

    Take a look at Class::Std or Damian Conway's Best Practices on the concept.

      Take a look at Class::Std

      No, please don't. Look at Object::InsideOut or Class::InsideOut instead. For a full review of the technique, see my YAPC::NA 2006 presentation, Eversion 101.

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

        I have looked at both of them and the reason that I don't use them is the same reason that I don't use a lot of other 'good' modules, poor documentation.

        While I understand that Class::Std is not the perfect for solving all the problems for InsideOut objects. The concepts well explained and the documentation is easier to understand. That is why I recommended it to blazar