From c43de549bacd3f6def734317656ddae7fa52c4cf Mon Sep 17 00:00:00 2001 From: Mike Frawley Date: Wed, 17 Feb 2010 09:41:18 -0600 Subject: [PATCH] Create #alias method, callable on any object, _ by default. While I'm not a fan of making abstractions where a simpe solution exists, I think this is good as it makes a public API for extending underscore, therefore making it "ok" to make your own alias names. Also give us some future proofing in case we ever add in hooks on method definition. For example, right now if you add a method or make an alias in user code, it isn't added to the wrapper prototype. Added tests and inline docs, no external docs --- test/objects.js | 17 ++++++++++++++++- underscore.js | 43 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/test/objects.js b/test/objects.js index c1c4aa327..8743eaed8 100644 --- a/test/objects.js +++ b/test/objects.js @@ -11,7 +11,7 @@ $(document).ready(function() { }); test("objects: functions", function() { - var expected = ["all", "any", "bind", "bindAll", "breakLoop", "clone", "compact", + var expected = ["alias", "all", "any", "bind", "bindAll", "breakLoop", "clone", "compact", "compose","defer", "delay", "detect", "each", "every", "extend", "filter", "first", "flatten", "foldl", "foldr", "forEach", "functions", "head", "identity", "include", "indexOf", "inject", "intersect", "invoke", "isArguments", "isArray", "isDate", "isElement", "isEmpty", "isEqual", @@ -183,4 +183,19 @@ $(document).ready(function() { value(); ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain'); }); + + + test("objects: alias", function() { + _.alias('isEqual', 'isTheSame'); + ok(_.isTheSame(9, 9), 'by default aliases methods on underscore'); + delete _.isTheSame; + // + var o = { hi: function () {return 9;} }; + _.alias(o, 'hi', 'ho'); + equals(o.ho(), 9, 'can add an alias on another object'); + _.alias(o, 'hi', 'there', 'sir'); + ok(o.hi==o.sir, 'can add multiple aliases'); + }); + + }); diff --git a/underscore.js b/underscore.js index ac694195e..538019fc8 100644 --- a/underscore.js +++ b/underscore.js @@ -440,6 +440,31 @@ return obj; }; + // Alias a method on an object to another name(s). + // If the first argument is NOT an object, then the object is assumed to + // be underscore. + // The first string argument is the existing method name, any following + // strings will be aliased to that name. + // Returns the object for chainability. + // + // Examples: + // + // Alias isEquals to isSame and eql on underscore: + // _.alias('isEqual', 'isSame', 'eql'); + // + // Alias `toString` to `to_s` on a given object: + // _.alias({}, 'toString', 'to_s') + // + // Implementation: explicitly cast arguments to array as calling mutating + // array methods on arguments object has strange behavior (at least in FF 3.6) + _.alias = function () { + var args = _.toArray(arguments), + obj = (typeof args[0] === 'string')? _ : args.shift(), + fn = obj[args.shift()]; + each(args, function (alias) { obj[alias] = fn; }); + return obj; + }; + // Perform a deep comparison to check if two objects are equal. _.isEqual = function(a, b) { // Check object identity. @@ -593,15 +618,15 @@ // ------------------------------- Aliases ---------------------------------- - _.each = _.forEach; - _.foldl = _.inject = _.reduce; - _.foldr = _.reduceRight; - _.select = _.filter; - _.all = _.every; - _.any = _.some; - _.head = _.first; - _.tail = _.rest; - _.methods = _.functions; + _.alias('forEach', 'each'). + alias('reduce', 'foldl', 'inject'). + alias('reduceRight', 'foldr'). + alias('filter', 'select'). + alias('every', 'all'). + alias('some', 'any'). + alias('first', 'head'). + alias('rest', 'tail'). + alias('functions', 'methods'); // ------------------------ Setup the OOP Wrapper: --------------------------