LessonsAdvanced: Bigger programsLesson 46

Libraries

Share handlers across a whole program with library stacks, keep helpers private, and use front and back scripts to see or catch every message.

  • Advanced
  • Lesson 46 of 83
  • About 10 minutes
  • 6 examples

Handlers for the whole program

A handler in a stack's script serves that stack's cards and controls (The message path). A library goes further: a stack whose handlers every script of the program can call, in any stack, as if they were built in. Text tools, a settings store, the code that talks to a server: anything several stacks need belongs in one.

start using

start using puts a stack's script on the message path of everything, after each stack's own script. stop using takes it off again. A library is usually a script-only stack, saved as a .livecodescript file beside the program; here the example makes one:

ExampleRun it in the playground
create script only stack "TextTools"
put "function shoutText pText" & return into tScript
put "   return toUpper(pText) & " & quote & "!" & quote & return after tScript
put "end shoutText" after tScript
set the script of stack "TextTools" to tScript

start using stack "TextTools"
put shoutText("hello")
put "TextTools" is among the lines of the stacksInUse

stop using stack "TextTools"
try
   put shoutText("again")
catch tError
   put "shoutText is gone"
end try
delete stack "TextTools"
Output
HELLO!
true
shoutText is gone

the stacksInUse lists the libraries in use, a line each. The IDE uses libraries of its own, so in the IDE the list is longer than yours: check for your library's name in it, as the example does, rather than counting.

When it is put into use, a library is sent libraryStack, and when it is taken out, releaseStack: the places to set it up and tidy it away. Other stacks' messages pass through a library too, so check that the message is the library's own:

ScriptPut it in an object's script
local sSettings

on libraryStack
   if the target is not me then pass libraryStack
   put empty into sSettings
   put "light" into sSettings["theme"]
end libraryStack

on releaseStack
   if the target is not me then pass releaseStack
   put empty into sSettings
end releaseStack

function settingOf pName
   return sSettings[pName]
end settingOf

Private helpers

Everything a library offers shares one name space with every other library and every script on the path, so a library should offer few names, and keep its helpers to itself. A handler marked private can be called only from its own script:

ExampleRun it in the playground
create script only stack "Counter"
put "local sCount" & return into tScript
put "command countUp" & return after tScript
put "   add 1 to sCount" & return after tScript
put "   return describeCount()" & return after tScript
put "end countUp" & return after tScript
put "private function describeCount" & return after tScript
put "   return " & quote & "the count is " & quote & " & sCount" & return after tScript
put "end describeCount" after tScript
set the script of stack "Counter" to tScript
start using stack "Counter"

countUp
put the result
countUp
put the result
try
   put describeCount()
catch tError
   put "describeCount is private"
end try

stop using stack "Counter"
delete stack "Counter"
Output
the count is 1
the count is 2
describeCount is private

A script local such as sCount belongs to the library's script and lasts as long as the library is open, so it is a library's memory: settings, a cache, the connection it made.

Front and back scripts

Any object's script can be inserted into the message path at either end. A front script sees every message before the object it is sent to: useful for logging, or for a tool that watches clicks. It should pass the message on, or it takes it away from everyone. The examples here make their buttons with create (Making controls from a script) and give them their scripts, so that each runs in one piece; in a stack of your own you would drag the buttons from the Tools palette and type the handlers into their scripts:

ExampleRun it in the playground
create invisible button "Spy"
set the script of it to "on mouseUp" & return & \
      "   put " & quote & "the front script saw a click on " & quote & " & the short name of the target" & return & \
      "   pass mouseUp" & return & "end mouseUp"
insert the script of it into front

create button "Go"
set the script of it to "on mouseUp" & return & "   put " & quote & "Go was clicked" & quote & return & "end mouseUp"
send "mouseUp" to button "Go"

remove the script of button "Spy" from front
send "mouseUp" to button "Go"
Output
the front script saw a click on Go
Go was clicked
Go was clicked

A back script sees a message only when nothing before it took the message: a place for what should happen when nothing else does.

ExampleRun it in the playground
create invisible button "Fallback"
set the script of it to "on mouseUp" & return & "   put " & quote & "no one else took the click" & quote & return & "end mouseUp"
insert the script of it into back

create button "Quiet"
send "mouseUp" to button "Quiet"
remove the script of button "Fallback" from back
Output
no one else took the click

the frontScripts and the backScripts list them. Libraries, back scripts and front scripts stay in place until they are removed or the program quits, so remove one when its work is done.

Try it yourself

Make a library Stats with a public function statsMean (the mean of a comma-separated list of numbers) and a private helper that adds the list up. Use it, put the mean of 4,8,15,16,23,42, show that the helper cannot be called from outside, and tidy up.

Show a solution
ExampleRun it in the playground
create script only stack "Stats"
put "function statsMean pList" & return after tScript
put "   return statsTotal(pList) / the number of items of pList" & return after tScript
put "end statsMean" & return after tScript
put "private function statsTotal pList" & return after tScript
put "   local tTotal" & return after tScript
put "   repeat for each item tNumber in pList" & return after tScript
put "      add tNumber to tTotal" & return after tScript
put "   end repeat" & return after tScript
put "   return tTotal" & return after tScript
put "end statsTotal" after tScript
set the script of stack "Stats" to tScript
start using stack "Stats"

put statsMean("4,8,15,16,23,42")
try
   put statsTotal("1,2")
catch tError
   put "statsTotal is private"
end try

stop using stack "Stats"
delete stack "Stats"
Output
18
statsTotal is private

Words in this lesson

Each one finds every lesson that uses it. The Dictionary has the whole story of each, with its syntax and more examples.