Apply a callback to an array: Difference between revisions

Line 1,275:
 
=={{header|PL/SQL}}==
PL/SQL doesn't have callbacks, though we can pass around an object and use its method to simulate one. Further, this callback method can be defined in an abstract class that the mapping function will expect.
{{works with|Oracle}}
<lang plsql>-- Let's create a generic class with one method to be used as an interface:
<lang plsql>set serveroutput on
create or replace
declare
TYPE callback AS OBJECT (
type myarray is table of number index by binary_integer;
-- A class needs at least one member even though we don't use it
x myarray;
-- There's no generic OBJECT type, so let's call it NUMBER
i pls_integer;
dummy NUMBER,
begin
-- Here's our function, and since PL/SQL doesn't have generics,
-- populate array
-- let's foruse itype inNUMBER for 1..5our loopparams
MEMBER FUNCTION exec(n number) RETURN number
x(i) := i;
) NOT FINAL not instantiable;
end loop;
/
i := x.first;
 
-- square array
-- Now let's inherit from that, defining a class with one method. We'll have ours square a number.
while i is not null loop
-- We can pass this class into any function that takes type callback:
x(i) := x(i)*x(i);
CREATE OR REPLACE TYPE CB_SQUARE under callback (
dbms_output.put_line(x(i));
OVERRIDING MEMBER FUNCTION exec(n NUMBER) RETURN NUMBER
i := x.next(i);
)
end loop;
/
end;
CREATE OR REPLACE
TYPE BODY CB_SQUARE AS
OVERRIDING MEMBER FUNCTION exec(n NUMBER) RETURN NUMBER IS
BEGIN
RETURN n * n;
END exec;
END;
/
 
-- And a package to hold our test
CREATE OR REPLACE
PACKAGE PKG_CALLBACK AS
myCallback cb_square;
TYPE intTable IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
ints intTable;
i PLS_INTEGER;
procedure test_callback;
END PKG_CALLBACK;
/
 
CREATE OR REPLACE PACKAGE BODY PKG_CALLBACK AS
-- Our generic mapping function that takes a "method" and a collection
-- Note that it takes the generic callback type
-- that doesn't know anything about squaring
procedure do_callback(myCallback IN callback, ints IN OUT intTable) IS
i pls_integerPLS_INTEGER;
myInt NUMBER;
begin
while for i isin 1 not.. nullints.count loop
x(i)myInt := x(i)*xints(i);
-- PL/SQL call's the child's method
ints(i) := myCallback.exec(myInt);
x myarray END LOOP;
end loopdo_callback;
 
procedure test_callback IS
BEGIN
myCallback := cb_square(null);
FOR i IN 1..5 LOOP
xints(i) := i;
END LOOP;
do_callback(myCallback, ints);
i := xints.firstFIRST;
WHILE i IS NOT NULL LOOP
dbms_outputDBMS_OUTPUT.put_line(xints(i));
i := xints.next(i);
END LOOP;
END test_callback;
END PKG_CALLBACK;
/
 
BEGIN
PKG_CALLBACK.TEST_CALLBACK();
END;
/</lang>
 
Anonymous user