jashkenas/coffee-script — pull request #2872 by epidemian (2013-03-21 07:55:39+00:00)
Title: Fix #2489 again: preserve bound methods length property

So, here's another attempt at fixing #2489. This one has a more straightforward output, it's basically the old `__bind` but inlined.

Sample input:

```coffeescript
class Foo
method: (a, b) => one

'bar:baz': (bar) => two

'--more crazy methods--': (lol) => tres
```

Old bare output:

```javascript
var Foo,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

Foo = (function() {
function Foo() {
this['--more crazy methods--'] = __bind(this['--more crazy methods--'], this);
this['bar:baz'] = __bind(this['bar:baz'], this);
this.method = __bind(this.method, this);
}

Foo.prototype.method = function(a, b) {
return one;
};

Foo.prototype['bar:baz'] = function(bar) {
return two;
};

Foo.prototype['--more crazy methods--'] = function(lol) {
return tres;
};

return Foo;

})();
```

This PR's output:

```javascript
var Foo;

Foo = (function() {
function Foo() {
var _bound, _bound1, _method,
_this = this;
_method = this.method;
this.method = function(a, b) {
return _method.apply(_this, arguments);
};
_bound = this['bar:baz'];
this['bar:baz'] = function(bar) {
return _bound.apply(_this, arguments);
};
_bound1 = this['--more crazy methods--'];
this['--more crazy methods--'] = function(lol) {
return _bound1.apply(_this, arguments);
};
}

Foo.prototype.method = function(a, b) {
return one;
};

Foo.prototype['bar:baz'] = function(bar) {
return two;
};

Foo.prototype['--more crazy methods--'] = function(lol) {
return tres;
};

return Foo;

})();
```

As you can see, the parameter names and number is preserved in the bound version of the method, thus making `length` work as expected.

Now, this PR works, but the code is _very bad_ :poop:. Or at least it contains a couple of really ugly hacks that i'm not proud of having produced. When i started with this i though that it would be just a matter of reverting this commit 67de35ff2959038018a71a917a24ad1a853d97e0 and then changing the `Class#addBoundFunctions` method a bit to make the compiled output match what i wanted. But things got pretty hairy pretty quick. Scoping issues, mutable state in destructuring parameters that prevented them from being used in more than one function (BTW, as of now, this produces some unnecessary code for bound methods with destructuring parameters), etc.

So, it's not production ready, but i wanted to open the PR to see if it would be a reasonable change or not. I personally wouldn't mind this being included or not, as i don't have much sympathy for bound methods.