Opened 9 years ago

Closed 9 years ago

#10990 closed defect (wontfix)

dojo.inherited() not calling base method

Reported by: eyee Owned by: Eugene Lazutkin
Priority: high Milestone: future
Component: Core Version: 1.4.1
Keywords: inherited Cc:
Blocked By: Blocking:

Description

If a child class's method b() calls the base class's method a() dojo.inherited() will invoke the child class's method a() instead of the base class's method a().

Here's the code to demonstrate the problem:


dojo.declare("BaseClass?", null, {

constructor: function() {

console.error("BaseClass?.constructor()");

}, a: function() {

console.error("BaseClass?.a()");

}, b: function() {

console.error("BaseClass?.b()");

}

});

dojo.declare("ChildClass?", BaseClass?, {

constructor: function() {

console.error("BaseClass?.constructor()");

}, a: function() {

console.error("ChildClass?.a()"); this.inherited("b", arguments);

}, b: function() {

console.error("ChildClass?.b()");

}

});

function onPageLoad() {

alert("stop"); var obj = new ChildClass?(); obj.a();

}

dojo.addOnLoad(onPageLoad);


I debugged dojo.inherited() and discovered that it is expecting the method name and the caller.nom to be the same. I modified inherited() to the following and it seems to work correctly. However, I'm not familiar with the code to know if this change will break the existing behavior.


function inherited(args, a, f){

var name, callerName, chains, bases, caller, meta, base, proto, opf, pos,

cache = this._inherited = this._inherited
{};

crack arguments if(typeof args == "string"){

name = args; args = a; a = f;

} f = 0;

caller = args.callee;

name = name
caller.nom;

if(!name){

err("can't deduce a name to call inherited()");

}

meta = this.constructor._meta; bases = meta.bases;

pos = cache.p; if(name != cname){

callerName = caller.nom;

method if(cache.c !== caller){

cache bust pos = 0; base = bases[0]; meta = base._meta; if(meta.hidden[callerName] !== caller){

error detection chains = meta.chains; if(chains && typeof chains[callerName] == "string"){

err("calling chained method with inherited: "

+ callerName);

} find caller do{

meta = base._meta; proto = base.prototype;

if(meta && (proto[callerName] === caller && proto.hasOwnProperty(name)
meta.hidden[callerName] === caller)){

break;

}

}while(base = bases[++pos]); intentional assignment pos = base ? pos : -1;

}

} find next base = bases[++pos]; if(base){

proto = base.prototype; if(base._meta && proto.hasOwnProperty(name)){

f = proto[name];

}else{

opf = op[name]; do{

proto = base.prototype; f = proto[name]; if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){

break;

}

}while(base = bases[++pos]); intentional assignment

}

}

f = base && f
op[name];

}else{

constructor if(cache.c !== caller){

cache bust pos = 0; meta = bases[0]._meta; if(meta && meta.ctor !== caller){

error detection chains = meta.chains;

if(!chains
chains.constructor !== "manual"){

err("calling chained constructor with inherited");

} find caller while(base = bases[++pos]){ intentional assignment

meta = base._meta; if(meta && meta.ctor === caller){

break;

}

}; pos = base ? pos : -1;

}

} find next while(base = bases[++pos]){ intentional assignment

meta = base._meta; f = meta ? meta.ctor : base; if(f){

break;

}

} f = base && f;

}

cache the found super method cache.c = f; cache.p = pos;

now we have the result if(f){

return a === true ? f : f.apply(this, a
args);

} intentionally if a super method was not found

}


Change History (2)

comment:1 Changed 9 years ago by Eugene Lazutkin

Component: GeneralCore
Milestone: tbdfuture
Owner: changed from anonymous to Eugene Lazutkin
severity: criticalnormal
Status: newassigned

Please attach files instead of making big snippets.

Technically it is not a bug, see http://docs.dojocampus.org/dojo/declare

Optional name of the method to call. Generally it should be specified when calling this.inherited() from an un-annotated method, otherwise it will be deduced from the method itself.

It is not used to specify, which method to call, but what method is calling. See the explanation at the bottom of #10788.

It is possible to implement the behavior you are talking about, but I am not sure if it breaks any other code in use.

comment:2 Changed 9 years ago by Eugene Lazutkin

Resolution: wontfix
Status: assignedclosed
Note: See TracTickets for help on using tickets.