Created
August 15, 2014 10:10
-
-
Save gatlin/f1f00518d84c0370f2bd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*** | |
* 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