Why is object orientation useful? The primary reasons, as far as viola-type applications are concerned, are:
From the point of the view of interepreter implementation,
The "single inheritance" classing model used in viola defines the basic types, or "classes", of object instances. Many of these predefined class types happen to be graphical user interface (GUI) oriented, because of the current application emphasis on hypermedia.
An Viola application consists of a collection of objects. Some Viola objects are purely visual (graphics), some are interactive (buttons, sliders, hypertext). There are also objects of non visual functions, but acting as repository of procedures, or as communication gateways to the network and to forked processes.
Shown below is the Viola class hierarchy tree. Note that the Cosmic class is the root of the hierarchy.
Each new class may define new attributes, and all classes inherit all attributes from the "super" (hierarchy ancestor) class. So, every object would have more or less the same sets of attributes, depending on the class of the object. (See Section 3.8 for more details on the classing system, and Appendix B for full reference on individual classes).
More complex GUIs can be composed out of the individual and simple classes.
For example, the "HTML" class as its own class no longer exists. It existed for the 1992 release of ViolaWWW. Since then, however, that special HTML class has been made obsolete because its functionality has been decostructed into more elemental components, such that the 1993 (and later) versions of ViolaWWW no longer uses the "HTML" class. Instead, ViolaWWW now constructs it HTML out of more primitive classes. Everything you see on the very rich HTML page is composed from the simpler parts. In fact, this deconstruction has made it easier to add new parts into Viola's HTML-- Fewer things are hard-coded, and more parts are now 'glued' together using the interpretive system.
For a more concrete example-- to build a dialog box -- a script could be written to create the necessary objects, and somehow them together to constitute a dialog box.
Making a dialog box can be made easy by calling a pre written procedure. The current way to do this in Viola is to build a kind of ``dialog box maker'', so that it can easily be employed by sending to it a ``Please make me a dialog box, with the following specifications...'' message.
First, let's make a button that, when clicked on, will invoke a dialog box.
Now, let's describe the dialog box application.
Save the two separate applications into two files, "hello.v" and "dialog.v".
Running Viola with hello.v will cause a button, labeled ``Click me!'', to appear. When it is clicked on, the button object "ask" will eventually receive a "buttonRelease" message, which according to the script will causes the object "dialog" to be called with the six parts message list.
All objects must have unique names. The convention is to use "." character to denote the hierarchical relationship between objects. For example: object "hello" is the parent of object "hello.msg". Other than this convention, an object name is a pretty arbitrary string. Not completely arbitrary because although you can call to an object named, say, " 123" by this statement ``send(" 123", "render");''. But, you can not with this `` 123("render");'', because the lexical analyzer will truncate the leading space character.
An object is basically a collection of attributes, representing the states of an entity that's called an "object". Even the "script" of an object is really just an attribute of the object.
Many attributes can be affected at the script level. The most basic way to see the value of an attribute is to use the 'get' method.
Note that there are some 'short cuts' to the get(attrname). Such as width() instead of get("width"). Same with height(), parent(), self(). Should use the get() method, since this method has been optimized and now actually runs faster than the abbreviations (XXX: confirm this).
Use the 'set' method to modify the attribute values. For example:
But, certain attributes can not be changed once the object is instantiated. The "class" attribute is the prime example. See the class documentation for more information on which slots are alterable.
When an object is referenced, viola first assumes that the object already exists (tries to find it in memory). If that fails, then it tries to load an object file (of the same same as the object plus the ".v" extension) from the file directories specified in the VIOLA_PATH environment variable (in lieu of the -path startup option).
Note that this behaviour works because it assumes that the first reference to an object file is also the name of the top-level object. So, make sure that the first reference to an application is, for example, the object "hello", and not the object "hello.pane.mesg".
[XXX: talk about how to explicitly load object files with the start up '-o' flag. how to refer to the exact path of the file. Using HTGet() and loadObjectFile() together.]
To avoid getting viola confused about which object/application files to load, try to use the top-level object as the gateway into the application. That is, use the top-level object to receive all messages that might be coming from outside the application, and as a message relay.
This auto loading scheme makes it feasible to build a vast number of useful objects and file them away in places like /usr/local/viola/lib, to be loaded and instantiated automatically only when needed.
Viola objects can be saved in a file, in those files with the ".v" file suffix.
A viola "objects" or "application" file is basically just a collection of description of objects, and each object is described by a collection of attributes, and an attribute is described by a name and value pair.
All information that's saved about an object is the attributes. Not all the object states are saved (refer to the object class descriptions (Appendix B) for information on what attributes are not saved). For example, variables created by scripts are not saved.
In this attributes description, a most important attribute is the "class" attribute of the object. Because, the class specification implies a lot of the object. The information listed is essentially 1) the class of an object, 2) all the other information that is different from the class defaults. Basically, viola reads a group of attributes, extracts the class attribute, instantiate the object of that class and fills in the default values defined for objects of that class. Then, viola modified the cookie stamped object by replacing the default attributes with those specified in the file.
The format is meant to be as human readable as is possible, and most data can be included into the file format. But, not binary data such as GIF. The ordering of the attributes is not significant.
This behavior of not requiring specification of all values is convenient. But it doesn't hurt if your application redundantly specifies attribute values that are the same as the defaults.
For information on the default slot values, refer to docmentation on the classes.
Each Viola object consists of a grouping of of ``slots'', each containing certain information pertaining specifically to the object: its class, name, script, colors, and so on. The number and type of each slot in an object is determined by the class of the object.
Each class inherits slot definitions from its superclasses, and has the option to set new values for the inherited slots (slots defined by super classes). In addition to the inherited slots, it may define two types of new slots: private and common.
The separation of common and private slots reduces redundancy of information carried by each object.
Common slots define slots that are shared by all object instances of the same class. An example of a common slot is the class script which is the default script that all object in the same class share.
Private slots define slots that make up each object instance. Examples of private slots are the objects' names, buton labels, slider values, toggle button states, etc.
As with slots, class methods are also inherited. The idea, again, is to provide a mechanism for sharing as much code as possible. It also makes the task of subclasing relatively easy and systematic. Note that the modification of the object system (to subclass, adding slots and methods) must, at this point, be done in C. There isn't yet provisions for dynamically defining new class objects.
The cosmic class defines the minimal object: a private slot that lets the object know what class it belongs to; and essential methods such as create(), destroy(), save(), etc. From here on the slots and methods definition is rather arbitrary and depends on what the application is.
And, the generic class defines more non-absolutely-necessary slots such as name, parent, childeren, message, ...; and methods like print(), cosine(), etc. and so on.
After instantiating an object to the specified class, the object is initialized with the attribute information that is specified. For example, the object "hello.greet" gets its "content" attribte set to the message "Hello World". All the other attributes in the object take on default values.
Viola will fill those objects with whatever information it can use. For instance, the "content" attribute of the object "hello.greet" would be set to the string "Hello World!", etc. and so on.