Hi,
On the face of it, I like the thought of skipping the arguments prep
in the no-args case, but have you done any profiling to be sure that
it really has a measurable benefit? Same question on inlining the per-
call arguments concatenation... Without a solid, measurable benefit,
I'd avoid the additional complexity. You can deal with the debugger
thing like this:
Replace Prototype's original:
return __method.apply(object, args.concat($A(arguments)));
with:
var newargs = args.concat($A(arguments));
return __method.apply(object, newargs);
Re: unbind. That version repeatedly unbinds until it finds a non-
bound function, which means it's not the reciprocal of bind. E.g.:
x = foo.bind(obj, 1);
y = x.bind(obj, 2);
y.unbind() === x ?
// -> false, the unbind returns foo, not x
>From the name, I'd expect unbind to be the reciprocal of bind. Since
it's mostly a debug function, it may be worth just using a different
name.
FWIW,
--
T.J. Crowder
tj / crowder software / com
Independent Software Engineer, consulting services available
On Mar 10, 4:41 pm, Robert Kieffer <[email protected]> wrote:
> As I suspect is common with many Prototype shops, over here at
> Zenbe.com, we're making HEAVY use of Function#bind(). We've been
> using a custom version of the bind() method for a while now, and I've
> recently added a couple enhancements that I'd like to get people's
> opinions on - especially that of the Prototype team.
>
> I've attached a commented version of our implementation below (we run
> this after importing the Prototype library, so it just overwrites the
> Prototype code). The motivation for this implementation is as
> follows:
>
> - bind() is so ubiquitous for us that performance is a top priority.
> We're willing to have a bit more code here to make things run faster.
> In particular, 99% of our use of bind() is simply to bind a function
> to an object, without binding any arguments (e.g. "...bind
> (someObject)"). So special-casing that situation makes sense.
>
> - Stepping through bound functions is painful because you constantly
> have to step-into/out-of the $A method. It's possible to improve
> performance *and* make stepping through code easier by inlining the
> code that sets up the args array.
>
> - Inspecting functions created by bind() (e.g. "someFunction.toString
> ()") is never helpful. Provide a way to "unbind" a function to get at
> the original method.
>
> Aside from the obvious increase in code size (which isn't *that* much
> when the code is compacted - adds ~100-150 bytes), are there any
> disadvantages/weaknesses to this implementation? Would it make sense
> to migrate some or all of these changes into the Prototype codebase?
>
> =======================
> Object.extend(Function.prototype, {
> bind: function(object) {
> var __method = this, __f;
> // Special case: No args or object being bound - just return
> this function
> if (arguments.length < 2 && arguments[0] === undefined) return
> this;
>
> if (arguments.length == 1) {
> // Special case: No args are being bound - don't bother
> creating a new
> // args structure
> __f = function() {
> return __method.apply(object, arguments);
> };
> } else {
> // General case: Basically do what the native Prototype
> implementation
> // does, but be as as efficient as possible, and make it
> trivial to
> // step through in a debugger.
> var args = $A(arguments), l = args.length-1;
> args.shift();
> __f = function() {
> // Set up the args array. Note that we recycle the args
> array,
> // rather than creating a new one. Also do all this on ONE
> line so
> // it only takes one click to step over in a debugger.
> var ll = arguments.length; args.length = l + ll; while
> (ll--) args[l+ll] = arguments[ll];
> return __method.apply(object, args);
> };
> }
>
> // Finally, keep a reference to the original function so we can
> // unbind() (below) as needed.
> __f._boundFunction = this;
> return __f;
> },
>
> unbind: function() {
> var orig = this;
> while (orig._boundFunction) orig = orig._boundFunction;
> return orig;
> }
> });
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Prototype & script.aculo.us" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~----------~----~----~----~------~----~------~--~---