Extensible class - for lack of a better term

Ok I came up with this idea in the middle of the night, and not sure if it is possilbe (perhaps someone has a different way to do it)

What I want to do is take a class that I have, and add code to it to allow it to support extra features that won’t be in the class it self… (yet)

Say for example in the class there was this line

#IF xyzflag 
   executeNewStuff()
#End if

but xyzFlag and the method executeNewStuff() are NOT in the code for the class,

There is also a MODULE (available seperatly) the has something like

public const xyzflag as boolean=true
sub executeNewStuff()
....
end sub

So if you ONLY had the class and NOT the companion module, it still compile, still runs, just you don’t get the benefit of whatever “executeNewStuff” can provide.
But if you add the extra Module to your project, you get it all. And the ONLY thing you have to do as a developer is include the module… NOTHING else

Is this possible? if not using this type of method, what would one do? Or can it not be done?

Sounds like what you want is a class that implements a bunch of methods that the class can use at points it defines.
Not a single delegate method but a class that holds a number of delegates that the class can call.

I don’t think it can be done, at least not the way you described it. The problem is, there is no compiler directive that will ignore code if some module, class, or plugin does not exist.

However, what if it wasn’t a module but a superclass.

Class MySuperClass
  Const xyzFlag As Boolean = False
  Sub ExcecuteNewStuff()
    // Does nothing
  End Sub

Class MySubclass As SuperClass

// Main
dim c as new MySubclass
#if MySubclass.xyzFlag then
  c.ExecuteNewStuff
#endif

The initial MySuperClass is a placeholder with no methods. Later, you can replace MySuperClass with a version that has the code you want.

Sounds like you want Extension Methods.

The thing is I don’t want two versions of the class…
I want it to be a two part solution…

If you have the original class you have the “lite” version
if later you simply add the module to your project you have the “Pro” version…
I don’t want to integrate all the ‘Pro’ features into the class code…

It was just an idea… Thanks

I think my idea did that for you, in a fashion. But instead of “adding”, the user will replace the superclass.

I understand that Kem… meaning I have to maintain either two classes or one class with flags in it… not what I want.

[quote=293589:@Dave S]If you have the original class you have the “lite” version
if later you simply add the module to your project you have the “Pro” version…[/quote]
As Paul said: Extension methods are exactly for that.

Sorry… I am missing something… to me EXTENDS adds something to a class… sure
but if the “pro” module extends the class… the original class still fails if the module isn’t there to provide the extension

If the class has

x=class.newstuff  // newstuff is an Extension of classs

then newstuff MUST be there … the idea is that it ISN’T there until the “pro” module is added

so either my question is misunderstood, or I am misunderstanding the attempts to anwer it

three projects with external items.
one lite project, one pro project, one main project

all the items of the main project are external
the pro and lite retain all the main project
the pro and lite have local versions of the classes

if something is common to the pro and lite, then you write it in the main project (and it gets updated in the others by the externals)
if something is pro you write it only in the pro project

you compile and sell the pro and the lite project.

No… No… No…
I am NOT selling a project… I am selling the CLASS
If someone buys just the CLASS they get features A,B and C
if they buy the Module as well the CLASS now has features D,E and F

you make all the properties and lite method in the class
then you make “extends” to the class methods in a separate module ?

Some clarification, please.

LiteClass has LiteMethod1 and LiteMethod2. Pro will add (somehow) ProMethod1. A user obtains only the LiteClass and writes code like this:

dim c as new LiteClass
c.ProMethod1

What should happen? Should it fail to compile, or compile and 1) do nothing, 2) raise an exception, 3) show a warning, or 4) something else?

  1. do nothing

Here is EXACTLY what I want to do.
as you all know I am in the final testing stages of gPDF (finally), and so far it does everything I had planned for it to do… including working in console apps. Due to the fact that most Xojo graphics usage are linear (draw line, then some text, then a circle etc), but a PDF file is NOT (ie. it needs to know all the relationships up front). my class creates an internal script of the actions to perform, then rearranges it to properly create the PDF.

What I want to do i add some more functions to this class, whereas it would be able to create Acroforms (listbox, checkbox, etc), THIS would be the stuff in the “pro” module.

So if the developer had JUST gPDF, they could write Xojo code telling it to insert these action fields, but when the compiled app they created was executed, and gPDF ran across one of those commands, it would skip it, because the required method to process it was not available.

But if they simply ADDED the “pro” module, and recompiled, the results would be all features.

gPDF (example of something that I might put in the class code)

#IF <pro_module_is_available>
   IF command="TextBox" then processTextBoxCommand
#ELSE
   continue
#ENDIF

So one the suite of new “commands” is determined, I can alter gPDF ONE time, but make the actual feature dependent on if the “pro” module is part of the project or not.

No keys, no passcodes, just drop the pro-module into your project

I still recommend my superclass/subclass idea. You only need placeholders in the “Lite” superclass.

Or ship gPDFLite with placeholders, then give them gPDFPro that overrides the proper methods. They would have to find/replace gPDFLite with gPDFPro, but that should be a simple change for the users.

Maybe someone has another idea, but I’m just not seeing it.

if you sell the class is it encrypted or full source ?

if the inexpensive one is encrypted then you just have a single class and the encrypted one has a constant “Pro” that is false and turns off pro features

the Pro one would, I assume, be full source code and has that constant set to true

nice thing about it being a constant is that its folded to a literal at compile time so it not modifiable via introspection

The plan was to make it available both ways…
another way I thought of … kinda kludgy… but it would work

Lite Version

  • class
  • module (key … contains ONE line const PRO_CODE=FALSE)

Pro Version

  • Add the Pro Module
  • replace the KEY module … const PRO_CODE=true

If they change the key from FALSE to TRUE without the Pro Module, it will compile fail

You wouldn’t need the “Lite” module at all with that scheme, right? Just put the constant into the class.

Ok… somebody tell me if there are any pitfalls or unseen overhead that I’m not seeing here

Add to the ORIGINAL CLASS this method

SUB executeNewSTuff(parameters as string)
   TRY
       gPDF_Forms.executeNewStuff(parameters)
  END TRY
END SUB

If the Forms Module is included it will have the SAME named function (not that the name is important at this point)
If the Forms Module is NOT included, then the TRY fails, and the class continues on its merry way

That won’t compile. Try blocks catch runtime errors, but referencing a module that doesn’t exist is a compiler error.

Replace it with:

#if kProVersion then
  gPDF_Form.executeNewStuff(parameters)
#endif

And it will work just fine. The user will just have to flip the value of kProVersion after installing the module.