Skip to content

Lambada Overloading Syntax

Till Wehowski edited this page Apr 21, 2015 · 18 revisions

"Lamb@da Overloading Syntax"

Introduction (WTF)

The class frdl\webfan\App supports the following construct:

` <?php

   frdl\webfan\App::God()

   ->{'$'}('MyMethodIdentifier', (function($arg){
                    $a = func_get_args(); echo $a[0];
       }) )

   -> {'MyMethodIdentifier'}('Hello world')

   ->{'$'}('-i!', array( new \ExampleNamespace\ExampleClass(),'run'))

   ->{'-i!'}() 

`

See /Tests/Hello.World-Special.Syntax.ability.php

Conventions

Shortcuts

'$' is a pre-defined shortcut , defined in the App Class constructor by the the method ->addShortCut(). The addShortCut method adds a callback to the overloading function mapping of the App class. It expects two parameters: The method fn and a callable. Callable could be e.g. a closure or a callable (array or string syntax). In the above example MyMethodIdentifier "is bound by" a closure while the use of the stupid method identifier -i! will call new \ExampleNamespace\ExampleClass() -> run() .

Amazing, isn't it? It works, because we can use ->{'any?S!ring<=>-||-'} curly brace to __call overloading methods while using invalid method identifiers. This enables php scripts to work with other or own syntax stylers.

Method j - Singleton getter

Overloaded callables of frdl\webfan\App will return $this or self::God() to prepare for Lambada syntax style. The (at this point of development) most important class, the autoloader frdl\webfan\Autoloading\SourceLoader provides the method "j" returning \webfan\App::God(), where \webfan\App is an alias for \frdl\webfan\App. Each class of this shamework SHOULD provide the method "j". This method MUST return the singletone instance of \webfan\App.

**Note: ** "Mapped functions" (added by ->addFunc($name, \Closure $func) ) are called when overloading too, BUT they return NOT the App singletone instance but the return values returned by the assigned function as excpected.

Avoid rough-handling the overloading system, better refer to another classes callable than to extend the App class itself. Use the class aliasing mapping with care! It is meant to provide a little plugin mechanism:

  • Alias names SHOULD be defined by the core and not implementation code!
  • The plugged real existing class SHOULD implement an certain feature interface or extend a certain abstract or wrapping class.

God

\webfan\App::God returns the App classes singletone instance and remembers that God classes are considered as antipattern in most (or all?) cases. In our case God just refers to a method (getInstance), and the App class MUST NOT be used as a God class, but it SHOULD be the application wide accessible singletone class to access, refer to, map and use all the significant classes used during the application flow and make them accessible in any/every scope of the application. All in all it could be called a Plugin-Interface/Mapping-Manager/Reference-Connector, or something like that... . It also works as a stream-wrappers mapping controller, but this another topic...

Use case / example

Someone could find this questionable or cannot see a benefit. Indeed, one COULD say this was developed as for its own sake, here are some pro-arguments:

`

 namespace frdl\webfan;

    class jQuery extends App{
           public function __call($name, $arguments){
	             if($name !== '$' && substr($name,0,1) === '$'){
                       //... insert jQuery interpreters/parsing flows...
                  }
           }
       }

         jQuery::God()->{'$("#body").load("myFile.html").'}($arguments);

`

Pre-defined and custom syntax

As you can see in frdl\webfan\App::_fnCallback there is a pre-defined method-name parser:

  • "." - Dot is interpreted as namespace separator ""
  • The first occurrence of "->" will split the methodname into class->method and return the corresponding callable array [ array($class,$method) ].
  • The first occurrence of "::" will split the methodname into class::method and return the corresponding callable string to call an (overloaded) static method [ "class::method" ]