Skip to main content

Objects

SenseTalk was designed to enable people to create their own software, without years of study to master the intricate and arcane details of programming. Information provided in other sections of this documentation focus on SenseTalk scripts primarily as simple lists of statements that tell the computer what you want it to do. For many people that basic approach to scripting will be sufficient for their needs.

For those who care to learn just a little bit more, SenseTalk’s object model offers a much richer environment, without adding greatly to its complexity.

The information explained here provides an overview of the modular structure of SenseTalk, and introduces the key concepts and terminology that you will want to be familiar with as you proceed with learning how to write your own object-oriented SenseTalk software.

Setting the Stage

SenseTalk is a "scripting" language. You create SenseTalk software by writing scripts that describe what different elements of your system will do. The usual way to do this in SenseTalk is to create a number of different “objects” which will be the actors in your system. Each object has its own script that tells what it does in the system. By taking this modular approach, each script can be relatively short and self-contained, which makes even complex systems relatively easy to work with.

The objects in your system will interact by sending and receiving messages. An object responds to a message if it has a handler for that message. A script consists of a series of handlers, one for each message that the object will respond to. Any other messages will be ignored by the object.

One SenseTalk object can help another. When you have a number of objects that need to have similar behaviors or abilities, you can create a helper object which embodies those shared behaviors and abilities. Each of the other objects can then be helped by the helper object, eliminating the need for them to each have those behaviors defined in their own scripts. This saves you a lot of time and effort. It also makes it easy to update a behavior by simply changing the script of the helper object. All of the other objects will then “inherit” the changed behavior.

It should be noted, for those who may be familiar with other object oriented languages, that SenseTalk is somewhat different. Most other languages define “classes” of objects and generally only implement behavior at the class level, for all objects in that class. In SenseTalk, each individual object has its own script, so it can have its own unique behavior.

SenseTalk has no classes, but its helpers provide a similarly rich set of capabilities by allowing objects to use (or inherit) functionality provided by any number of other objects. This all-object (classless) approach is both simpler and more versatile than class-based systems.

Objects Defined

SenseTalk is an Object-Oriented Language. SenseTalk scripts describe the behavior of objects. Depending on the host environment, an object may be something visible which can be directly manipulated and interacted with, such as a button or an image on the screen, or it may be more abstract, such as an object representing a bank account or an exercise schedule.

Whether an object represents something visual or something that is purely conceptual, all objects in the SenseTalk world share certain characteristics. Any object can have attributes, called properties, which store information that is important to that object. An object may also have behaviors, which are defined by the object’s script and define what the object can do.

In the case of a picture shown on a computer screen, its properties might include such things as its height and width as well as the colors of all the dots that form the image itself. An object representing a person’s contact information would include properties such as their name, telephone number, and mailing address.

An object’s behaviors as defined by its script might include such things as turning an image upside down, or sending an email message to a person on a mailing list. Other “behaviors” of an object may be more passive, such as providing information about the object which is not directly represented in its properties. For example, an object representing a person might include a property that stores their birth date. The object’s script could provide the person’s age by accessing the current date and calculating the number of years that have passed since their birth date.

Property Lists

Property lists were described in another section as a collection of values identified by their keys. It was mentioned there that a property list is actually a simple object.

A property list is an object that’s mainly properties. Behaviors can be added to a property list, though, either by assigning helpers, or by setting the script property to a valid script. For more information, see Helpers. To set the script of an object, simply store the text of one or more handlers into the “script” property of that object:

put {width:7,length:12} into myRect

set the script of myRect to {{
function area
return my width * my length
end area
}}

put myRect's area --> 84

Script Files

In many SenseTalk scripting environments, each script is stored in a text file on the disk. In these environments, each such file is a SenseTalk object, and the contents of the file is the object’s script.

A script consists of a sequence of SenseTalk commands (also called statements) which define the behaviors of that object. Here is the simplest and shortest complete SenseTalk script you are likely to encounter:

put "Hello, World!"

A script file is an object that’s mainly behaviors. The script above constitutes a very simple object, with a single behavior that will be invoked when the script is run: displaying the words “Hello, World!”.

Properties Declarations

In addition to behaviors, a script file may also include properties declarations if desired. When an object is created by loading a script file from disk, any properties declarations in that script will define initial values for the object’s properties.

A properties declaration can be placed outside of any handler. If it is the first thing in your script, the initial handler comes after it. For example, it would appear before a params declaration. Otherwise, it ends the initial handler like a declared handler does. For more information on working with handlers, see Handlers.

tip

While it is possible to have multiple properties declarations in the same script, for simplicity and to avoid confusion it is recommended to only use one.

Syntax:
Properties
    propertyKey1 : value1 ,
    {propertyKey2 : value2} ...
end Properties

Example:

This properties declaration defines five properties of the object, and assigns them initial values. Values that contain spaces and special characters must be enclosed in quotation marks, as shown here for the name and birthDate properties. Simple values do not require quotes, but may be quoted if you prefer. Some properties may be assigned a list of values, as shown for the helpers property.

Properties
name: "Charlie Brown",
birthDate: "May 14, 1942",
hairColor: brown,
numberOfSiblings: 1,
helpers: ["Linus", "Lucy"]
end properties

Script Folders

A folder can also serve as a SenseTalk object. When treating a folder as an object, each script file within the folder is treated as a handler of that object. If a script with the special name "_initialHandler_" exists in that folder, it will be loaded and used as the folder object's initial handler, and any properties defined in that script will be used as the initial property values of the folder object.

Using Objects

Creating Property Lists

A simple property list (an object with properties but no handlers) can be created by simply listing its properties and values in the format shown here:

put {x:44, y:108, z:-19} into point2

Creating Simple Objects

An object can be helped by other objects (helpers are described in detail later in this section):

put {name:"Hank", age:47} helped by parent,actor into person

Creating Initialized Objects

Fully-initialized objects can be created with a new object expression:

put new object with {width:14, length:9} into dimensions

When an object is created using new object as shown in the example here, the result is essentially the same as the simple objects shown earlier. The only difference is that an “initialize” message is sent to the newly-created object. Of course, it won’t have a handler to respond to that message, unless it has a helper with such a handler. You can create the object with one or more helpers, like this:

put new object with (partNum:1234) helped by part into aPart

Creating with Prototype Objects

A more common way to use a new object expression is to specify a “prototype object”, as shown in the following example:

set child to be a new Person with {name:"Penny", age:6}

In this example, Person is a prototype object. Prototype objects (if they want) can control exactly how the new object is constructed (the details of how this works are given later in this section). In the usual case, however, the new object will have the properties given in the script plus copies of any other properties from the prototype, and will be helped by the prototype object. So, unless the Person object overrides the usual behavior, the statement above would be equivalent to this:

set child to a new object with ({name:"Penny", age:6} adding properties of (object Person)) helped by Person

Accessing Object Properties

An object’s properties can be accessed in several different ways, using a dot (.) or apostrophe-S (‘s) and the property name after the object, or the property name followed by of before the object:

put {make:Yamaha, model:"U3", finish:"Walnut"} into piano
put "My piano is a " & piano.make && piano's model
put "It has a pretty " & finish of piano & "finish"

Object properties are containers. Properties can be added, deleted, or their values changed, as described in detail for property lists in Lists and Property Lists.

Using “Me” and “My” to Access an Object’s Own Properties

It is very common for an object to need to access its own properties from within its script. Rather than referring to itself by name, it can do this using the terms me and my:

put the age of me
if my name begins with "S" then return "Smilin' " & my name

Undefined Properties and the StrictProperties global property

Ordinarily, if you access a non-existent property of an object, SenseTalk will simply return empty as the value of that property. Occasionally, this may lead to trouble, such as if you inadvertently misspell the name of a property. To help with debugging your script in such cases, or if you simply prefer a more rigorous approach, you may set the strictProperties global property to true. When this property is set, any attempt to access a property of an object that has not been previously set will throw an exception.

put a new object into emptyObj
put (property abc of emptyObj) is empty -- displays 'true'
set the strictProperties to true
put (property abc of emptyObj) is empty -- throws an exception

Using “Object” to Ensure Object Access

In most contexts, SenseTalk can recognize when an object is needed and will treat a string value as the name of a script object. However, there are times when the meaning may be ambiguous. In these situations, the word object can be used to indicate that a value should be treated as an object name:

put "Person"'s greeting -- since "Person" is text, not an object, the greeting function will be called
put (object "Person")'s greeting -- treat "Person" as an object name, and access its greeting property