Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to define my own helper functions/external globals for nools files? #26

Merged
merged 9 commits into from May 23, 2013

Conversation

paullryan
Copy link
Contributor

I want to define some helper functions, objects and/or variables that are accessible from the then of the nools compile (such as a winston logger, or a pd extension).

Is there currently a way to add these to the active scope in a .nools file? If not what area of the code would you suggest I look in to add this?

@paullryan
Copy link
Contributor Author

I'm thinking something along the lines of

    "global": function (orig, context) {
        var src = orig.replace(/^global\s*/, "");
        var name = src.match(/^([a-zA-Z_$][0-9a-zA-Z_$]*\s*)/);
        if (name) {
            src = src.replace(name[0], "").replace(/^\s*|\s*$/g, "");
            if (utils.findNextToken(src) === "=") {
                name = name[1];
                var fullbody = utils.getTokensBetween(src, "=", ";", true).join("");

                var body = fullbody.substring(1, fullbody.length - 1);
                context.scope.push({name: name, body: body});
                src = src.replace(fullbody, "");
                return src;
            }
            else{
                throw new Error("unexpected token : expected : '=' found : '" + utils.findNextToken(src) + "'");
            }
        }
        else {
            throw new Error("missing name");
        }
    },

This is currently not working when I try the following.
.nools file has:

define Counter {
    count: 0,
    constructor: function(count){
        this.count = count;
    }
}

global logger = require('winston').loggers.get('main');

rule "A rule" {
    when {
        not($ctr: Counter);
    }
    then{
        console.log(this.scope);
        console.log(this.scope.logger);
        console.log(this.scope['logger']);
    }
}

Output:

{ console: 
   { log: [Function],
     info: [Function],
     warn: [Function],
     error: [Function],
     dir: [Function],
     time: [Function],
     timeEnd: [Function],
     trace: [Function],
     assert: [Function] },
  'logger ': 
   { domain: null,
     _events: null,
     _maxListeners: 10,
     padLevels: false,
     levels: { silly: 0, verbose: 1, info: 2, warn: 3, debug: 4, error: 5 },
     silly: [Function],
     verbose: [Function],
     info: [Function],
     warn: [Function],
     debug: [Function],
     error: [Function],
     level: 'info',
     emitErrs: false,
     stripColors: false,
     exitOnError: true,
     transports: { console: [Object], file: [Object] },
     rewriters: [],
     exceptionHandlers: {},
     profilers: {},
     _names: [ 'console', 'file' ],
     _hnames: [] } }
undefined
undefined

Again thanks for the great tool and I look forward to working on and with it.

@paullryan
Copy link
Contributor Author

This should be a complete pull request now. Sorry about the confusion, I'm still new to working with github pull requests.

@doug-martin
Copy link
Contributor

Ill look at this a little closer this evening, but have you tried the scope option when compiling your rules?

nools.compile("my_nools_file.nools", {
   scope: {
      logger: require('winston').loggers.get('main')
   }
});

Anything specified in scope can also be used in the constraints as well as the action. The reason I kept requires out of the rules was for interoperability between the browser and server rule definitions (commonjs, requirejs, no dependency manager etc...)

At a cursory glance can you please remove the console.logs and add tests?

Thanks for the great feedback I really appreciate it!

-Doug

@paullryan
Copy link
Contributor Author

So as you can see from the last commit 94440d3 the console.logs have been removed. I'll work on generating better tests this evening for you. Thanks for the review. Again sorry for the confusion I think I get how git is handling this stuff now so future submits should be cleaner from me :).

… the spacing issue uncovered by the test in the body of the scope generated by the parser.
@paullryan
Copy link
Contributor Author

Ok tests added.

I understand your statements about keeping it the same for browser and node however I can see any number of pieces of code that could be written into the then portions of the rules that would break this. Globals could be written (as per the example I added to documentation) to use requires but it does not have to be used and if there is a mechanism for loading objects that the user has available from their browser code this mechanism is not limited to requires but has access to anything that the scope creation code does.

My reasoning for wanting globals is that there are a number of things including the logger and custom error code that I need access to but don't necessarily know that in the javascript but my rules know that so I'd like to keep these closer to the place they're used.

Thanks for reviewing this code.

doug-martin added a commit that referenced this pull request May 23, 2013
Is there a way to define my own helper functions/external globals for nools files?
@doug-martin doug-martin merged commit 46c01d6 into noolsjs:master May 23, 2013
@paullryan paullryan deleted the add-globals branch May 23, 2013 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants