Correct Syntax???!!!

David Burgun dburgun at dsl.pipex.com
Fri Mar 24 14:34:21 EST 2006


Hi,

On 24 Mar 2006, at 18:11, Richard Gaskin wrote:

> Right. While your specific setup did manage to discover a bug,  
> perhaps the reason no one's reported this before is that they  
> prefer to write less code.
>
> Replicated code not only takes more time to write, but as you note  
> it takes more time to revise.  Even if you were using something  
> that worked perfectly, there may come a time when you want to  
> enhance it. Replicated code means replicating the enhancement effort.

Well it definitely does if it's wrong!!!! lol

By replicate I mean that whenever I wanted to store something in a  
field, I used put <something> into me form rather than the long id  
form. Which meant that now I have implemented the ISM I had revise  
all usages to use the long id form. But it's done now and well worth it.

>
> In common practice "me" is rarely used, as it only affects one  
> object. In the example shown above, a more generalized approach  
> might be this card script:
>
>   on preOpenCard
>       repeat with i = 1 to the number of flds
>         if the lockText of fld i is false then
>            put empty into fld i
>         end if
>       end repeat
>       pass preOpenCard
>   end preOpenCard

Yes, but this only works for fields and it only works on *all*  
fields, what if you wanted to leave the field untouched from the last  
time it was used. By putting the logic in the field/object in  
question you can initialize it or not initialize depending on what is  
needed and you only need to change the object in question which stops  
potential bugs from affecting ALL objects. You only have to worry  
about bugs in the object you have changed.

> That simple handler accomodates any number of fields without  
> modification to the code or the objects.  You can add or delete  
> fields at any time, and the form still clears itself before being  
> displayed.
>
> Now suppose we later decide we want to have some fields to display  
> default values, while still leaving others blank.  We could add a  
> simple property to any field that needs it, and we only make a  
> small change in that one card handler:
>
>   on preOpenCard
>       repeat with i = 1 to the number of flds
>         if the lockText of fld i is false then
>            put the uDefaultValue of fld i into fld i
>         end if
>       end repeat
>       pass preOpenCard
>   end preOpenCard

See above, but also, what if the default value is is not a constant,  
but can be changed by the user? Using this method you are stuck with  
the single "uDefaultValue" value, whereas using the ISM approach you  
are free to obtain the value anyway you like and it's specific for  
the object in question.

> I read your outline at <http://lists.runrev.com/pipermail/use- 
> revolution/2006-March/079065.html>, and although after two readings  
> I can't figure out what its goal is my hunch is that it could be  
> satisfied with a single backScript or library and property settings  
> in affected objects.

Maybe a better example is this. I have a preferences stack, one of  
the items on it is the unit of measurement, it can be set to MM, CM  
or Inches. I have a couple of groups in my Group Library to do with  
measure. One of them has the following fields:

[] = a field
<> = variable value

[Width:]   [ <value_in_units>]   [<Units>]
[Height:]  [ <value_in_units>]  [<Units>]

If the units were set to CM and the values were 100.

Now the user opens the preferences stack and changes the units to MM.  
I want all <Units> values to change from CM to MM and I want 100 CM's  
to now be 1000 MM's.

Using ISM, I would do this in the script for the Value and Units fields:

ListenForMessage("PrefsMeasureUnits",kMeasureUnits)

and define the following handlers for the <Units> fields:

on PrefsMeasureUnits theMessageID, theSubClass, theUnitValue
set the text of the long id of me to theUnitValue
end

and on the <value_in_units> fields:

on PrefsMeasureUnits theMessageID, theSubClass, theUnitValue
put CalcualteNewValue(the text of the long id of me, theUnitValue)  
into myNewValue
set the text of the long id of me to myNewValue
end

And in the script of the popup menu in the preferences stack, I'd write:
get ISMPutMessage("PrefsMeasureUnits", kMeasureUnits,theNewUnitsValue)

And any object in any card on any stack can "listen" for the message,  
so they all initialize to the correct value. I therefore only need to  
change the value once, not once for each object.

For instance:

No other stacks are open/running.

The user runs Preference Stack and changes the measure units to MM.
The user closes the Preference Stack.
The last time Stack A was run the measure units was set to CM.
The User runs Stack A, the "measure" fields call ISMListenForMessage,  
since there is now a message pending they automatically change to  
"MM". If there was not a message pending then a message would not be  
sent and no code would be executed. The way you are proposing I would  
have to re-initialize the object every time whether the value has  
changed or not!

> Such an approach keeps the code centralized, making it easier to  
> write, maintain, and enhance.  Objects could be added or removed  
> from the behavioral management by just changing a property, never  
> needing to even open a script editor.

I don't need to open the script editor either! And if I delete an  
object then messages just stop being sent to it!

> There's also a performance benefit to using the natural message  
> path whenever practical.  Consider these benchmarks from a simple  
> test case* (times shown are per call):
>
> Native:  0.007ms
> Send:    0.011ms
> Do:      0.013ms
>
> In a single call, the difference between native message inheritance  
> and "send" is only 0.004ms, certainly not worth worrying about.   
> But if one were building a system in which "send" is being used  
> throughout as the primary means of driving things, the aggregate  
> cost of that 50% peformance difference may make the system  
> noticeably less responsive. Those clock cycles could probably be  
> put to better use; even if performance appears fine for now, future  
> enhancements may require additional load elsewhere, so it's often a  
> good idea to keep performance in mind even when it doesn't  
> initially seem important.

I see your point, but in practice, using the ISM approach only the  
objects that need to act are called whereas using the other methods  
all fields need to be visited. I have found that the performance is  
about the same and it's just as responsive. This is just driving a  
basic GUI, if I needed to do something really fast, I would use an  
external command and deal in microseconds not milliseconds.

For instance the Experimental stack I did has 274 objects, 94 of them  
can be called via ISM, but in practice the most objects I have that  
are affected by a user GUI action is 6. The overhead is minimal. I  
have to get a stack working by Monday, but after that I will do the  
extra work needed in ISM, do a first draft of the documentation and  
post it to RevOnline. You can then take a look at how it works, but I  
am willing to bet you will not think that it's any slower than other  
Rev Apps I have seen.

> There are of course times when "send" and "do" are the only way to  
> solve a problem, but with the flexibility of frontScripts,  
> libraries, and backScripts such cases are few.

ISM is a library so I am using this technique.I really don't know  
anything about front or back scripts, and to be honest the lack of  
good documentation has put me off looking at them. What I have works  
for me and allows me to create apps must more quickly than using the  
methods you describe.

Have a Great Weekend and thanks again for all the help.
All the Best
Dave



More information about the use-livecode mailing list