| Version 1.9 Build 1556
|
|
Next: Testing Your Application
Up: How to Write an AIPS++ Application
Previous: Creating Distributed Objects
Subsections
Binding Distributed Objects to Glish
Next we show the Glish code necessary to bind
this class so that the user can manipulate it directly.6
if (! is_defined('squarer_g_included')) { # 1
squarer_g_included := 'yes';
include "servers.g" # 2
const squarer := function(host='', forcenewserver = F) { # 3
self := [=] # 4
public := [=] # 5
self.agent := defaultservers.activate("dsquarer", host, # 6
forcenewserver)
self.id := defaultservers.create(self.agent, "squarer") # 7
self.squareRec := [_method="square", # 8
_sequence=self.id._sequence]
public.square := function(x) { # 9
wider self # 10
self.squareRec["x"] := x # 11
return defaultservers.run(self.agent, self.squareRec) # 12
}
return public
} # constructor
} # include guard
Some comments on individual lines:
- 1.
- This is how you implement an include guard in Glish, to
prevent multiple-inclusion of the file.
- 2.
- This file must be included -- it contains the code that knows
how to communicate with the server executables and DO's.
- 3.
- This global function is the glish equivalent of our default
constructor -- and it will end up calling the default constructor.
Normally the system will keep all the objects in the same server
process, however you can force new server processes (possibly
on different hosts on the network) if the user wants to
to use coarse-grained parallelism. Constructor functions, like
most global functions and objects, should be const to prevent
users from accidentally overwriting them. We shall see later
how to bind classes with non-default constructors.
- 4.
- This record will hold our private data.
- 5.
- This record will hold our public member functions. It is the
users interface to the DO.
- 6.
- This activates a server process if necessary. dsquarer7 is the name of the binary executable on disk (it
must be in
the path). This is the line that maps the name of the class to
the name of the executable that serves it.
defaultservers implements the communication link to the
server and its DO's.
- 7.
- This line creates the DO in the server of the specified type.
In the event of an error, a Glish fail will be returned.
- 8.
- While you could create the record that is passed back and forth
to the DO afresh each time, it is most efficient to cache it
so it is created only once. You must always set the method name
and sequence number. Note the leading underscores!
- 9.
- This is the square() member function proxy that will invoke
the real function in the DO.
- 10.
- This is a bit of Glish magic that you need to get at your private
data. If you want access to the other member functions in this
function you would also need wider public.
- 11.
- Put the supplied parameters into the record that will be passed
to the DO.
- 12.
- Invoke the actual function in the DO. Note that if you had
Out or InOut parameters, the glish arguments would
be of type ref, and you would have to change the arguments before
returning. For example, suppose ``a'' was changed in place, then
this function would look like:
public.square := function(ref x) {
wider self
self.squareRec["x"] := x
returnval := defaultservers.run(self.agent, self.squareRec)
val x := self.squareRec.x
return returnval
}
Binding objects with non-standard constructors
If you are only using the default constructor, you can ignore this
section.
If you have a DO class with more than one constructor, you need to
have more than one global function that constructs the object. To do
this, you:
- 1.
- Factor out the code that sets up the public functions into a
global function unintended for general consumption; and
- 2.
- Call that function from each constructor function.
This is illustrated in the next code fragment. To hide the
common creation function, we suggest that there names begin with an
underscore and that they not be documented in user documentation.
const _define_image := function(ref agent, id) {
self := [=]
public := [=]
self.agent := ref agent;
self.id := id;
... Define the functions here ...
return public
} # _define_image()
const image := function(filename, host='', forcenewserver=F) {
agent := defaultservers.activate("image", host, forcenewserver)
id := defaultservers.create(agent, "image", "image",
[theimage=filename]);
return _define_image(agent,id);
} # image()
const fits2image := function(imagefile, fitsfile, whichhdu=1,
host='', forcenewserver=F) {
... create using the fits2image constructor ...
} # fits2image()
Next: Testing Your Application
Up: How to Write an AIPS++ Application
Previous: Creating Distributed Objects
  Contents
Please send questions or comments about AIPS++ to aips2-request@nrao.edu.
Copyright © 1995-2000 Associated Universities Inc.,
Washington, D.C.
Return to AIPS++ Home Page
2006-10-15