Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#2286]: Underscore could use a _.propertyResult #2531

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions test/utility.js
Expand Up @@ -95,6 +95,18 @@
assert.equal(undefPropertyOf('curly'), void 0, 'should return undefined when obj is undefined');
});

QUnit.test('method', function(assert) {
var stooge = {name: function() { return 'moe'; }, sum: function(a, b, c) { return a + b + c; }};
assert.equal(_.method('name')(stooge), 'moe', 'should return the results of calling the method with the given name');
assert.equal(_.method('sum')(stooge, 1, 2, 3), 6, 'should pass rest of arguments to named method for evaluation');
assert.equal(_.method(function() { return this.name(); })(stooge), 'moe', 'should apply a function literal passed.');
assert.equal(_.method(function(a, b, c) { return this.sum(a, b, c); })(stooge, 1, 2, 3), 6, 'should pass arguments when applying a function literal.');
assert.equal(_.method('macerena')(stooge), void 0, 'should return undefined for non-existant method name on defined object');
assert.equal(_.method('name')(null), void 0, 'should return undefined for null object');
assert.equal(_.method()(stooge), void 0, 'should return undefined for undefined method name on existing object');
assert.equal(_.method()(void 0), void 0, 'should return undefined for undefined method name on undefined object');
});

QUnit.test('random', function(assert) {
var array = _.range(1000);
var min = Math.pow(2, 31);
Expand Down
15 changes: 15 additions & 0 deletions underscore.js
Expand Up @@ -1370,6 +1370,21 @@

_.property = property;

// Generates a function for a given object that returns the passed function's return value.
// Accepts a method name or function literal for value.
// If value is a string, function assumes this string is a method name on the
// referenced object.
_.method = function(value) {
return restArgs(function(obj, args) {
if (obj == null) { return; }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this not valid when a function is provided?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method responds to both a string literal (a method name) or a function literal. This check is to sort out if the value passed is a function literal, so that later we know what to call apply on.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any rational why should func not be called if it is a function literal and obj is null?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My current rational is that this invocation pattern doesn't make much sense to me. e.g.,

_().method(function() { /* function body *. })
_.method(null, function () { /* function body */ })

since both would be more easily written as a plain function literal, and this invocation pattern reads to me as 'call the provided method on undefined'.

That said, if allowing an undefined object in this position is more in keeping with underscore's style, I'm happy to update so we can call _.method on undefined objects.

var func = _.isFunction(value) ? value : obj[value];
if (func) {
return func.apply(obj, args);
}
});
};


// Generates a function for a given object that returns a given property.
_.propertyOf = function(obj) {
return obj == null ? function(){} : function(key) {
Expand Down