Aspect-oriented Programming with Entities

Warning

This is an testing feature. This documentation take precedence.

Now, you know how to define all types of entities. As Imagination is also a framework to let you do the aspect-oriented programming with ease, this section will show you how you can do that with just XML configuration files.

How can you do that?

Suppose you have the following scenarios.

Given entity "bob" orders "Pad Thai"
 Then entity "server" passes on the order to entity "chef"
  And entity "chef" cooks the order.

Given entity "chef" finishes cooking
  And entity "server" delivers the order to "bob"
 Then before entity "bob" can eat, the entity must wash hands.

Given entity "entity" makes unavailable order
 Then entity "server" apologizes

From the following scenarios, you can translate into the XML configuration.

<imagination>
    <entity id="bob" class="...">
        <!-- ... (assumed the paramaters are defined) ... -->

        <interception before="bob" do="eat" with="sanitize_hands"/>
        <!--
            bob.order()          -> str
            bob.eat(order)       -> None
            bob.sanitize_hands() -> None
        -->
    </entity>
    <entity id="server" class="...">
        <!-- ... (assumed the paramaters are defined) ... -->

        <interception after="bob" do="order" with="relay_order"/>
        <!--
            server.relay_order(order):
                chef.cook(order)
        -->

        <interception after="chef" do="cook" with="deliver"/>
        <!--
            server.deliver(order):
                bob.eat(order)
        -->

        <interception error="bob" do="error" with="apologize"/>
        <!--
            server.apology(order)
                server.say('We do not have this at the moment.', bob)
        -->
    </entity>
    <entity id="chef" class="...">
        <!-- ... (assumed the paramaters are defined) ... -->
        <!--
            chef.cook(order) -> str
        -->
    </entity>
</imagination>

At this point, when you execute assembler.core.get('bob').order(), the execution chain will be executed as specified.

No events/interceptions shall return anything.

“Before” events

From this example, to run code before executing some code, from “bob”

<interception before="bob" do="eat" with="sanitize_hands"/>

means “before bob executes eat, bob executes sanitize_hands with the parameters for executing eat”.

“After” events

Or from “server”, to run code after executing some code, from “server”,

<interception after="chef" do="cook" with="deliver"/>

means “after chef executes cook, server executes deliver with the result from executing cook as the first parameter”.

“Error” events

Or from “server”, to run code when an uncaught exception occurs while executing some code, from “server”,

<interception error="bob" do="order" with="apologize"/>

means “while bob executes order, if an error occurs, server executes apologize with the following parameters”:

  1. error: the error raised while executed the intercepted callback
  2. largs: the positional parameters used for the execution
  3. kwargs: the keyword parameters used for the execution

Tip

For more information about the DTD of the configuration file, please check out the DTD on GitHub.

Next step? What else can it do?.