B4J Tutorial [BANano] Exploring BANanoObject.GetFunction & Execute

Discussion in 'B4J Tutorials' started by Mashiane, Nov 6, 2019.

  1. Mashiane

    Mashiane Expert Licensed User

    Ola

    The newest version of BANano comes with a lot of enhancements and some very interesting stuff. There's so much to learn.

    So I decided to check one interesting thing out, Getting / Executing a function.

    What does this really mean, I thought.

    Let's make a simple assumption based on a javascript Object.

    Code:
    var cody = new Object(); 
    cody.living = 
    true
    cody.age = 
    33
    cody.gender = 
    'male'; 
    cody.getGender = function () { return cody.gender; }; 
    console.log(cody.getGender()); // Logs 'male'.
    To try and demonstrate this, we will NOT use a map but an actual object and initialize it. For this I have created a JSObject class in my code. This JSObject class tries and replicates the simple example to create the above object.

    1. var cody = new Object();

    Code:
    obj.Initialize2("Object"Null)
    2. cody.living = true; We will use the .setField for this

    Code:
    obj.SetField(k, v)
    and later..

    3. cody.getGender = function () { return cody.gender; };

    We need to create a callback function for this. We will do this in our module and use a global variable.

    We have created a shortcut for this in our JSObject class.

    Code:
    obj.setCallBack("getGender", Me, "getGender"Null)
    Lets define a method to assign a callback to an object property.

    Code:
    Sub getGender As String
        
    Return obj.get("gender")
    End Sub
    The property is getGender and the function to call should return the "gender" property of the object.

    This .setCallBack method has been defined as..

    Code:
    'set a callback
    Sub setCallBack(k As String, module As Object, methodname As String, params As List)
        
    Dim cb As BANanoObject = BANano.CallBack(module, methodname, params)
        obj.SetField(k, cb)
    End Sub
    We pass it the module, method name and the params it needs.

    To be able to run out "getGender" property, we need a way to have the function/callback execute from the object itself. For that we have created a method in our JSObject class to call.

    Code:
    Log(obj.getCallBack("getGender"))
    As our method is not passed any variables, we just define and call it with null. What getCallBack does is to read the property we previsouly defined. i.e. getGender => callback and then executes it.

    Code:
    'get callback
    Sub getCallBack(k As StringAs BANanoObject
        
    Dim cb As BANanoObject = obj.GetFunction(k)
        
    Return cb.Execute(Null)
    End Sub
    We can extend this to have it accept params and pass them to .Execute. Because the "getGender" method returns something, thats why I have returned cb.Execute.

    I'm also getting my head around this, however I hope it provides some green lights into the methodology.

    #You are welcome to add/improve/correct anything on the thread.

    #TheUsualExperimentor

    PS: The complete code

    Code:
    'Static code module
    Sub Process_Globals
        
    Private BANano As BANano  'ignore
        Private obj As JSObject
    End Sub


    Sub Init
        obj.Initialize
        obj.set(
    "living"True)
        obj.set(
    "age"33)
        obj.set(
    "gender""male")
        obj.setCallBack(
    "getGender", Me, "getGender"Null)
        
        
    Log(obj.It)
        
    Log(obj.ToJSON)
        
    Log(obj.getCallBack("getGender"))
    End Sub


    Sub getGender As String
        
    Return obj.get("gender")
    End Sub
    Results of the logs

    getexecute.png
     

    Attached Files:

    joulongleu and alwaysbusy like this.
  2. alwaysbusy

    alwaysbusy Expert Licensed User

    This is a good example of the use of GetFunction and Execute, however i would've solved it differently so it is easier to 'use' the object and a bit more B4J like IMO. GetFunction is not really needed here (execute runs on a BANanoObject), but it can make your code a bit more readable so that is fine.

    A class Human:
    Code:
    Sub Class_Globals
       
    Private BANano As BANano 'ignore
       Public Living As Boolean
       
    Public Age As Int
       
    Public Gender As String
       
    Public GenderCallback As BANanoObject
    End Sub

    'Initializes the object. You can add parameters to this method if needed.
    Public Sub Initialize
      
    End Sub

    Public Sub GetGender() As String
       
    Return GenderCallback.Execute(Array(Me)).Result
    End Sub

    public Sub ToJson() As Object
       
    Return BANano.ToJson(CreateMap("living": Living, "age" : Age, "gender" : Gender))
    End Sub
    Usage (very similar to the javascript sample) and an example of 'why' one would use such a system:
    Code:
    Sub init
       
    Dim cody As Human
       cody.Initialize
       cody.Living = 
    True ' <--- normal properties
       cody.Age = 33
       cody.Gender = 
    "male"
       cody.GenderCallback = BANano.CallBack(Me, 
    "getGender"Array(cody))  
       
    Log(cody.ToJson)
       
    Log(cody.GetGender)
      
       
    ' lets change the callback and re-run the same GetGender method
       cody.GenderCallback = BANano.CallBack(Me, "getGenderUpperCase"Array(cody))  
       
    Log(cody.GetGender)
    End Sub

    ' a first callback
    Sub getGender(who As Human) As String 'ignore
       Return who.Gender
    End Sub

    ' a second callback
    Sub getGenderUpperCase(who As Human) As String 'ignore
       Return who.Gender.ToUpperCase
    End Sub
    So adding such a CallBack property allows you to Execute different functions, while still making the same call.

    Result:
    Code:
    {"living":true,"age":33,"gender":"male"}
    male
    MALE
    Alwaysbusy
     
    Last edited: Nov 6, 2019
    Mashiane and joulongleu like this.
  3. Mashiane

    Mashiane Expert Licensed User

    ;)

    Looks nice...

    I need to wrap my head around this.

    Code:
    Public Sub GetGender() As String
       
    Return GenderCallback.Execute(Array(Me)).Result
    End Sub
    Secondly, in most of javascript libs, one initializes them with an object {} that will have properties and property functions as per example.

    So instead of

    Code:
    var xxx = new Lib({'name':'BANano', 'getGender': function(){...}})
    can one use?

    Code:
    dim className as clsClass
    className.Initialize
    className.name = 
    "BANano4"
    className.TheCallBack = ...

    Dim xxx as bananoobject
    xx.Initialize2(
    "Lib"array(className))
    Where the className will point to the class we have created with those properties and property functions? So instead of passing an object we pass the class we have defined with properties and its own callback functions?

    #Just Thinking Aloud
     
    Last edited: Nov 7, 2019
  4. alwaysbusy

    alwaysbusy Expert Licensed User

    If you are the one who has written the lib in BANano I believe you can, but not an external one. This is because in your clsClass, the names of the properties will be altered:

    name -> _name
    TheCallBack -> _thecallback
     
    Mashiane and Johan Hormaza like this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice