Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PL/SQL private object method

I'm a bit new to Oracle's PL/SQL (using 10g), I was wondering if there's a way to make a private method in an object type, as is often done for private helper methods in other languages (Java, C++, C#, etc...). I know it is possible to make private methods in packages, but I can't seem to find a way to do this for object types. I keep getting compiler errors telling me:

Error: PLS-00539: subprogram 'FOO' is declared in an object type body 
and must be defined in the object type specification.
like image 406
PrivateMethodMan Avatar asked Oct 23 '25 18:10

PrivateMethodMan


1 Answers

Ok, here's a potential solution that I tested very briefly, and it seems to work so far:

Create a parent object type that will marked as NOT FINAL and NOT INSTANTIABLE and then put all the private code in there. The private methods won't be truly private, but putting them in a type that is not final and not instantiable prevents them from being called. In the instantiable subtype, reference the "private" methods in the supertype through SELF. Example:


create or replace type PrivateFoo under SuperFoo
(

  member procedure setUpCommonFoo
) NOT INSTANTIABLE NOT FINAL;

create or replace type body PrivateFoo is
  -- Member procedures and functions
  member procedure setUpCommonFoo is
        begin
            SELF.someAttrib:='Some Common Default Value';
        end;
end;

create or replace type Foo under PrivateFoo
(
    CONSTRUCTOR FUNCTION Foo RETURN SELF AS RESULT,
    CONSTRUCTOR FUNCTION Foo(fkey FooKey) RETURN SELF AS RESULT -- assume fkey is defined in SuperFoo, and FooKey type is defined somewhere else ;)
)

create or replace type body Foo is
    --no-arg Constructor For basic Foo set up.
    CONSTRUCTOR FUNCTION PartyConvertor RETURN SELF AS RESULT AS
    BEGIN
        self.setUpCommonFoo;
        RETURN;
    END;
        --alt constructor for other situations...
    CONSTRUCTOR FUNCTION PartyConvertor(fkey FooKey) RETURN SELF AS RESULT AS
    BEGIN
        self.setUpCommonFoo;
                SELF.rarelyUsedAttrib:='Special Value!'; --just assume that someAttrib and rarelyUsedAttrib actually exist ;)
        self.fkey := fkey;
        RETURN;
    END;
        --Other Members go here...
end;

Now I have to admit, I don't really like this pattern. It seems awkward and kludgy. I'm probably going to just avoid Object Types as much as I can and stick to packages (or very simlpe object types). A package-as-fatory only helps me solve the private common code problem for constructors, not for other types of common code refactoring.

...unless there's a better way to work with Object Types.... anyone? anyone?

like image 57
PrivateMethodMan Avatar answered Oct 26 '25 10:10

PrivateMethodMan