0

I'm using the 'binary-parser' NPM module in node.js and am trying to use my own 'assert' function instead of supplying it inline. I don't know if the problem is that of 'binary-parser' or is that of my ignorance of calling functions and/or function references in javascript.

Here's the code that works but not what I want:

var Parser = require('binary-parser').Parser;

var data = new Buffer([0x23, 0x36, 0x74, 0x0e, 0x01, 0xff, 0xff]);

function range (min, val, max) {
    return (min <= val && val <= max);
}
var dataParser = new Parser()
.endianess('little')
.uint8('inside_humidity', {assert: function(x){return(x <= 100);}})
.uint16('barometer', {assert: function(x){return(20000 <= x && x <= 32500);},
     formatter: function(x) {return x/1000;}})
.uint16('wind_direction', {assert: function(x){return(x <= 360);}})
.uint16('crc');

console.log(dataParser.parse(data));

I'd like to call my own 'range' function like this:

    .uint16('barometer',
        {assert: range(20000, x, 32500),
     formatter: function(x) {return x/1000;}})

But I get:

ReferenceError: x is not defined

So I tried:

assert: function(x){range(20000, x, 325000)}

and

{assert: function(x){range.bind(this, 20000, x, 32500)},

and get:

ReferenceError: range is not defined

Is it possible to do what I want?

kevdev
  • 177
  • 2
  • 12
  • 1
    Maybe http://stackoverflow.com/questions/12930272/javascript-closures-vs-anonymous-functions is an interesting and helpful read? – Dilettant Jun 02 '16 at 17:06
  • 1
    Thank you and I found this to be even more helpful (at least to me): http://stackoverflow.com/questions/111102/how-do-javascript-closures-work – kevdev Jun 02 '16 at 18:06

2 Answers2

2

You will want to use a closure:

function range(min, max) {
    return function(x) {
        return min <= val && val <= max;
    };
}

With that you can write

…
.uint8('inside_humidity', {assert: range(-Infinity, 100)})
.uint16('barometer', {assert: range(20000, 32500), formatter: function(x) {return x/1000;}})
.uint16('wind_direction', {assert: range(-Infinity, 360)})
…
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • That comes back 'min is not defined'. It recognizes 'min' and 'max' outside of 'function(x)' but not inside of it. I tried: `function range (someMin, someMax) { var min = someMin; var max = someMax; return function(x) { return min <= x && x <= max; }; }` and it still did not recognize 'min' inside function(x). – kevdev Jun 02 '16 at 18:02
  • 2
    Oh my, what a horrible library. It [stringifies the function](https://github.com/keichi/binary-parser/blob/master/lib/binary_parser.js#L316) which makes closures impossible. You should file a bug. – Bergi Jun 02 '16 at 18:11
  • 1
    @kevdev: As a workaround, `function range(min, max) { return new Function("x", "return "+JSON.stringify(min)+" <= x && x <= "+JSON.stringify(max)+";"); }` should do it. – Bergi Jun 02 '16 at 18:15
  • Wow, I never would've come up with that but it works. Thanks! – kevdev Jun 02 '16 at 19:38
0

Did you try:

.uint16('barometer', {assert: function(x){return range(20000, x, 32500);},

HTH

Dilettant
  • 3,267
  • 3
  • 29
  • 29