Script Only Stack Architecture

Richard Gaskin ambassador at fourthworld.com
Thu Mar 31 17:51:52 EDT 2016


The difference between a library and a behavior is scope:  the library 
is global, while the behavior only affects the objects to which it's 
assigned.

The preloading thang with behaviors is somewhat specific, only coming 
into play when all three of the following are true:

- The behavior script must be outside of the stack file containing
   objects that depend on it;

- The objects that depend on it happen to be in a stack file loaded
   into memory before the external behavior stack is loaded;

- For some reason just setting the stackfiles property to include
   the external stack is prohibitive.

Most of my apps have a substack named "<appname>RSRC" where I keep 
images and such, and my behavior scripts are buttons there. I never 
think about behavior load order at all.


As for scope:

Your library option is a workable solution.  Indeed that's the only way 
we did things for many years.  And where it's a good fit we still do.

But what if you want to change the script so that rather than respond on 
mouseUp you want to respond to mouseDown?  Or add a handler for new 
mouse message?

With a library you'd either have to change the scripts of every object 
you want updated, or you could use the message name directly in the 
library with a condition in the library, e.g.:

    if the uClassName of the target is "MyClass" then...

But with a behavior you just edit one script.  Ever. For any change to 
all child objects it governs.

And being limited in scope to child objects assigned to it, a behavior 
is slightly more efficient than a library, since it's not in the message 
path for all of the objects it's unrelated to.

But that performance difference is tiny (very, almost immeasurable).

The biggest benefit is keeping all code in one place.  With a behavior 
you know that if any subscribed child has code in it, it's an exception 
and the code is there for a very distinct reason (overloading or 
overriding the behavior).

For all other objects of a class, chances are they'll have no code at 
all.  The only code they'll have is code that makes them unique; common 
code is stored in one common place.

A small stylistic benefit is not needing to keep track of the target, 
which may sometimes change during a multi-call sequence.

With behaviors, "me" refers to the child object subscribing to the 
behavior. So if you have complex routines that use "send" or "click at" 
or other things that can change the target, you still always know the 
child object using the behavior, "me".

In all respects the code acts as though it's attached to that child - it 
even maintains its own distinct set of local and script-local variables 
for each child.

This latter feature is very handy.  You could conceivably use custom 
properties similarly to keep info bound to the object, but unless you 
need that info to be persistent you'll want to clear it or reset it at 
some point.   But with variables within a behavior script being unique 
to each child using it, you never need to think about it - you just code 
as if you were coding on the object's own script.

For more sophisticated systems the ability to subclass can be very 
useful.  If you had a globally-available library that filters out class 
members with a condition, using subclasses or superclasses means adding 
more conditions.  But with behaviors it's just a single property setting 
on the affected behavior to chain another to it.

-- 
Richard Gaskin
Fourth World Systems
Software Design and Development for the Desktop, Mobile, and the Web
____________________________________________________________________
Ambassador at FourthWorld.com http://www.FourthWorld.com


William Prothero wrote:

 > Ok, for the sake of argument (and my learning), compare that to:
 >
 > 1. Make  new stack and call it “Alt Behavior Playground”
 >
 > 2. Make a new button and enter the script:
 > on mouseDown
 >    put the long ID of the target into theTarg
 >    doABehavior theTarg
 > end mouseDown
 >
 > 3. Make a substack and call it “myBehaviorLib”  —just for the heck of
 > it.
 > Put the following script in it:
 >
 > on doABehavior tCtl
 >     doTheGrab tCtl
 > end doABehavior
 >
 >
 > on doTheGrab tCtl
 >    grab tCtl
 > end doTheGrab
 >
 > 4. Better do: start using stack “myBehaviorLib”
 >
 > Run it and drag the button you made. This will work in all stacks
 > with the on mouseDown script in it.
 >
 > So, the “myBehaviorLib” substack could be simply a script only stack
 > that contains some reasonable number of separate behavior type
 > scripts, and once the “start using” is invoked, say on a preopenStack
 > script, all common code for button behaviors becomes a single code
 > element. Inheritance, like adding new behavior is just adding another
 > script to the “on doABehavior” handler in the “myBehaviorLib” stack.
 > What you don’t get is the ability to have the same name for a bunch
 > of different behaviors, but …… perhaps it’s easier to keep track of
 > handler names that are different anyway.
 >
 > Somehow, this seems more direct to me. It also avoids the need for a
 > preloader stack the opens a bunch of small files that are behaviors.
 >
 > What do you think?






More information about the use-livecode mailing list