[Omnis-Newsletter] Omnis Technical Newsletter
omnis-news-admin@omnis.net
omnis-news-admin@omnis.net
Wed, 10 Jul 2002 17:22:28 +0100
July 10th, 2002
========================================
UNSUBSCRIBE OPTIONS: You have been sent this email because you have directly
signed up for, or expressed an interest in receiving a technical newsletter
when you downloaded an evaluation of Omnis Studio, or registered Omnis
Studio via a magazine promotion. If, however you feel you have received this
email in error you can unsubscribe as well as change your subscription
options at www.omnis.net/newsletter.
N.B. If you subscribed by checking a box on one of our forms, you will not
have received a password. You will need to submit your email address at
www.omnis.net/newsletter and select the 'email me my password' option on the
next page in order to receive this.
========================================
IMPORTANT
SUMMER BREAK: The Omnis Technical Newsletter is going on vacation for the
summer. Normal service will resume in September. In the meantime, thank you
for subscribing to this newsletter and may we wish you a happy and relaxing
holiday season.
========================================
WELCOME!
The Omnis Technical Newsletter is intended for Omnis developers of all
levels and experience, for those people evaluating Omnis Studio, or for
developers moving from a similar tool. We think you'll find the content both
interesting and useful for your Omnis development needs and hopefully it
will help you become more productive in Omnis application design.
In the first part of this newsletter, there is a summary of the latest Tech
Notes discussing the Omnis Web Client and Server products, located on the
Omnis web site. Plus we have some good news about the OzOmnis developer
conference. Then leading Omnis trainer and author David Swain discusses the
difference between public and private methods and demystifies messaging.
You may find it easier to work through the exercises and examples in this
newsletter by printing it out before you begin.
CONTENTS:
-Omnis Tech Notes: Omnis Web Client and Server
-FrontBase to sponsor OzOmnis conference
-Methods and Messages, by David Swain
-Copyright and Unsubscribe details
========================================
Omnis Tech Notes: Omnis Web Client and Server
The following section summarizes some of the more recent Tech Notes
discussing the Omnis Web Client and Server products.
TNWE0011 - NEW*
Deploying the Omnis Server on Linux Appliances.
This technical note explains the configuration changes that must be made to
Linux based server appliances to facilitate the use of the Omnis Web Client
Server.
http://www.omnis.net/develop/resources/notes/technotes/tnwe0011.html
TNWE0010 - NEW*
Configuring the Apache Web Server module on Mac OS X.
This tech note describes how you configure the Apache Web Server module on
Mac OS X for use with the Omnis Server serving Omnis web applications.
http://www.omnis.net/develop/resources/notes/technotes/tnwe0010.html
TNWE0009
Setting Secure mode for the Omnis Web Client plugin.
This tech note explains the way the Omnis Server and the Web Client works
with secure sockets.
http://www.omnis.net/develop/resources/notes/technotes/tnwe0009.html
For a full list of Omnis Tech Notes, please click on the following url:
http://www.omnis.net/develop/resources/notes/technotes.html
========================================
FrontBase to sponsor OzOmnis conference...
The organizing team for OzOmnis has recently announced that FrontBase Inc,
the Scalable Relational Database Server Company, will both sponsor and
present at OzOmnis 2002 in Newport, Sydney Australia this August. OzOmnis is
a brand new technology-lead conference organized for and by the Omnis
Developer Community in the South East Asian region. The conference takes
place August 10-13, 2002, at the Newport Mirage in the northern beach area
of Sydney Australia, and is hosted by The DLA Group, Omnis distributor for
South East Asia.
SPECIAL OFFER: Register before July 13th and save money on fully inclusive
conference fees! Please read the full story in the Omnis news at:
www.omnis.net/news
Or go to the OzOmnis web site for latest details about the conference:
www.ozomnis.com
========================================
Methods and Messages
By David Swain, Polymath Business Systems Inc
Email: dataguru@polymath-bus-sys.com
Web: www.polymath-bus-sys.com
About the Author
David Swain is the founder and president of Polymath Business Systems, for
many years a leading provider of Omnis training. His expertise in Omnis
programming and his ability to make complex concepts understandable are
recognized throughout the worldwide Omnis community. His current schedule of
Omnis Studio training classes can be found on his web site at
http://www.polymath-bus-sys.com.
========================================
It has come to my attention that many people are either confused or
concerned about how methods and event handlers are executed in Omnis Studio.
Questions occasionally arise on the Omnis Underground list (and in my own
mailbox!) like "When should I make a method public as opposed to private?",
"When should I use the 'Do' command as opposed to 'Do method'?" and "How do
I detect the <insert name here> event?". Apparently it's time for some
clarification on these issues.
I will tackle this set of questions in two parts: In this issue of Omnis
Tech News I will examine methods and how we invoke them in Omnis Studio. In
the next issue I will detail how events are detected and handled.
The information in this series of articles is a small part of my "Omnis
Studio 101" course given at all the international Omnis Studio conferences
(and elsewhere) for the past few years. If you are within range of the
OzOmnis conference in Sydney, Australia next month, be sure to attend these
sessions to get the most complete version of the Omnis Studio story.
Back to Basics
In an attempt to avoid tripping over terminology, let's first define what it
is we're talking about:
A "method" is a set of computer instructions that are arranged in sequential
order for execution. A method "belongs to" or "is part of" a specific
object - it cannot stand alone. The word "object" is used in this discussion
in its broadest sense - as either a class (or instance) or a component
object of a class (or instance). In this sense, we can think of a method as
being a "behavior property" of that object.
There are two basic types of methods: "built-in" methods (we will ignore
these in much of the rest of this discussion) that ship with Omnis Studio
and its components and "custom" methods that are made up of Omnis Studio
method command objects. We cannot examine what makes up the "built-in"
methods since they are compiled directly from the source code of Omnis
Studio, but we can often create "custom" methods with the same name that
"override" the built-in method. More on this later...
The basic distinguishing feature of a method is its "name". Each method must
be named uniquely within its object (otherwise, there would be confusion).
The way that we name a method determines its "visibility" within our
application. There are two flavors of "visibility": "public" methods and
"private" methods.
"Public" methods can be "seen" (and therefore invoked) from outside the
object that contains them. In Omnis Studio, we make a "custom" method
"public" by beginning its name with a "$". The method name is then part of
the "public interface" of each instance of that object. (All built-in
methods - at least, the ones we're aware of - are public because their names
all begin with a "$".)
"Private" methods can only be "seen" from within the object and its methods.
Private methods of a container object can be seen by the methods of the
container and the methods of objects held within the container. We make a
method "private" by NOT beginning its name with a "$".
Why would we choose to make some methods private? The primary reason in my
work (you may find others) is that it may be a method containing common code
that is "shared" by many other methods of the object, yet the method does
not "stand alone" well enough to be offered as part of the public interface.
Messaging
A "message" is an instruction sent to an object to perform one of its public
methods. "Messaging" is a means (but not the only one) of invoking a public
method. In Omnis Studio we send such messages using Omnis (Dot) Notation.
There are two ways we can do this: "explicit" messaging and "implicit"
messaging.
With "explicit" messaging we use the "Do" command to directly tell an object
to execute one of its methods. This generally takes the form:
Do <notation identifying object>.$methodname()
The Notation string containing the message is the expression in the
"Calculation" "property" of the "Do" command. The parentheses following the
name of the public method can contain a comma-delimited list of parameters
for the method, but are required even if the method needs no parameters.
With "implicit" messaging we simply use a Notation string as given above
within any "live" expression in our application. ("Live" expressions are
those that are tokenized. This includes expressions injected into an
otherwise "static" string using "Square Bracket Notation".) In fact, the
"Do" command is nothing more than a "placeholder" command that puts an
expression on a method line, so "explicit" messaging is a simple subset of
"implicit" messaging. While we often place a single message in a "Do"
command, we can put as many messages in its expression as we need. The
operators and parentheses we use to "combine" these messages in the
expression determine the order in which the messages are issued.
Messaging is often described as a democratic means of allowing
self-determination for objects. Rather than forcing them to reveal their
innermost secrets, we politely request of them that they execute the public
method we name and we don't concern ourselves with the inner workings of how
the job gets done. There is a small catch in the way this is implemented.
The Dark Side of Messaging
Try a little experiment: Create a new window class. Somewhere on this window
class, place a new pushbutton and make sure its "buttonmode" property value
is set to "kBMuser". Put the following code in the "$event" method of the
pushbutton object:
On evClick
Do $cobj.$testmethod()
OK message {method call completed}
Now open a test instance of the window class and click the pushbutton. The
"OK" dialog box will appear. Does this result seem at all odd to you? The
pushbutton does not contain a method named "$testmethod" (at least I didn't
tell you to create one...), but Omnis Studio moved right along as if it
did - with no warning of any kind that such a method doesn't exist!
If there is a downside to messaging, it is this: if the method mentioned in
the message doesn't exist (or is just spelled wrong), there is no error
generated. It simply isn't executed. The message is sent, but there is no
automatic test to make certain that it can be received.
The "Do" command (and messaging in general) is not only democratic - it is
altruistic. It doesn't expect anything in return once having issued its
message. It somewhat reminds me of the old "altruistic love" mantra from the
'60s: "If you love a thing, let it go. If it comes back to you, it was and
always will be yours. If it does not, it was never yours to begin with."
While this made perfect sense to me as a liberal teenager, it causes me some
concern as a conservative programmer using messaging.
This doesn't prevent me from using the messaging technique (far from it!),
but it is important to be aware of this aspect of invoking methods through
messaging when debugging. If it appears that a method invoked through
messaging is not performing, make sure that the method exists in the target
object and that everything is spelled correctly in the message.
There are, in fact, techniques that rely upon this "broadcast" feature of
messaging. When used with the "$sendall()" method for an object group, we
can rely on a message only being acted upon by objects that contain the
named method. Occasionally this will relieve us from having to specify a
second parameter of "$sendall()" to limit the message to only a subset of
the members of the group. The implied subset is "all members that contain
the named method".
"Do" vs. "Do Method"
There is another command that can be used to invoke a "custom" method: the
"Do method" command. This command is used to invoke a method in the more
traditional way - with a test to be certain that the named method exists
before attempting to execute it.
The "Do method" command is the ONLY way to invoke a private method of an
object, but invoking private methods is not the only use of this command. We
can invoke public methods using this command as well. There are advantages
to this, but there are also some significant restrictions.
To invoke a method using "Do method", the target method has to be "in
scope". (Only "custom" methods can be so invoked - not "built-in" methods.)
It will be easiest to explain this by examining the options of this command
in the Method Editor. Suppose we wish to use the "Do method" command as a
line in a method of a window field component object. Further suppose that
the window class contains public and private methods, as does the field. The
"details" view of the "Do method" command displays a scrolling list that
contains first the public and private methods of the field itself, then
those of the window class, followed by three lines labeled "$cfield...",
"$cinst..." and "$ctask...". These last three lines can be double-clicked to
reveal the public methods of the current field, (window) instance and task
instance in Notational form. We can select any of these as the target of the
"Do method" command.
Interestingly, if the field is contained in a "container" field (such as a
tab pane), we cannot use the "Do method" command to invoke a method of the
container field. No "$ccontainer" line appears in the selection list. We can
invoke either public or private methods of the class without qualifying it
(using its name without reference to the class itself) or public methods of
the current instance of that class or of the task instance containing it
WITH qualification (prefixed by "$cinst." or "$ctask."). These methods are
all "in scope" for the "Do method" command.
There is an additional benefit to using "Do method" to invoke methods. Not
only are these methods "in scope", they are in known memory locations, so
they can be more quickly invoked. When using messaging, the Notation string
must be "resolved" to determine which method to invoke. When using "Do
method", Omnis Studio knows that the method must be in a rather restricted
area of RAM, so it can locate and execute the code faster than with
messaging. While today's computers are very fast even for slow processes,
there is still a performance benefit for using "Do method" over messaging.
The "Do method" command expects to be listened to and reports an error if
the named method doesn't exist. The name of the target method is stored as a
string and not as a token, so misspellings can still occur and method name
changes are not "automatically" made in a "Do method" line. But if the
method named in this command line does not exist, an error is reported at
runtime and the debugger indicates that the method name is not valid. This
is the behavior that we programmers expect - and it helps us tremendously in
tracking down errors in our code during development!
Method Execution Stack
Methods are executed in a linear fashion. When a method is invoked, it is
placed in an area of RAM known as the "Method Stack" and executed one line
at a time. If another method is invoked from within the first method, the
new method is placed "on top of" the first on the stack and is executed one
line at a time until there are no more lines left to execute. The second
method is then removed from the stack and the original method continues from
where it left off. This process can occur for many levels of "nesting".
At no time can a method in the middle of the stack continue or quit
execution. Only the "topmost" method on the stack is active and it must
complete execution (or be quit) before the one "beneath" it can continue (or
be quit).
When Omnis Studio drops into the debugger, we can examine the Method Stack
using the "Stack" menu in the Method Editor. While we can't see everything
contained in this stack, we can see which methods are contained in it and
the order in which they were invoked. We can also go to each method on the
stack and view the "Return Point" for that method. This is the line
following the one that invoked the method above it on the stack - the line
that will be executed next when execution returns to that method.
Return Values
Both the "Do" and the "Do method" commands offer a provision for a "return
variable". The "Returns" feature is optional, but should be given the name
of an appropriate variable if a return value is desired. The "return value"
is generated using the optional "Returns" expression of the "Quit method"
command.
The return value can be anything from a simple Boolean that indicates
success or failure of subroutine execution to a value used for further
processing in the main method. For "explicit" messaging and methods invoked
using the "Do method" command, the value is returned into the variable
specified in the "Returns" field of the command. For example:
Do $cinst.$methodname returns errorcode
will receive a value in the variable "errorcode", which can then be tested
or displayed. The command line in the subroutine that generates this value
might be:
Quit method kFalse
For "implicit" messaging, the value is returned in-line in the expression,
replacing the message. For example:
Calculate result as $cinst.$customfunction(operand)*25
sends the value of "operand" as a parameter to the public method
"$customfunction" of the current instance. "$customfunction" returns a
value, which is then multiplied by 25. The return value is generated in the
same manner as before, but no variable is required (or able!) to receive the
return value in this case. The message acts like any other function call.
Overriding Built-In Methods
Built-in methods can also be customized. While we can't see what a built-in
method contains, we can create a custom method with the same name that will
"override" the Built-in method. Usually the custom method must include a
line that states "Do default" so that the default behavior of the built-in
method takes place. This is especially important when overriding methods
like "$redraw" and "$print" where it is desirable to have the default
behavior occur. The "Do default" allows us to determine at what point in our
custom method the default behavior is to be executed.
Occasionally, overriding methods are assumed to add functionality to a
built-in method that will be executed in any event, but in a predetermined
order. This is the case with "$construct" and "$destruct". In these cases,
the command line "Do default" is not required and will be ignored if
included. A custom "$construct" contains command lines that are executed
between the initial construction of an instance and its eventual drawing on
the monitor. A custom "$destruct" is executed before the final destruction
of the instance.
Code Methods
I have studiously avoided mention of the "Do code method" command in this
article, as it is only useful and proper in very specialized circumstances.
In general, use of the "Do code method" command is not recommended. It is
primarily included in Omnis Studio for backwards compatibility with Omnis 7
and earlier versions of Omnis.
========================================
I hope you've found this issue of the Omnis Tech Newsletter both interesting
and informative. Please send me your comments and feedback, and include
suggestions for future articles if you like. We would like to hear from
you...
Regards,
--Andrew Smith.
Omnis Technical Newsletter Editor
Email: editor@omnis.net
========================================
No part of this newsletter may be reproduced, transmitted, stored in a
retrieval system or translated into any language in any form by any means
without the written permission of Raining Data.
(c) Copyright Raining Data, Inc., and its licensors 2002. All rights
reserved.
Omnis(r) is a registered trademark and Omnis 7(tm), and Omnis Studio are
trademarks of Raining Data UK Ltd. Other products mentioned are trademarks
or registered trademarks of their corporations.
========================================
To unsubscribe from this newsletter or change your subscription options,
please go to:
www.omnis.net/newsletter