1
0
Fork 0

Super method now provided on method override wrapper

This allows invoking any arbitrary method of a supertype. This is needed,
for example, if some method `foo` is overridden, but we wish to call the
parent `foo` in another method; this is not possible with __super:

  var C = Class(
  {
      'virtual foo': function() { return 'super'; }
  } );

  var SubC = C.extend(
  {
      'override foo': function() { return 'sub'; },

      superfoo: function() { return this.foo.super.call( this ); }
  } );

  SubC().superfoo();  // 'super'

Obviously, __super would not work here because any call to __super within
SubC#superfoo would try to invoke C@superfoo, which does not exist.
protolib
Mike Gerwitz 2014-05-02 21:27:02 -04:00
commit 1b9317de62
No known key found for this signature in database
GPG Key ID: F22BB8158EE30EAB
2 changed files with 37 additions and 1 deletions

View File

@ -26,7 +26,7 @@
exports.standard = { exports.standard = {
wrapOverride: function( method, super_method, cid, getInst ) wrapOverride: function( method, super_method, cid, getInst )
{ {
return function() var retf = function()
{ {
var context = getInst( this, cid ) || this, var context = getInst( this, cid ) || this,
retval = undefined retval = undefined
@ -55,6 +55,9 @@ exports.standard = {
return retval; return retval;
}; };
retf.super = super_method;
return retf;
}, },

View File

@ -201,6 +201,39 @@ require( 'common' ).testCase(
}, },
/**
* While __super is convenient and concise, it is not general-purpose
* and does not solve the problem of invoking any arbitrary method on
* the supertype. In particular, we may override some method foo, but
* wish to call the parent foo in another method; we cannot do that with
* __super.
*
* Note, however, that this will require foo.super.call( this ) to
* provide the proper context.
*/
'Can invoke super method by calling override.super': function()
{
var expected = {},
getInst = function() { return {}; },
// super method to be overridden
method = this._sut.standard.wrapNew(
function() { return expected; },
null, 0, getInst
),
// the overriding method (we don't care what this does)
override = this._sut.standard.wrapOverride(
function() {}, method, 0, getInst
)
;
// we should be able to invoke the super method by override.super,
// which is added atop of the wrapper
this.assertStrictEqual( override.super(), expected );
},
/** /**
* The proxy wrapper should forward all arguments to the provided object's * The proxy wrapper should forward all arguments to the provided object's
* appropriate method. The return value should also be proxied back to the * appropriate method. The return value should also be proxied back to the