Syntax:
objectref „ ŚNEW classref
objectref „ ŚNEW classref param1 param2..
objectref „ ŚNEW 'classname'
objectref „ ŚNEW 'classname' param1 param2..
objectref „ 'env' ŚNEW 'classname'
objectref „ 'env' ŚNEW 'classname' param1 param2..
The system function ŚNEW is the principal means by which you create an object, i.e. an instance of a class. The class can be either written in APL (an internal or user-defined class), or a built-in System class, or a class written in an external environment such as .Net, Java or Ruby (an external class). ŚNEW creates a new instance of the class, runs any constructor defined for the class, and returns a reference to the new object as its explicit result.
The class is specified as the right argument (or first element of the right argument). It can be specified either as a class reference, or as a class name (i.e. a character vector). Any parameters to be passed to the constructor of the class (the method which is run automatically when a class is created) follow the class name or reference.
If you specify the class by name, you also need to identify the environment where the class exists, unless it is internal. The left argument is a character vector as follows (the keywords are not case-sensitive):
Left arg | Environment | Windows DLL | Macintosh bundle | Linux shared library |
'apl' or omitted | User-defined APL class | None | None | None |
'Ś' | System-defined class (ŚWI) | None | None | None |
'.net' | Microsoft .Net | aplxobj_net.dll | Not supported | Not supported |
'java' | Java | aplxobj_java.dll | aplxobj_java.bundle | aplxobj_java.so |
'r' | R | aplxobj_r.dll | aplxobj_r.bundle | aplxobj_r.so |
'ruby' | Ruby | aplxobj_ruby.dll | aplxobj_ruby.bundle | aplxobj_ruby.so |
Other | Customized environment | aplxobj_XXX.dll | aplxobj_XXX.bundle | aplxobj_XXX.so |
Left arg | Environment | Windows DLL | Linux shared library |
'apl' or omitted | User-defined APL class | None | None |
'Ś' | System-defined class (ŚWI) | None | None |
'.net' | Microsoft .Net | aplx64obj_net.dll | Not supported |
'java' | Java | aplx64obj_java.dll | aplx64obj_java.so |
'r' | R | aplx64obj_r.dll | aplx64obj_r.so |
'ruby' | Ruby | aplx64obj_ruby.dll | aplx64obj_ruby.so |
Other | Customized environment | aplx64obj_XXX.dll | aplx64obj_XXX.so |
Normally, you create an instance of a user-defined class by passing the class reference directly as the right argument (or first element of the right argument). For example, if you have a class called Invoice, you can create an instance of it by entering:
I„ŚNEW Invoice
What is really happening here is that the symbol Invoice refers to the class definition, and when it is used in this way, it returns a reference to the class. You can see this explictly:
Invoice © Entering the name of a class returns a reference to that class {Invoice} © Class references are displayed as class name in curly braces C„Invoice © C contains a second reference to the class Invoice C {Invoice} I2„ŚNEW C © ... so we can use C as the argument to ŚNEW I2.ŚCLASSNAME Invoice
Note that you can also pass the class name rather than a class reference. The following are alternative ways of creating an instance of a user-defined class:
I„ŚNEW 'Invoice' I„'apl' ŚNEW 'Invoice'
A constructor is a special method of a class, which is run automatically when the class is created using ŚNEW, and is used to initialize the class. For APL classes, the constructor is a method whose name is the same as the name of the class. It should be a function which takes a right argument, and does not return a result.
Any arguments to the constructor can be provided as extra elements on the right argument of ŚNEW. When the constructor is run, these extra elements are passed as the right argument to the constructor. If there are no extra elements, an empty vector is passed as the right argument to the constructor.
For example, suppose the class Invoice looks like this:
Invoice { TimeStamp Account InvNumber {Serial„0} ’Invoice B © Constructor for class Invoice. B is the account number Account„B TimeStamp„ŚTS Serial„Serial+1 InvNumber„Serial ’ }
When a new instance of this class is created, the constructor will be run. It will store the account number (passed as an argument to ŚNEW) in the property Account, and store the current time stamp in the property TimeStamp. It will then increment the class-wide property Serial (common to all instances of this class), and store the result in the property InvNumber.
S„ŚNEW Invoice 23533 S.ŚDS Account=23533, TimeStamp=2007 10 11 15 47 34 848, InvNumber=1 T„ŚNEW Invoice 67544 T.ŚDS Account=67544, TimeStamp=2007 10 11 15 48 11 773, InvNumber=2
(To see the properties, we use the system method ŚDS which summarizes the property values):
A System class is a pre-built class which is part of APLX. Examples are the Form, Timer, ChooseColor and Chart classes. (In previous versions of APLX, these classes were accessed through ŚWI).
To create an instance of a top-level System class, you can provide the name of the class as the right argument, and use 'Ś' as the left argument:
DLG„'Ś' ŚNEW 'ChooseColor' DLG.ŚNL 3 Close Create Delete New Open Send Set Show Trigger
You can then use dot notation to access the properties and methods of the object:
DLG.color„234 23 56 DLG.Show 1
To create an instance of an external class, you call ŚNEW with the class name as the right argument (possibly followed by constructor arguments), and the environment keyword (e.g. '.net', 'java', or 'ruby') as the right argument. (In some cases, you may need to call ŚSETUP first, to set up environment parameters such as the search path and namespace prefix).
Create an instance of the .Net DateTime class, defined in the .Net System namespace:
NETDATE„'.net' ŚNEW 'System.DateTime' 2007 6 20 9 32 3
Create an instance of the Ruby DateTime class, defined in the Ruby class library Date:
'ruby' ŚSETUP 'require' 'Date' RUBYDATE„'ruby' ŚNEW 'DateTime' 2007 6 20 9 32 3
Create an instance of the Java Date class:
JAVADATE„'java' ŚNEW 'java.util.Date' 2007 6 20 9 32 3
Use the ŚDS System method to convert each of the different objects to string form:
(3 1˝NETDATE,RUBYDATE,JAVADATE).ŚDS 20/06/2007 09:32:03 2007-06-20T09:32:03+00:00 Sat Jul 20 09:32:03 BST 3907
You can also obtain a reference to an external class, and use that instead of the class name (and left argument) to specify the class. For example:
NetDateClass„'.net' ŚGETCLASS 'DateTime' NetDateClass {.net:DateTime} START„ŚNEW NetDateClass 2004 12 4 12 34 2 START.ŚDS 04/12/2004 12:34:02
Because there may be a significant overhead in searching in the external environment for the class name, this method is likely to be more efficient if your application needs to create many different instances of a given class.
When you use ŚNEW to create a new object, that object persists until there are no more references to it in the workspace. It is then deleted immediately, if it is an internal or system object. If it is an external object, such as an instance of a .Net class, the fact that there are no more references to it in the APL workspace means that it available for deletion by the external environment (unless the external environment itself has further references to the same object). However, in typical external environments such as .Net, Java and Ruby, the actual deletion of the object may not occur until later.
Consider this sequence, where we create an instance of a class called Philosopher which has a property Name:
A„ŚNEW Philosopher A.Name„'Aristotle'
At this point, we have created a new instance of the class, and we have a single reference to it, in the variable A. We now copy the reference (not the object itself) to a variable B:
B„A B.Name Aristotle
We now have two references to the same object. So if we change a property of the object, the change is visible through either reference - they refer to the same thing:
B.Name„'Socrates' A.Name Socrates
Now we erase one of the references:
)ERASE A
We still have a second reference to the object. The object will persist until we delete the last reference to it:
B.Name Socrates )ERASE B
At this point, there are no more references to the object left in the workspace, and the object itself is deleted.
It follows from this that, if you use ŚNEW to create an object, and do not assign the result to a variable, it will immediately be deleted again. In this example, we create an instance of the class Philosopher. The explicit result of ŚNEW is a temporary workspace entry (of type object reference), which is displayed using the default display format for objects, and then deleted. AT that point the object itself is also deleted, as there are no references left:
ŚNEW Philosopher [Philosopher]
The ŚNEW mechanism also allows the same APL syntax to be used for accessing other object-oriented environments or custom class libraries written in languages such as C++. For example, you wanted to make use of a timeseries analysis class library written in C++, you could write a simple interface DLL aplxobj_ts.dll which would allow classes contained in that library to be used from APL:
TS„'ts' ŚNEW 'TimeSeries'
The APLX interpreter, seeing this line, would pick up the environment identifier 'ts' which would cause it to search for aplxobj_ts.dll to handle the creation and use of the classes within the custom library. Contact MicroAPL for more information on how to write customized interfaces.