KBOS methods

After scopes, types and signatures we got all the prerequisites to talk about the syntax and semantics of KBOS methods. Unless you want to contribute to Kephra or write a plugin, you may never use them, but please join me in the thought experiment - maybe we get a littler smarter.

General Rules of Syntax

KBOS is outspokenly declerative. The keyword class starts a class, attribute an attribute definition and you could even guess what method name (...) {....} stands for. In front of method may appear several combinable keywords. Lets call them method modifier for now, because Raku has them too. If one of them is present, writing method is optional.

Method modifier signal the presence of an additional mechanism, that is often related to the architectural purpose of the method. So you know what is going on and you got help in navigating the sources.

MMD

multi work almost like in Raku. It enables to write several methods with the same name, but different signatures. KBOS simpy tries them out in the order they appear in the sources. If the current arguments match one signature (see last part) this one will be called and the next ones get ignored. Unlike Raku there are no multi subs. And unlike Raku not all multi methods have to be in same scope. For instance, some of them may be public and some of them may be private. That means in private scope all of them are present, but outside the scope of the class only the public ones are considered.

Public Privacy

The modifier public and private are self explanatory. Public is default and may be omitted. Inside of every public or private method do exist two special variables: $self and $arg, that also do, what they are sound like. $self is a ref to the current object (in private scope - ClassName::PRIVATE) and $arg is a ref to an ClassName::ARGUMENT::MethodName object. That has methods, named after the arguments of the method, as defined by the signature. (which has to give a name to each arg). This way you have a very declarative readonly access to the arguments ($arg->date). And you can rely on the arguments data type, because the method would not be started if the type checks spew an error. If you need to react on malformed data, just write a multi method with a very lenient signature.

In some rare cases the names $self and $arg lead to conflicts or you may have your very own preferential naming scheme. Than you can pull $self and $arg also out of @_ since they also stored under $_[0] and $_[1].

Accessors

Simple accessors are autogenerated. Just tell name and scope inside the attribute definition (more details in next episode). If you omit the name, the accessor will be named after the attribute. Name collisions will cause a hard BEGIN time error (like any perl syntax mistake) and its also possible to get a combined getter/setter.

For more complicated cases, use the method modifier getter and setter which do from a technical point the same thing. Choose the right alternative to beautify the sources. (If you write private getter, you will get what you see.) But you have to use one of them to get special access to one attribute. Which attribute that is, springs from the definition of that attribute, where this method has to be mentioned. So please choose a method name, that strongly hints, which attribute is associated.

As always, $self and $arg are present inside the method, or can be pulled out of @_ as well as $attribute aka $_[2]. The ladder will have the methods get, set and reset (to the attribute types default value). Since this method is an accessor, it will have a $self in ACCESS scope. So not only public and private methods can be called but also the special acessore that are invisible to the public and private methods. That is what I call the interface to the inner layer of the class (the attributes). To create a method in ACCESS scope but acess in front of getter/setter or define the appropriate scope for the auto generated.

Since attributes can be objects themself, you may want to foreward a method call to an attribute. This is done by a delegator method, which also can be auto generated or hand crafted, like a getter or setter. A special kind of delegators are wrapper (a concpet straight out of Raku). They are for attributes that are not KBOS objects, but created within vanillar perl, Moo, etc.

BUILD Scope Methods

When you create or demolish an object, you just need acess to all attributes. That is why KBOS has the BUILD scope, where all accessors are visible, even the ones that are restricted to just BUILD scope. Other than that, most of the previous rules apply. You can auto generate a constructor a deconstructor or write them by hand using the modifier constructor and deconstructor. Inside of them, $self, $arg and $attribute (by name or in @_) can be found. Only this time $attribute has a setter method for each attribute in the constructor and a getter in the deconstructor. Because from the first line on, inside the constructer, the new object is already created (all attributes have the default value of their types), there is no need for bless or a BUILD method. And you can have as many constructors and deconstructors as you heart desires. Just be aware that the names state and restate are already taken. state dumps the complete internal state of an object (like .perl does in Raku), which I wanted not only for debugging purposes. You also could take the dump and feed it to the constructor restate and you will get a perfect clone of the object. This is needed to serialize the complete state of the app (for next start, remote session or moving an object into another running instance of the app). If you just wanted to clone an object, use ->clone, because KBOS auto generates that too.

Thats it for today. I think there will be only 2 more parts: attributes and overall usage.

Leave a comment

About lichtkind

user-pic Kephra, Articles, Books, Perl, Programming