From: Thomas 'PointedEars' Lahn on
Dmitry A. Soshnikov wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Dmitry A. Soshnikov wrote:
>> > David Mark wrote:
>> >> > By the way, there's also one more ability to call overwritten
>> >> > parent method just with `this._super()' expression.
>> >>
>> >> I assume you mean this._super.foo() to call the "super" foo method.
>> >
>> > Actually, just this._super(), e.g.
>> >
>> > foo: function () {
>> > this._super(); // will call `foo' in parent
>> > }
>> Never. Check your assumptions.
>
> Please remember this ;) And your asking to show to you something that
> you don't know. If you want, I can show you the code.

Please do. I would be very much surprised if it worked as you posted.
For that would require that the method was called as a method of itself.


PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)
From: Dmitry A. Soshnikov on
On Jan 13, 5:20 pm, Thomas 'PointedEars' Lahn <PointedE...(a)web.de>
wrote:
> Dmitry A. Soshnikov wrote:
> > Thomas 'PointedEars' Lahn wrote:
> >> Dmitry A. Soshnikov wrote:
> >> > David Mark wrote:
> >> >> > By the way, there's also one more ability to call overwritten
> >> >> > parent method just with `this._super()' expression.
>
> >> >> I assume you mean this._super.foo() to call the "super" foo method.
>
> >> > Actually, just this._super(), e.g.
>
> >> > foo: function () {
> >> > this._super(); // will call `foo' in parent
> >> > }
> >> Never.  Check your assumptions.
>
> > Please remember this ;) And your asking to show to you something that
> > you don't know. If you want, I can show you the code.
>
> Please do.  I would be very much surprised if it worked as you posted.
> For that would require that the method was called as a method of itself.
>

This is just a copy-paste of my theoretical thoughts based on well-
known patterns (with intermediate constructor to make prototype chain
and with wrappers for methods with the same name).

Main goals of the code bellow:

* No optimization;
* No whatever;
* scope chain of wrapped methods and wrapper will have some garbage;
* I *don't* use this pattern (and have never used) in production, this
is *just academical interest*;
* I don't like this pattern, it's just to show alternative.

File for constructors ("classes") building, you can call it Class.js
or whatever:

---------------------------------

function Class(params) {

function Klass() {
this.initialize.apply(this, arguments);
}

if (params.__extends) {
var __inheritance = function () {};
__inheritance.prototype = params.__extends.prototype;
Klass.prototype = new __inheritance();
Klass.prototype.constructor = Klass;
Klass.superClass = params.__extends;
}

!params.initialize && (params.initialize = Class.emptyFn);
Klass.prototype.__class__ = Klass;

for (var method in params) if (params.hasOwnProperty(method)) {
if (method == '__extends') {
continue;
}
Klass.prototype[method] = params[method];
if (params.__extends && typeof params.__extends.prototype[method]
== 'function') {
(function (methodName) {
var __originalMethod = params[methodName];
var __superMethod = params.__extends.prototype[methodName];
Klass.prototype[methodName] = function () {
var __previousSuper = this._super;
this._super = __superMethod;
var result = __originalMethod.apply(this, arguments);
this._super = __previousSuper;
return result;
};
})(method);
}
}

return Klass;

}

Class.emptyFn = function () {};

---------------------------------

So, nothing special, all of this you all know.

Usage. File for testing:

---------------------------------

<script type="text/javascript" src="Class.js"></script>
<script type="text/javascript">

var A = Class({
initialize: function (aArg) {
this.aArg = aArg;
alert('A#initialize');
},
test: function () {
alert('A#test');
}
});

var B = Class({
__extends: A,
initialize: function (bArg) {
this._super(bArg);
this.bArg = bArg;
alert('B#initialize');
},
test: function () {
this._super();
alert('B#test');
}
});

var C = Class({
__extends: B,
initialize: function (cArg) {
this._super(cArg);
this.cArg = cArg;
alert('C#initialize');
},
test: function () {
this._super();
alert('C#test');
}
});

var D = Class({
__extends: C,
initialize: function (dArg) {
this._super(dArg);
this.dArg = dArg;
alert('D#initialize');
},
test: function () {
this._super();
alert('D#test');
this.testD();
},
testD: function () {
alert('D#testD');
}
});

var d = new D(10);
d.test();

---------------------------------

You can see how `d' instance is created and how parent methods are
called (alerts will inform about this). The code is complete and
runnable.

But as I said, I don't like this implementation much as it's not so
useful from the performance.

Regarding to implementation with `caller' which also will let to use
just `this.super()', I haven't yet code, will write later if will be
needed (but can tell, that only difference will be in marking methods
to set their `name' property, which is used in Spidermonkey's
implementation. Using that ability we can call parent methods by name,
using `caller' from the `this._super()', quit easy and elegant, but
dangerous as `caller' is deprecated and even throw an exception in
strict of ES5).

/ds
From: Thomas 'PointedEars' Lahn on
Dmitry A. Soshnikov wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Dmitry A. Soshnikov wrote:
>> > Thomas 'PointedEars' Lahn wrote:
>> >> Dmitry A. Soshnikov wrote:
>> >> > David Mark wrote:
>> >> >> > By the way, there's also one more ability to call overwritten
>> >> >> > parent method just with `this._super()' expression.
>> >> >> I assume you mean this._super.foo() to call the "super" foo
>> >> >> method.
>> >> > Actually, just this._super(), e.g.
>> >> >
>> >> > foo: function () {
>> >> > this._super(); // will call `foo' in parent
>> >> > }
>> >> Never. Check your assumptions.
>> > Please remember this ;) And your asking to show to you something that
>> > you don't know. If you want, I can show you the code.
>> Please do. I would be very much surprised if it worked as you posted.
>> For that would require that the method was called as a method of itself.
>
> This is just a copy-paste of my theoretical thoughts based on well-
> known patterns (with intermediate constructor to make prototype chain
> and with wrappers for methods with the same name).
>
> Main goals of the code bellow:

I don't think you were looking for the word "goals" here; perhaps
"problems".

> * No optimization;

OK.

> * No whatever;

Pardon?

> * scope chain of wrapped methods and wrapper will have some garbage;
> * I *don't* use this pattern (and have never used) in production, this
> is *just academical interest*;
> * I don't like this pattern, it's just to show alternative.

Not a viable or remotely equivalent alternative, though.

> File for constructors ("classes") building, you can call it Class.js
> or whatever:
>
> ---------------------------------
>
> function Class(params) {
>
> function Klass() {
> this.initialize.apply(this, arguments);
> }

Calling an `initialize' method instead of using a constructor is indicative
of a lack of minimum clue. Last I checked, it was one of Prototype.js's
major flaws.

> if (params.__extends) {
> var __inheritance = function () {};
> __inheritance.prototype = params.__extends.prototype;
> Klass.prototype = new __inheritance();

We have already established here that it is potentially more efficient and
reasonably safe to create the dummy constructor only once.

> Klass.prototype.constructor = Klass;

OK.

> Klass.superClass = params.__extends;

Those identifiers are questionable.

> }
>
> !params.initialize && (params.initialize = Class.emptyFn);
> Klass.prototype.__class__ = Klass;

Do not define properties which names start and end with `__'; those should
be reserved to built-in properties. At least four of them
(__defineGetter__, __defineSetter__, __iterator__ and __proto__) are built
into one implementation (JavaScript) already. And of course `__class__' is
wrong in itself.

> for (var method in params) if (params.hasOwnProperty(method)) {

I am using a similar approach, but I have come to realize that iterating
over an Array using numeric indexes is probably safer and more efficient.

> if (method == '__extends') {
> continue;
> }
> Klass.prototype[method] = params[method];
> if (params.__extends && typeof params.__extends.prototype[method]
> == 'function') {
> (function (methodName) {
> var __originalMethod = params[methodName];
> var __superMethod = params.__extends.prototype[methodName];
> Klass.prototype[methodName] = function () {
> var __previousSuper = this._super;
> this._super = __superMethod;
> var result = __originalMethod.apply(this, arguments);
> this._super = __previousSuper;
> return result;
> };
> })(method);

You can't be serious. Efficiency aside, this is not thread-safe, not even
exception-safe. So even if we would be operating in an ECMAScript vacuum
without DOMs this would not be acceptable.

> }
> }
>
> return Klass;
>
> }
>
> Class.emptyFn = function () {};
>
> ---------------------------------
>
> So, nothing special, all of this you all know.

Unfortunately.

> [...]
> But as I said, I don't like this implementation much as it's not so
> useful from the performance.

Performance is the least of its issues. This is even worse than what Jorge
proposed.

> Regarding to implementation with `caller' which also will let to use
> just `this.super()', I haven't yet code, will write later if will be
> needed (but can tell, that only difference will be in marking methods
> to set their `name' property, which is used in Spidermonkey's
> implementation. Using that ability we can call parent methods by name,
> using `caller' from the `this._super()', quit easy and elegant, but
> dangerous as `caller' is deprecated and even throw an exception in
> strict of ES5).

Please refrain from posting it, then. Nothing useful/sane can be learned
there.


PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f806at$ail$1$8300dec7(a)news.demon.co.uk>
From: Dmitry A. Soshnikov on
On Jan 13, 4:50 pm, Thomas 'PointedEars' Lahn <PointedE...(a)web.de>
wrote:

[...]

> > foo: function () {
> >   this._super(); // will call `foo' in parent
> > }
>
> Never.  Check your assumptions.
>

So? I was asking to remember this words. And showed you that it's
possible (regardless the code itself). Is it really never? I'm waiting
your agreement that it's possible. Your helper David is also welcome
for that.

/ds
From: Dmitry A. Soshnikov on
On Jan 13, 6:50 pm, Thomas 'PointedEars' Lahn <PointedE...(a)web.de>
wrote:
> Dmitry A. Soshnikov wrote:
> > Thomas 'PointedEars' Lahn wrote:
> >> Dmitry A. Soshnikov wrote:
> >> > Thomas 'PointedEars' Lahn wrote:
> >> >> Dmitry A. Soshnikov wrote:
> >> >> > David Mark wrote:
> >> >> >> > By the way, there's also one more ability to call overwritten
> >> >> >> > parent method just with `this._super()' expression.
> >> >> >> I assume you mean this._super.foo() to call the "super" foo
> >> >> >> method.
> >> >> > Actually, just this._super(), e.g.
>
> >> >> > foo: function () {
> >> >> >   this._super(); // will call `foo' in parent
> >> >> > }
> >> >> Never.  Check your assumptions.
> >> > Please remember this ;) And your asking to show to you something that
> >> > you don't know. If you want, I can show you the code.
> >> Please do.  I would be very much surprised if it worked as you posted.
> >> For that would require that the method was called as a method of itself.
>
> > This is just a copy-paste of my theoretical thoughts based on well-
> > known patterns (with intermediate constructor to make prototype chain
> > and with wrappers for methods with the same name).
>
> > Main goals of the code bellow:
>
> I don't think you were looking for the word "goals" here; perhaps
> "problems".
>
> > * No optimization;
>
> OK.
>
> > * No whatever;
>
> Pardon?
>
> > * scope chain of wrapped methods and wrapper will have some garbage;
> > * I *don't* use this pattern (and have never used) in production, this
> > is *just academical interest*;
> > * I don't like this pattern, it's just to show alternative.
>
> Not a viable or remotely equivalent alternative, though.
>
> > File for constructors ("classes") building, you can call it Class.js
> > or whatever:
>
> > ---------------------------------
>
> > function Class(params) {
>
> >   function Klass() {
> >     this.initialize.apply(this, arguments);
> >   }
>
> Calling an `initialize' method instead of using a constructor is indicative
> of a lack of minimum clue.  Last I checked, it was one of Prototype.js's
> major flaws.
>
> >   if (params.__extends) {
> >     var __inheritance = function () {};
> >     __inheritance.prototype = params.__extends.prototype;
> >     Klass.prototype = new __inheritance();
>
> We have already established here that it is potentially more efficient and
> reasonably safe to create the dummy constructor only once.
>
> >     Klass.prototype.constructor = Klass;
>
> OK.
>
> >     Klass.superClass = params.__extends;
>
> Those identifiers are questionable.
>
> >   }
>
> >   !params.initialize && (params.initialize = Class.emptyFn);
> >   Klass.prototype.__class__ = Klass;
>
> Do not define properties which names start and end with `__'; those should
> be reserved to built-in properties.  At least four of them
> (__defineGetter__, __defineSetter__, __iterator__ and __proto__) are built
> into one implementation (JavaScript) already.  And of course `__class__' is
> wrong in itself.
>
> >   for (var method in params) if (params.hasOwnProperty(method)) {
>
> I am using a similar approach, but I have come to realize that iterating
> over an Array using numeric indexes is probably safer and more efficient.
>
>
>
> >     if (method == '__extends') {
> >       continue;
> >     }
> >     Klass.prototype[method] = params[method];
> >     if (params.__extends && typeof params.__extends.prototype[method]
> > == 'function') {
> >       (function (methodName) {
> >         var __originalMethod = params[methodName];
> >         var __superMethod = params.__extends.prototype[methodName];
> >         Klass.prototype[methodName] = function () {
> >           var __previousSuper = this._super;
> >           this._super = __superMethod;
> >           var result = __originalMethod.apply(this, arguments);
> >           this._super = __previousSuper;
> >           return result;
> >         };
> >       })(method);
>
> You can't be serious.  Efficiency aside, this is not thread-safe, not even
> exception-safe.  So even if we would be operating in an ECMAScript vacuum
> without DOMs this would not be acceptable.
>
> >     }
> >   }
>
> >   return Klass;
>
> > }
>
> > Class.emptyFn = function () {};
>
> > ---------------------------------
>
> > So, nothing special, all of this you all know.
>
> Unfortunately.
>
> > [...]
> > But as I said, I don't like this implementation much as it's not so
> > useful from the performance.
>
> Performance is the least of its issues.  This is even worse than what Jorge
> proposed.
>
> > Regarding to implementation with `caller' which also will let to use
> > just `this.super()', I haven't yet code, will write later if will be
> > needed (but can tell, that only difference will be in marking methods
> > to set their `name' property, which is used in Spidermonkey's
> > implementation. Using that ability we can call parent methods by name,
> > using `caller' from the `this._super()', quit easy and elegant, but
> > dangerous as `caller' is deprecated and even throw an exception in
> > strict of ES5).
>
> Please refrain from posting it, then.  Nothing useful/sane can be learned
> there.
>

Ah, common ;) I was asking do not discuss the code itself but to
concentrate on the main thing we were talking about - is possible to
use `this._super()' with correct meaning (and behavior) or not? That's
all.

About implementation with caller, I guess you've understand the main
principle and can do it yourself if will be needed.

/ds