A
A
Andrey Kuntsevich2013-07-25 21:03:44
JavaScript
Andrey Kuntsevich, 2013-07-25 21:03:44

How to implement multilevel nested function launch?

I'm afraid that the title is fundamentally wrong is not entirely clear.
There are two classes of objects:

  • record - a record containing a name and a value.
    js and screenshot from chrome devconsole
    var record = function() {
        var name;
        this.name = name;
        var value;
        this.value = value;
    }
    731ae871e917220e30c9de5aca4e6f6b.png
  • group is a list containing the name, status, and an array of entries.
    js and screenshot from chrome devconsole
    var group = function() {
        var _name;
        this.name = _name;
        var _status
        this.status = _status;
        var _stack = [];
        this.stack = _stack;
    }
    72029f916619519238c5c65c676d9dc2.png

Some groups may contain more groups, with no restrictions on the nesting level.
There is also a root element root - which is a zero-level group.
You need to implement 2 functions:
  • makeRecord - creates a record object of the class and puts it on the stack of the current nesting level.
    js
    var makeRecord = function(name,value) {
        var newrecord = new record();
        newrecord.name=name;
        newrecord.value=value;
        root.stack.push(newrecord);
    }

  • makeGroup is a group that creates an object of the class, pushes it onto the stack of the current level, and runs inside the function passed to it, inside which both new calls to makeRecord and makeGroup can be located. The most important thing is that she should pass them a link (?) to her own stack
    js
    var makeGroup = function(name,fun) {
        var newgroup = new group();
        newgroup.name=name;
        var stack=[];
        try{fun();} catch(e) {
            newgroup.status=e;
        }
        newgroup.status='ok';
        newgroup.stack=stack;
        root.stack.push(newgroup);
    }


It's the last one I'm having trouble with.
From this code:
makeRecord('first record','some text');
makeGroup('first group');
makeRecord('second record','yet another text');
makeGroup('second group',function(){
    makeRecord('first record in second group','how can i do it?');
});

The current implementation gives the following result:
{
    "name": "root",
    "status": "ok",
    "stack": [
        {
            "name": "first record",
            "value": "some text"
        },
        {
            "name": "first group",
            "status": "ok",
            "stack": []
        },
        {
            "name": "second record",
            "value": "yet another text"
        },
        {
            "name": "first record in second group",
            "value": "how can i do it?"
        },
        {
            "name": "second group",
            "status": "ok",
            "stack": []
        }
    ]
}
screenshot from chrome devconsole362a50d64635935dd854305e18dc7f4c.png
And I want to get this:
{
    "name": "root",
    "status": "ok",
    "stack": [
        {
            "name": "first record",
            "value": "some text"
        },
        {
            "name": "first group",
            "status": "ok",
            "stack": []
        },
        {
            "name": "second group",
            "status": "ok",
            "stack": [
                {
                    "name": "first record in second group",
                    "value": "how can i do it?"
                }
            ]
        }
    ]
}
screenshot from chrome devconsolecddde3efaf6dc431ed1e3c9e609b8efe.png
Perhaps all this can be fixed with just a couple of lines in makeGroup, or maybe I chose the wrong approach in principle. Just in case, I uploaded the code from the examples here so that you don’t have to type again.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
m-haritonov, 2013-07-25
@titulusdesiderio

To do this, before calling the fun() function in makeGroup , the value of root must be temporarily replaced by the newly created group. Here is the new code for makeGroup:

var makeGroup = function(name,fun) {
    var newgroup = new group();
    newgroup.name=name;
    newgroup.status='ok';
    newgroup.stack=[];
    
    var oldRoot = root;
    root = newgroup;
    
    try {
        fun();
    }
    catch(e) {
        newgroup.status=e;
    }
    
    root = oldRoot;
    
    root.stack.push(newgroup);
}

S
sheknitrtch, 2013-07-25
@sheknitrtch

I see the line in the source code:

root.stack.push(newrecord);

That is, the function makeRecord always adds a new entry to the root.
I would add one more argument parentGroupto
var makeRecord = function(name,value, parentGroup) {
    var newrecord = new record();
    newrecord.name=name;
    newrecord.value=value;
    if(parentGroup === undefined) {
        parentGroup = root;
    }
    parentGroup.stack.push(newrecord);
}

Correct the function in the same way makeGroup.
You can use these features like this:
makeRecord('first record','some text');
makeGroup('first group');
makeRecord('second record','yet another text');
makeGroup('second group', function(parentGroup) {
    makeRecord('first record in second group','how can i do it?', parentGroup);
});

IMHO, parsing the call stack or introducing some additional global variables is a bad option.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question