Normally, when writing classes, especially ones that are meant to be used as lib, there are cases that you would need to define so-called "private" methods which act as helper subroutines for some of the public methods exposed by the API. Commonly, to imply that these method(s) are for internal use only, the dev would usually use naming conventions(underscore prefix, etc.), "warning" comments and omit the usage of these methods from the documentation. These usually are enough but just for fun, I will be demonstrating a way to define so-called "private" methods and/or properties in a manner that it would be easy for the dev to maintain/organize the code and most importantly encapsulate the subroutines from the caller(be it a person or object(instance/class)). You may have noticed in the documentation under function objects(not to be confused with Func objects) -- (I can't provide a link, it seems that the online doc is temporarily unavailable), a way to define custom callable objects. This method has always been available prior
v1.1.20, however, with the introduction of
Func.Call(), we can say that there is now a more standardized way of defining custom "function objects". The trick is to convert the "public" methods which use/call the "private" methods into nested classes, implement these nested classes as callable objects by putting its routine in the
.Call()method and then define the "private" helper methods as methods of these nested callable classes. But before you do this you would first need to define a base object from which all your "callable" objects will derive from. The base object should be defined as follows(similar to the one in the AHK documentation):
You can put this as a nested class of your class if you plan to use it for the that class only.
Now that we have the base object, we can define our "public" and "private" method as follows:
class Public extends Foo.Callable
; instance.Public(args*) invokes .Call()
Call(self, args*) ; instance is passed as second argument(self), 'this' is actually Foo.Public class
; main routine of Foo.Public() goes here
this.Private(self, args*) ; call a private subroutine, pass instance('self') if needed/required
Private(self, args*) ; private method callable only from within Foo.Public()
; you may omit 'self' if you don't need the reference
class Callable ; base object for all callable objects
if IsObject(method) || (method == "")
return method ? this.Call(method, args*) : this.Call(args*)
- If multiple "public" methods need to call the same "private" method, you can have them extend from the nested class which contains the "private" method.
- If you plan to use this for
__Newmake sure that
Pros of using this approach:
- Code is easy to read, maintain and document as you can see which helper subroutine(s) a particular method uses.
- Class instance(s) have no direct way of calling the "private" methods avoiding possible invalid calls that may compromise the script
In normal cases, there is no need to use this convention, however, it comes really handy with large and complex classes.