Separating class and instance methods inside a module into submodules (ruby-like idiom)?

42 views
Skip to first unread message

Roman Snitko

unread,
May 30, 2012, 4:11:44 AM5/30/12
to jsclas...@googlegroups.com
(hope it's not too many questions in row, but I'm playing with JS.Class really actively now).

I was trying to implement a ruby-like separation of class and instance methods inside a module using `included`, here's what it looks like:

    Validatable = new JS.Module({

      InstanceMethods: new JS.Module({
        ...
      }),

     ClassMethods: new JS.Module({
       ...
     }),

    extend: {
      included: function(klass) {
        klass.include(this.klass.InstanceMethods);
        klass.extend(this.klass.ClassMethods);
      }
    }

  }

However, `this.klass.ObjectMethods` and `this.klass.ClassMethods` are undefined. How do I get access to them correctly?

James Coglan

unread,
May 30, 2012, 5:47:52 AM5/30/12
to jsclas...@googlegroups.com
On 30 May 2012 10:11, Roman Snitko <roman....@gmail.com> wrote:
I was trying to implement a ruby-like separation of class and instance methods inside a module using `included`, here's what it looks like:

    Validatable = new JS.Module({

      InstanceMethods: new JS.Module({
        ...
      }),

     ClassMethods: new JS.Module({
       ...
     }),

    extend: {
      included: function(klass) {
        klass.include(this.klass.InstanceMethods);
        klass.extend(this.klass.ClassMethods);
      }
    }

  }

However, `this.klass.ObjectMethods` and `this.klass.ClassMethods` are undefined. How do I get access to them correctly?

To explain what's going on here: you've made InstanceMethods and ClassMethods as instance properties of the Validatable module, so they will become instance properties of whatever you mix the module into. The the included() function, `this` refers to the Validatable module, so the value of `this.klass` is Module.

What you probably want to do is move the modules into the `extend` block, and just use `this.InstanceMethods` to refer to them in included().

Roman Snitko

unread,
May 31, 2012, 4:23:38 AM5/31/12
to jsclas...@googlegroups.com

To explain what's going on here: you've made InstanceMethods and ClassMethods as instance properties of the Validatable module, so they will become instance properties of whatever you mix the module into. The the included() function, `this` refers to the Validatable module, so the value of `this.klass` is Module.

What you probably want to do is move the modules into the `extend` block, and just use `this.InstanceMethods` to refer to them in included().

Yes, thank you for the explanation, makes a lot of sense, actually. It works.
However, I must ask you a bit more about included(). This is from the docs:

In the same vein, if you include() a module that has a singleton method called included, that method will be called. This effectively allows you to redefine the meaning of include for individual modules.

Yet you're saying that InstanceMethods and ClassMethods, if defined as module's instance properties, become instance properties of whatever I mix the module into. Does that mean that included() is simply a callback and by providing this callback I don't prevent module's instance properties from mixing in?

James Coglan

unread,
Jun 5, 2012, 11:35:02 AM6/5/12
to jsclas...@googlegroups.com
On 31 May 2012 09:23, Roman Snitko <roman....@gmail.com> wrote:
However, I must ask you a bit more about included(). This is from the docs:

In the same vein, if you include() a module that has a singleton method called included, that method will be called. This effectively allows you to redefine the meaning of include for individual modules.

Yet you're saying that InstanceMethods and ClassMethods, if defined as module's instance properties, become instance properties of whatever I mix the module into. Does that mean that included() is simply a callback and by providing this callback I don't prevent module's instance properties from mixing in?

Yes, I guess the docs are misleading here. The baseline behaviour of include() is *always* to mix properties in and add the module to the ancestor chain. included() lets you define *additional* behaviour, not replace the existing behaviour.
Reply all
Reply to author
Forward
0 new messages