PL/SQL: Any trick to avoid cloning of objects? PL/SQL: Any trick to avoid cloning of objects? oracle oracle

PL/SQL: Any trick to avoid cloning of objects?


Based on Alex suggestion (use an associative array), I have created a package that encapsulates objects, so we can use them in an abstract way, as if they were references:

create or replace type cla as object        -- complex class(    name varchar2(10));create or replace package eo as     -- package to encapsulate objects    type ao_t                       -- type for hash (associative array)        is table of cla        index by varchar2(100);    o ao_t;                         -- hash of objectsend;declare    o1 varchar2(100);    o2 varchar2(100);begin    o1 := 'o1';                         -- objects are hash indexes now    eo.o(o1) := new cla('hi');          -- store new object into the hash    o2 := o1;                           -- assign object == assign index    eo.o(o1).name := 'bye';             -- change object attribute    dbms_output.put_line('eo.o(o1).name: ' || eo.o(o1).name);    dbms_output.put_line('eo.o(o2).name: ' || eo.o(o2).name);   -- equal?end;

Now 'bye' is written twice, as expected with object references. The trick is that both o1 and o2 contain the same index (~reference) to the same object. The syntax is a bit more complex, but still very similar to standard object manipulation when accessing both attributes and methods.

Assigning an object to other is exactly as standard object assigning:

o2 := o1;

Same for using an object as a function argument:

afunc(o1);

Internally, afunc() will just use o1 with the same special syntax to access methods or attributes (and no special syntax to assign):

eo.o(o1).attrib := 5;eo.o(o1).method('nice');o3 := o1;

The only requirement to use this trick is to add a hash (type and variable) to the eo package for each class we want to encapsulate.


Update: The index value based on the variable name:

o1 := 'o1';

could be a problem if, for example, we create the object in a funcion, since the function would have to know all values used in the rest of the program in order to avoid repeating a value. A solution is to take the value from the hash size:

o1 := eo.o.count;

That takes us into other problem: The hash content is persitent (since it is into a package), so more and more objects will be added to the hash as we create objects (even if the objects are created by the same function). A solution is to remove the object from the hash when we are done with the object:

eo.o(o1) = null;

So the fixed program would be:

create or replace type cla as object        -- complex class(    name varchar2(10));create or replace package eo as     -- package to encapsulate objects    type ao_t                       -- type for hash (associative array)        is table of cla        index by varchar2(100);    o ao_t;                         -- hash of objectsend;declare    o1 varchar2(100);    o2 varchar2(100);begin    o1 := eo.o.count;                   -- index based on hash size    eo.o(o1) := new cla('hi');          -- store new object into the hash    o2 := o1;                           -- assign object == assign index    eo.o(o1).name := 'bye';             -- change object attribute    dbms_output.put_line('eo.o(o1).name: ' || eo.o(o1).name);    dbms_output.put_line('eo.o(o2).name: ' || eo.o(o2).name);   -- equal?    eo.o(o1) = null;                    -- remove object    eo.o(o2) = null;                    -- remove object (redundant)end;