Referencing another class in a class constructor

Writing and using Classes in Dyalog APL

Referencing another class in a class constructor

Postby mfleming on Mon Jul 01, 2019 1:44 am

As part of a class constructor I would like to create an instance of another class and assign it to a field within the class instance I'm creating. Even if the two classes are in the same namespace, I get an undefined name value error for the code
Code: Select all
∇new0
:Access Public
:Implements Constructor
matl← ⎕NEW Material



In this example I have a namespace RayTracer and two classes within it, Shape and Material. The use of :Include with the enclosing namespace reference doesn't help, nor unfortunately does ⎕PATH. If I use an absolute path reference to Material, all is fine but it is not what I would prefer. A local relative path reference works, but only if I'm within the enclosing RayTracer namespace, i.e.
Code: Select all
matl← ⎕NEW ##.Material


If I try to create the class instance outside of the enclosing RayTracer namespace, for example in #, that also fails with undefined name. What I need is the equivalent of ⎕PATH for class references. Having to code all references as absolute within a constructor would pin me to a particular place, as in
Code: Select all
matl← ⎕NEW #.RayTracer.Material


The only alternative at the moment is to not assign the field in the constructor at all, but assign a class instance after creation like this
Code: Select all
⍝ Within RayTracer namespace
p←⎕NEW Shape
p.matl←⎕NEW Material

⍝ or anywhere else
p←⎕NEW #.RayTracer.Shape
p.matl←⎕NEW #.RayTracer.Material


This will work regardless of where I am, but requires a little extra work on the part of the programmer. Any suggestions on avoiding full namespace path references within the class code I'm writing if I'd like to create instances of other classes within constructors?

Thanks in advance,
~Mark
mfleming
 
Posts: 10
Joined: Sat Mar 02, 2019 11:09 pm

Re: Referencing another class in a class constructor

Postby paulmansour on Mon Jul 01, 2019 11:13 am

I if remember correctly, the problem here may be the naked ⎕NEW, which creates an instance of a class where the ⎕NEW is called, thus leaving the instance with no knowledge of where the actual class definition is (or where its brother and sister classes are).

I always ask the class to create its own instance using a static .New method. This ensures that all instances of the class are in a predictable location, and can thus find all related class definitions (or any other related assets) via relative paths by going up and over using ##. Something like:

Code: Select all
z←New x                      ⍝ Creates a New Instance
 :Access Public Shared        ⍝
 z←##.⎕NEW(↑∊⎕CLASS ⎕THIS)x   ⍝
paulmansour
 
Posts: 431
Joined: Fri Oct 03, 2008 4:14 pm


Return to Object Oriented Programming

Who is online

Users browsing this forum: No registered users and 1 guest