[Laszlo-dev] [setter attribute? (head melts)

P T Withington ptw at pobox.com
Fri Nov 2 10:33:50 PDT 2007


[Adding laszlo-dev]

Just to be clear:

The purpose of the setter property on an attribute is to allow you to  
create a 'virtual' attribute.  It allows you to intercept the setting  
of the attribute and do arbitrary computations.  Potentially, you  
could store the value (state) of the attribute in another attribute  
(which might or might not be public).  The canonical example of a  
virtual attribute is a dimension in a different unit, e.g., you might  
have an Angle object with degrees and radians attributes, only one of  
which is actually stored, the other being a virtual attribute that  
converts to/from the 'native' unit.

In LZX there is an additional wrinkle, because of events.  Normally,  
without a custom setter, an event is sent every time you set an  
attribute.  Adam felt that there might, just might, be a case where  
you didn't want to send an event (or would want to send several); so,  
when you give an attribute a custom setter, you have to handle the  
event sending in your setter.

Finally, Eliot's example could be made more efficient by not having  
the separate _setFoo method, just putting the body of _setFoo in the  
setter field.  I realize this makes the code less legible.

We have several times discussed how to improve the legibility of  
setters.  If we were to adopt a more JS2-like approach, you would write:

<attribute name="degrees" allocation="virtual" />
<method name="set degrees" args="newValue">
   this.setAttribute('radians', degreesToRadians(newValue));
   if (this.ondegrees.ready) { this.ondegrees.sendEvent(newValue); }
</method>
<method name="get degrees">
   return radiansToDegrees(this.radians);
</method>

(Both the 'set foo' and 'get foo' methods could still be written in- 
line in the attribute tag too.  In fact, specifying a getter or setter  
should imply that the attribute is virtual, e.g:

<attribute name="degrees" getter="radiansToDegrees(this.radians)" />
<method name="set degrees" args="newValue">
   this.setAttribute('radians', degreesToRadians(newValue));
   if (this.ondegrees.ready) { this.ondegrees.sendEvent(newValue); }
</method>

should be equivalent.  The long-hand form is just for legibility.)

On 2007-11-01, at 18:05 EDT, Elliot Winard wrote:

> This is used in a bunch of places in Webtop.
>
> By having a setter you can have code that runs before the  
> onattribute events fire.
> Most instances of the pattern look like this -
>
>
> <attribute name="foo" setter="this._setFoo(foo)" />
> <event name="onfoo" />
> <method name="_setFoo" args="foo">
>     // do something special that must run before onfoo events fire
>     this.foo=foo;
>     if (onfoo) onfoo.sendEvent();
> </method>
>
>
> Yup,
> -e
> On Thu, Nov 1, 2007 at  5:38 PM, Benjamin Shine wrote:
>
>> The code from the guy who is rotating OpenLaszlo in webkit[1]  
>> includes this:
>>
>>    <attribute name="wrot" type="number" value="0"
>>      setter="this.wrot = wrot; this.updateRot(wrot);"/>
>>
>> I've never seen this "setter" attribute-of-an-attribute before. Is  
>> this still a supported and/or recommended API?
>>
>> -ben
>>
>>
>> [1] http://www.cuppadev.co.uk/2007/10/31/rotating-openlaszlo-with-webkit/



More information about the Laszlo-dev mailing list