On Wed, May 23, 2012 at 6:36 PM, alessioalex <[email protected]> wrote:
> That wouldn't work because you cannot call doubleFoo.m directly without
> creating a new doubleFoo objected.

Yeah, that was a typo.

> Secondly, even if you would instantiate a
> new doubleFoo object the m function will get overriden by foo.m (since
> that's stored in the prototype).

Well, that's because you made it so. Mine works differently, see below.

> Last but not least, you cannot call
> this.inherited if there's no class to inherit from (a class inherits from a
> super class if the uber property stores a reference to that super class).
>
> What you can do instead is extend the foo class with its own m method and
> then call inherited inside the m function:
>
> var Cls = require('Cls');
>
>
> var Foo = Cls({
>   methods: {
>     m: function (x) {
>       console.log(x);
>     }
>   }
> });
>
> var DoubleFoo = Cls({
>   uber: Foo,
>   methods: {
>     m: function(x) {
>       // first argument is name of super function, second is array of
> arguments
>       this.inherited('m', [x * 2]);
>     }
>   }
> });
>
> var df = new DoubleFoo();
> df.m(1);

Well, this is plain old class inheritance. The downside of this
approach you cannot import DoubleFoo's behavior to another class Baz
with a base class.
Whereas defineClass allows that:

// define a trait
var DoubleXInM = {
  m: function (x) {
    return this._super(x); // call a method that _will be_ inherited.
  }
};

var DoubleFoo = defineClass({
  _super: [Foo, DoubleXInM],
  // other stuff
});

var BaseBaz = defineClass({
  m: function (x) {
    alert(x);
  }
});

var Baz = defineClass({
  _super: [BaseBaz, DoubleXInM]
});

new Baz().m(1); // alert(2)

This approach allows putting a behavior to a trait and reusing it in
_different_ class hierarchies.
It makes sense in big systems.

> You may be asking yourself why the heck do i ask for the name of the super
> function when calling inherited?
>
> Well, I could have just used this.inherited(arguments) or simply
> this.inherited() and make the function call super with the last function
> that was executed on the child, like Klass (https://github.com/ded/klass)
> does.
> The problem with that is that if I call functionA and functionB of the "sub
> class" (the class that inherits from the super class) and function a would
> call this.inherited() after 2 seconds for example that wouldn't work
> (because the last function called would be functionB not functionA).
>
> Example that wouldn't work:
>
>
> var Foo = Cls({
>   methods: {
>     m: function (x) {
>       console.log(x);
>     }
>   }
> });
>
> var DoubleFoo = Cls({
>   uber: Foo,
>   methods: {
>     m: function(x) {
>       var that = this;
>       setTimeout(function() {
>         that.inherited();
>       }, 2000);
>     },
>     bla: function() {
>       // do stuff
>     }
>   }
> });
>
> var df = new DoubleFoo();
> df.m(1);
> df.bla();
>
> But with the approach from Cls (specifying inherited with name of super
> function and arguments) this does work properly (although more verbose).

Yes, I am aware of that problem and I have warning in me readme:

---
The _super field value changes from method call to method call, so it
may be used only in the method that has overridden the base method. Do
not use it in a nested function unless you know what you are doing.
----

But I like the approach I used more because:

1. It's shorter and works in the majority of cases
2. You don't have to change these string(s) when you rename a method
as a part of refactoring

In such cases I recommend saving the method to a variable:

{
  m: function (x) {
    var that = this,
         super = this._super;

    function a() {
      return super.call(that, x);
    };
}
  a();
}

Thanks,
-Nodir

>
> On Wednesday, May 23, 2012 2:09:49 PM UTC+3, Nodir Turakulov wrote:
>>
>> On Wed, May 23, 2012 at 4:00 PM, Nodir Turakulov <[email protected]>
>> wrote:
>> > On Wed, May 23, 2012 at 2:17 PM, alessioalex <[email protected]>
>> > wrote:
>> >> I've made a OOP module myself a couple of days ago:
>> >> https://github.com/alessioalex/Cls
>> >>
>> >> It uses an extends function and a mixin function under the hood, very
>> >> basic
>> >> stuff.
>> >
>> > As far as I understand after a quick look at the readme, your mixins
>> > only overwrites properties without inheriting methods
>>
>> Sorry, the word "inheriting" is wrong here. I meant that a mixin
>> method cannot call a base method.
>>
>> -Nodir
>>
>> > Can I call a base/super method in a mixin method?
>> >
>> > var foo = Cls({
>> >  methods: {
>> >    m: function (x) {
>> >      console.log(x);
>> >    }
>> >  }
>> > });
>> >
>> > var mixin = {
>> >  m: function (x) {
>> >    this.inherited(x * 1);
>> >  }
>> > };
>> >
>> > var doubleFoo = Cls.mixin(foo, mixin);
>> > doubleFoo.m(1); // will it output 1 or 2?
>> >
>> > -Nodir
>> >
>> >> --
>> >> Job Board: http://jobs.nodejs.org/
>> >> Posting guidelines:
>> >> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
>> >> You received this message because you are subscribed to the Google
>> >> Groups "nodejs" 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/nodejs?hl=en?hl=en
>
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" 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/nodejs?hl=en?hl=en

-- 
Job Board: http://jobs.nodejs.org/
Posting guidelines: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" 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/nodejs?hl=en?hl=en

Reply via email to