Topic: APLX Help : Help on APL language : System Functions & Variables : ⎕NEW Create new instance of class
[ Previous | Next | Contents | Index | APL Home ]

www.microapl.co.uk

⎕NEW Create new instance of class


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):

For 32-bit implementations of APLX:

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

For 64-bit implementations of APLX:

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

Creating instances of internal (user-defined) classes

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'

Passing arguments to the constructor

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):

Creating instances of System classes

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

Creating instances of External classes

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

Using references to external classes

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.

Object references and object lifetimes

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]

Customized interfaces

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.


Topic: APLX Help : Help on APL language : System Functions & Variables : ⎕NEW Create new instance of class
[ Previous | Next | Contents | Index | APL Home ]