Coded something up in Couch in an interesting way? Have a snippet or shortcode to share? Post it here for the community to benefit.
2 posts Page 1 of 1
(this is based on Couch Functions but deserves a new topic)

I have thought through various approaches tied together to work with objects in Couch. Posting serves as an introduction to manipulation of a JSON object (a.k.a. 'Couch Array') via a set of functions (a.k.a. 'Object Methods') that are also a part of said JSON !!

Isn't this awesome? :)

In practice it means you can save a JSON object to file (once it is created a.k.a. 'constructed') and restore its state with all attached methods and immediately work with it, without need of any external funcs or snippets.

Code that I present below has a few keywords, customary to objects and classes of objects, — this and self. These help during writing of the methods and are simple Couch variables. In fact, there are only Couch variables used in creating an object. :)

You'll also recognize anonymous functions — these are at the core of the method. Needless to say, but I will repeat this too: anonymous functions are also simple JSON objects ;) and can be dealt with the usual ways e.g. printed, saved to file and assigned to another variable. Of course, they can be called via <cms:call> — yes, anonymous functions are not used exclusively as a value of 'not_active' parameter in editable fields :lol: — and this is another gem.

Here is a class 'Computer'. It can create many identical clones of itself but we only create one object out of it, named "PC".

Code: Select all
<cms:func _into='classComputer' return_object='' ><cms:hide>
    <!-- commentaries hidden-->


    <!-- create local object "this" -->
    <cms:set this='[]' is_json='1' scope='local'/>

    <!-- remember object name: this is important to 'know' itself -->
    <cms:set this.Name = return_object />


    <!-- create one public property — "Parts" -->
    <cms:set this.Parts='[]' is_json='1' />





    <!-- Use "setter" method with property -->
    <cms:func _into='this.set' var='' value='' self=this.Name _scope='parent'>
        <cms:get self into='this' into_scope='local'/>

        <cms:put var="this.Parts.<cms:show var />" value=value scope='local'/>

        <!-- Copy back object only in setter -->
        <cms:put var=self value=this scope='parent' />
    </cms:func>




    <!-- method adds something to a property "Parts" of the main object -->
    <cms:func _into='this.insert' part='' self=this.Name _scope='parent'>
        <cms:get self into='this' />

        <cms:call this.set var='' value=part />
    </cms:func>



    <!-- Remove something from "Parts" -->
    <cms:func _into='this.remove' part='' self=this.Name _scope='parent'>


        <!-- copy object to a local var 'this' -->
        <cms:get self into='this' into_scope='local'/>


        <!-- nullify full property of the main object with dynamic name -->
        <cms:put var="<cms:show self />.Parts" value='[]' is_json='1' scope='parent'/>


        <!-- enumerate local copy, but write into main object -->
        <cms:each this.Parts>
            <cms:if item ne part>
                <cms:call this.set var='' value=item />
            </cms:if>
        </cms:each>

    </cms:func>




    <!-- method creates a view for one property -->
    <cms:func _into='this.listParts' self=this.Name _scope='parent'>
        <cms:get self into='this' />


        <cms:each this.Parts>
            <cms:if k_first_item><ol></cms:if>
            <cms:concat '<li>' item  '</li>' />
            <cms:if k_last_item></ol></cms:if>
        </cms:each>

    </cms:func>



    <!-- return "this" as object -->
    <cms:put var=return_object value=this scope='global'/>


</cms:hide>
</cms:func>



I construct one JSON object named "PC" from the 'classComputer'.

Code: Select all
<!--new object "PC" will have all methods -->
<cms:call classComputer return_object='PC'/>


My JSON object "PC" can already do a few operations. I will insert a few parts to it and print them all, then remove a part and print again.


Code: Select all
<!--new object "PC" will have all methods -->
<cms:call classComputer return_object='PC'/>

<!-- object PC is given a few parts -->
<cms:call PC.insert 'CPU' />
<cms:call PC.insert 'Memory' />
<cms:call PC.insert 'SSD' />



<!-- show all inserted parts -->
<cms:call PC.listParts /><br>


<!-- now remove one part -->
<cms:call PC.remove 'Memory' />


<!-- show all available parts -->
<cms:call PC.listParts /><br>


Result:

Screenshot-2023-03-12-124604.658.png
Screenshot-2023-03-12-124604.658.png (2.36 KiB) Viewed 6050 times



Being simple JSONs, the content of the class, func or object are available for your inspection —

Code: Select all
Parts Property: <cms:show PC.Parts as_json='1'/><br>

Complete object with all methods and properties: <cms:show PC as_json='1' /><br>


The code in methods is prepared so it covers most common scenarios while working with objects, methods and classes.

I hope this was useful.

- - -

A huge thanks to @KK for a study of his PHP Objects drives the learning forward and @mwlarkin1 for his interest in good design of 'Models' hit me and inspired looking closer to make a better model for a project I work on (sorted trees).

P.S. Take a look at the 'driving simulator' game based on the concept outlined above viewtopic.php?f=7&t=13371
Well, Anton, I can only say that I am amazed.
You are really, really pushing the envelope :)
2 posts Page 1 of 1