Anonymous user
Apply a callback to an array: Difference between revisions
→{{header|PL/SQL}}
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.
<lang plsql>-- Let's create a generic class with one method to be used as an interface:
create or replace
TYPE callback AS OBJECT (
-- 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,
-- let's
MEMBER FUNCTION exec(n number) RETURN number
x(i) := i;▼
) NOT FINAL not instantiable;
end loop;▼
/
i := x.first;▼
-- 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);▼
)
/
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
myInt NUMBER;
▲ begin
-- PL/SQL call's the child's method
ints(i) := myCallback.exec(myInt);
procedure test_callback IS
BEGIN
myCallback := cb_square(null);
FOR i IN 1..5 LOOP
END LOOP;
do_callback(myCallback, ints);
WHILE i IS NOT NULL LOOP
END LOOP;
END test_callback;
END PKG_CALLBACK;
/
BEGIN
PKG_CALLBACK.TEST_CALLBACK();
END;
/</lang>
|