develooper Front page | perl.perl6.language | Postings from June 2005

Magic mutators and my $var is Proxy( ... );

Thread Next
From:
Sam Vilain
Date:
June 26, 2005 01:36
Subject:
Magic mutators and my $var is Proxy( ... );
Message ID:
42BE68C9.6020205@vilain.net
To me it is a trivial case that you want to provide a fake attribute
which for all intents and purposes behaves exactly like there was a real
attribute there, backing against another attribute.

A Date object is a classic example of this; you want to provide 0-based
and 1-based attributes, which you want to present as equivalent to each
other.

So, we've got this "my $var is Proxy( ... )" construct in A06.
Say you've got this class:

   class MagicVal {
      has Int $.varies is rw;

      method varies returns Int is rw {
	return my $var is Proxy ( :for($.varies),
	               		  :FETCH{ $.varies += 2 },
		       		  :STORE{ $.varies = $_ + 1 },
		     		);
      }
   }

Firstly, would this be correct syntax?  In particular, what should
I call $.varies inside the :FETCH and :STORE subs?  Would they close
over $?SELF, too?

If they did, doesn't this mean that $var will be a new Proxy attribute
every time that the attribute is read, and will have side effects?

Such as;

  my $foo = MagicVal.new();
  $foo.varies = 5;    # sets to 6;
  say $foo.varies;    # says 8
  say $foo.varies;    # says 10
  my $var = $foo.varies;  # $var is proxy for attribute
  say $foo.varies;    # says 12
  say $var;           # says 14

It seems to me that the only time I'd want to actually return a
Proxy object is when taking a reference to the fake attribute.  In
all other situations, you'd simply want to dispatch to either an
accessor or a mutator, depending on the context.

ie, I'd like the design of this feature to be sufficient that most
of the time, the Proxy object need never be constructed, and instead
the relevant closure could be bound to that method instead.

In particular, I think this would mean making Proxy objects
automatically call FETCH when returned, unless in reference context.

In fact, I think I'd rather see the proxy as a closure trait;

   class MagicVal {
      has Int $.varies is rw;

      method varies returns Int is Proxy( :FETCH(&get_varies),
                                          :STORE(&set_varies) );

      method get_varies { $.varies += 2 };
      method set_varies { $.varies = $^v + 1 };
   }

Of course this wouldn't preclude the possibility of using the syntax
in A06 where it is more suited to the problem at hand.  Also, in the
case where you do take a reference of a $foo.varies, then a Proxy object
could be constructed to DTRT based on the information there.

This would make the "is Proxy()" construct effectively a compile-time
want() switch.

Any opinions on this?

Sam.

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About