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

Ruby-ism: include/extend #218

Closed
jnicklas opened this issue Feb 28, 2010 · 3 comments
Closed

Ruby-ism: include/extend #218

jnicklas opened this issue Feb 28, 2010 · 3 comments

Comments

@jnicklas
Copy link

Yay classes! Maybe we could have Ruby's extend/include to mix in stuff in our classes? We can make it way cooler than Ruby by allowing any Object to be mixed in!

nameMixin: { name: 'Steve' }
makeSteveMixin: { steve: -> new this() }
class Person
  include nameMixin
  extend makeSteveMixin

steve: new Person
steve.name() #=> 'Steve'
steve2: Person.steve
@tim-smart
Copy link
Contributor

Well technically they aren't 'classes', rather just a wrapper around Javascript prototypes.

One question one must ask, is how far are we wanting to take 'classes' in Coffee. We don't want to bending the underlying Javascript too much...

@jashkenas
Copy link
Owner

So, you already have this ability in JavaScript. Here's extend:

extend: (obj, mixin) ->
  for name, method of mixin
    obj[name]: method

And here's include, using extend from above:

include: (klass, mixin) ->
  extend klass.prototype, mixin

It's all just attaching functions to the proper location. I don't think that we need to formalize this pattern in CoffeeScript, as many core libraries (jQuery, Prototype, Underscore) already have this extend function, and many objects that are intended for use as mixins already have it built-in. Any many people prefer helper objects and composition over mixing methods right in to the prototype.

So, closing as a 'wontfix'.

But if you use the methods above, your example could be written like so:

nameMixin: { name: 'Steve' }
makeSteveMixin: { steve: -> new this() }
class Person

include Person, nameMixin
extend Person, makeSteveMixin

steve: new Person()
puts steve.name
steve2: Person.steve

This runs, and prints "Steve".

@petebrowne
Copy link

If you'd like to use this feature, I've built a simple class for including mixins: Mixable.

With it, you get pretty damn close to extend and include keywords:

nameMixin = { name: "Steve" }

makeSteveMixin = { steve: -> new this() }

class Person extends Mixable
  @include nameMixin
  @extend  makeSteveMixin

steve = new Person
steve.name() # => "Steve"
steve2 = Person.steve()

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants