pulling Evgeniy Dolzhenko's patch to add _.tap, with tests

This commit is contained in:
Jeremy Ashkenas
2009-12-11 09:25:20 -05:00
parent c17879453a
commit d49196f2e7
3 changed files with 39 additions and 2 deletions

View File

@@ -206,7 +206,7 @@ _(lyrics).chain()
<b>Objects</b>
<br />
<span class="methods"><a href="#keys">keys</a>, <a href="#values">values</a>,
<a href="#functions">functions</a>, <a href="#extend">extend</a>, <a href="#clone">clone</a>,
<a href="#functions">functions</a>, <a href="#extend">extend</a>, <a href="#clone">clone</a>, <a href="#tap">tap</a>,
<a href="#isEqual">isEqual</a>, <a href="#isEmpty">isEmpty</a>, <a href="#isElement">isElement</a>,
<a href="#isArray">isArray</a>, <a href="#isArguments">isArguments</a>, <a href="#isFunction">isFunction</a>, <a href="#isString">isString</a>,
<a href="#isNumber">isNumber</a>, <a href="#isDate">isDate</a>, <a href="#isRegExp">isRegExp</a>
@@ -766,6 +766,22 @@ _.extend({name : 'moe'}, {age : 50});
<pre>
_.clone({name : 'moe'});
=&gt; {name : 'moe'};
</pre>
<p id="tap">
<b class="header">tap</b><code>_.tap(object, interceptor)</code>
<br />
Invokes <b>interceptor</b> with the <b>object</b>, and then returns <b>object</b>.
The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.
</p>
<pre>
_([1,2,3,200]).chain().
select(function(num) { return num % 2 == 0; }).
tap(console.log).
map(function(num) { return num * num }).
value();
=&gt; [2, 200]
=&gt; [4, 40000]
</pre>
<p id="isEqual">

View File

@@ -17,7 +17,7 @@ $(document).ready(function() {
"indexOf", "inject", "intersect", "invoke", "isArguments", "isArray", "isDate", "isElement", "isEmpty", "isEqual",
"isFunction", "isNaN", "isNull", "isNumber", "isRegExp", "isString", "isUndefined", "keys", "last", "lastIndexOf", "map", "max",
"methods", "min", "noConflict", "pluck", "range", "reduce", "reduceRight", "reject", "rest", "select",
"size", "some", "sortBy", "sortedIndex", "tail", "template", "toArray", "uniq",
"size", "some", "sortBy", "sortedIndex", "tail", "tap", "template", "toArray", "uniq",
"uniqueId", "values", "without", "wrap", "zip"];
ok(_(expected).isEqual(_.methods(_)), 'provides a sorted list of functions');
var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce};
@@ -131,4 +131,18 @@ $(document).ready(function() {
ok(_.isUndefined(undefined), 'undefined is undefined');
});
test("objects: tap", function() {
var intercepted = null;
var interceptor = function(obj) { intercepted = obj; };
var returned = _.tap(1, interceptor);
equals(intercepted, 1, "passes tapped object to interceptor");
equals(returned, 1, "returns tapped object");
returned = _([1,2,3]).chain().
map(function(n){ return n * 2; }).
max().
tap(interceptor).
value();
ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain');
});
});

View File

@@ -495,6 +495,13 @@
return typeof obj == 'undefined';
};
// Invokes interceptor with the obj, and then returns obj.
// The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.
_.tap = function(obj, interceptor) {
interceptor(obj);
return obj;
}
// Define the isArray, isDate, isFunction, isNumber, isRegExp, and isString
// functions based on their toString identifiers.
var types = ['Array', 'Date', 'Function', 'Number', 'RegExp', 'String'];