Since the developer's guide is aimed (mostly) at the LZX programmer,  
it should just say that it is best practice to declare all the  
attributes of your class and to give them default values.  Adding  
attributes to a class at run time is discouraged as it impacts both  
the performance and safety of your code.

For a default value, it is preferable to use a value of the expected  
type.  E.g., for a boolean attribute, use `true` or `false`, rather  
than `null` (or no default).  `null` and the undefined value are  
equivalent to `false` in a boolean context, but if you mean false,  
say so; don't leave future maintainers mystified over whether you  
might have meant your attribute to behave differently for null and  
false (yes, there are such attributes in the LFC and they should be  
documented with blinking red text).

For an attribute that expects an object value, it may be that `null`  
is the only sensible default value, but often it will be worthwhile  
to consider either initializing the attribute to an 'empty' instance  
or giving the attribute a 'sentinel' instance that can act as a  
marker for the default value, and will behave innocuously if it is  
accessed.  If you use `null` as the default value, then everywhere in  
your code where you access this attribute, you need to first check if  
it is null before you attempt to access its properties; if you use a  
sentinel object, then your code can safely access the sentinel's  
properties and you only need to check for the sentinel when you are  
trying to determine if the attribute has other than default properties.

A simple example:  you have an attribute that is an Array of values.   
You have three choices for initialization:

o `null` -- which you have to check for each time you access the  
attribute
   very efficient, least safe (must check every access)
o `new Array` -- which means you will allocate an empty array for  
each instance
   less efficient, very safe (always of correct type)
o a sentinel array -- which you will have to replace when you add values
   moderately efficient, moderately safe (must check on modifying  
access)

<!-- Null default, must check on each access -->
<attribute name="valueList" value="null" />
<method name="addValue" args="value">
   if (! valueList) {
     this.valueList = new Array;
   }
   valueList.push(value);
</method>
<method name="getValues">
   if (! valueList) {
     this.valueList = new Array;
   }
   return valueList;
</method>

<!-- Empty default, cost at creation, but no checking required -->
<attribute name="valueList" value="$once{new Array}" />
<method name="addValue" args="value">
   valueList.push(value);
</method>
<method name="getValues">
   return valueList;
</method>

<!-- Sentinel default, only check on setting, not getting -->
var emptyList = new Array;
<attribute name="valueList" value="emptyList" />
<method name="addValue" args="value">
   if (valueList === emptyList) {
     this.valueList = new Array;
   }
   valueList.push(value);
</method>
<method name="getValues">
   return valueList;
</method>


On 2006-05-18, at 08:03 EDT, John Sundman wrote:

> I have followed this discussion with great attention and even  
> greater head-scratching, trying to figure out what, if anything I  
> should add to the Developer's Guide about checking for the  
> existence of properties.
>
> It seems to me that the first sentence of Tucker's message, below,  
> is basically all I need to say on the topic. Any deviations from  
> "good software engineering practice" being beyond the scope of  
> OpenLaszlo docs.
>
> If I should say anything else, please let me know what it is.
>
> Thanks,
>
> jrs
> On May 12, 2006, at 1:33 PM, P T Withington wrote:
>
>> I think it is best to define all your properties, rather than relying
>> on it not being an error to reference an undefined property.  It's
>> good software engineering, and I think we will see Javascript tending
>> in a direction where you have to give up this kind of dynamicity for
>> performance anyways (IOW, it will cost you more to reference a non-
>> existent property than a property declared with a default).
>>
>> Remember also that many times you can set a default value on the
>> class prototype and get it 'for free' in all the instances of the  
>> class.
>>
>> On 2006-05-12, at 09:19 PDT, Philip Romanik wrote:
>>
>>> Thanks Tucker!
>>>
>>> I have a related question. When I find object properties that are
>>> not defined, I am giving them an initial value of null. This
>>> eliminates the problem with undefined and allows me to do this,
>>>
>>>     if (this.somevariable)
>>>         ...
>>>
>>> in the code. This makes cleaner code but it does potentially define
>>> a lot of properties that are not often used.
>>>
>>> Any advice?
>>>
>>> Phil
>>>
>>>
>>>> `in` is not yet supported in the SWF runtime.
>>>>
>>>> `hasOwnProperty` is supported in both runtimes.  When we use `new
>>>> Object` or literal objects to represent hash tables, best
>>> practice is
>>>> to use `hasOwnProperty` to detect the presence of a key in the
>>>> table.  (Consider a table that might have the keys `toString`,
>>>> `constructor`, etc. which are inherited by all objects:  only
>>>> `hasOwnProperty` can tell if those keys are in the table or not.)
>>>>
>>>> So my recommendation to Phil is to use `hasOwnProperty` anywhere it
>>>> is clear that we are using an object as a hash table and only  
>>>> resort
>>>> to `[]` or `typeof` if it is not clear.
>>>
>>
>> _______________________________________________
>> Laszlo-dev mailing list
>> [email protected]
>> http://www.openlaszlo.org/mailman/listinfo/laszlo-dev
>

_______________________________________________
Laszlo-dev mailing list
[email protected]
http://www.openlaszlo.org/mailman/listinfo/laszlo-dev

Reply via email to