Skip to content

Instantly share code, notes, and snippets.

@gatlin
Created August 15, 2014 10:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gatlin/f1f00518d84c0370f2bd to your computer and use it in GitHub Desktop.
Save gatlin/f1f00518d84c0370f2bd to your computer and use it in GitHub Desktop.
/***
* Fun with closures!
*
* Run this with node.js:
*
* $> node closurewanking.js
*/
var http = require('http');
/*
* Closure Example 1: simple object oriented design pattern
*/
var myObject = (function() {
var name = "gatlin";
var age = 25;
var methods = {
"getName": function() { return name },
"getAge" : function() { return age },
"setName": function(n) { name = n },
"setAge" : function(a) { age = a }
};
return function(method) {
return methods[method];
};
})();
console.log(myObject("getName")()); // "gatlin"
console.log(myObject("getAge")()); // 25
myObject("setAge")(26); //
console.log(myObject("getAge")()); // 26
/*
* Closure Example 2: streaming data, fixed amount
*/
var fakeData = [
{
"name": "Gatlin",
"nationality": "American",
},
{
"name": "Basile",
"nationality": "French"
},
{
"name": "Michael",
"nationality": "German"
}
];
// Enumerates the values of an array to a sink function
var makeArrayEnumeratorSimple = function(xs) {
var _idx = 0;
return function(fn) {
while (_idx < xs.length) {
fn(xs[_idx++]);
}
};
};
var fdEnumerator = makeArrayEnumeratorSimple(fakeData);
fdEnumerator(console.log);
/*
* Closure Example 3: Folding a stream of data with an iteratee
*/
// Enumerates the contents of an array to a sink function, signaling when it is
// finished
var makeArrayEnumerator = function(xs) {
var _idx = 0;
return function(fn) {
while (_idx < xs.length) {
fn({datum: xs[_idx++],finished: false});
}
return fn({finished: true});
};
};
// This sink maintains a running total of the numbers it has received
var summer = function() {
var total = 0;
return function(msg) {
if (msg.finished) {
return total;
}
else {
total += msg.datum;
}
};
};
// usage:
var theSum = makeArrayEnumerator([1,2,3])(summer());
console.log(theSum);
/*
* Closure Example 4: Folding an unbounded, dynamic stream of data
*/
// Enumerates chunks of an ajax response
var makeAjaxEnumerator = function(_url) {
var xs = _url.split('/');
var options = {
hostname:xs[0],
path: "/"+xs.slice(1).join('/'),
port: 80
};
return function(fn) {
http.request(options, function(res) {
res.on('data',function(chunk) {
fn({datum: chunk, finished: false});
});
res.on('end',function() {
fn({finished: true});
});
}).end();
};
};
// consumes chunks of an ajax response; in this case, we simply append the data
// to an array. It's easy to see how this could perform other analysis, or even
// transform the data and then enumerate it to another sink.
var makeSink = function() {
var xs = [];
return function (msg) {
if (msg.finished) {
console.log(xs);
}
else {
xs.push(msg.datum.toString());
}
};
};
// usage:
var txData = makeAjaxEnumerator(
"api.sba.gov/geodata/city_county_links_for_state_of/tx.json");
txData(makeSink());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment