PDA

Просмотр полной версии : (сложный) Потеря наследования - моя вина или компилятора?


camelot
10.02.2009, 20:33
проект большой и классов много. но случилась непонятная проблема.
допустим класс

import core.Library;
import some.package.Class;
import parent.ClassAsParent;

dynamic class other.package.SimpleClass extends ClassAsParent
{

public function SimpleClass()
{
trace(this instanceof ClassAsParent);
}

}


пишет "false"

я уже всё перебробовал:
- менял очередности импортов.
- называл классы так что бы имя отцовского класса было первым по алфавиту например: "FIRST_ClassAsParent" и "SECOND_SimpleClass"
- называл классы так чтобы имя отцовского классы было последним например: "SECOND_ClassAsParent" и "FIRST_SimpleClass"
- писал полный путь до отцовского класса "dynamic class other.package.SimpleClass extends parent.ClassAsParent"

единственно что помогает это
other.package.SimpleClass.prototype.__proto__ = parent.ClassAsParent.prototype;

но это не решение и я уверен на 200% что дело в чем-то другом и лучше решить проблему чем затыкать дыры.

chingachgoog
10.02.2009, 20:49
А почему экземпляр класса SimpleClass должен показывать, что он экземпляр своего предка (ClassAsParent)? Он и не будет это показывать, пока вы ему насильно не пропишите prototype.__proto__ = ...
А так правильно:
trace(this instanceof SimpleClass);

etc
10.02.2009, 23:34
Это недостаток instanceof, в силу кривой реализации классов в AS1/AS2.

dimarik
11.02.2009, 00:27
А на каком этапе наследования инстансоф становится якобы не ребенком суперкласса?

camelot
11.02.2009, 13:00
А почему экземпляр класса SimpleClass должен показывать, что он экземпляр своего предка (ClassAsParent)? Он и не будет это показывать, пока вы ему насильно не пропишите prototype.__proto__ = ...
А так правильно:
trace(this instanceof SimpleClass);

a extends в классе зачем, если каждому классу надо будет прописывать родителя руками в рантайме? я уже задумываюсь сделать и запускать вначале проигрывания swf. но это же не выход
class Bubn
{
public static function bindClasses()
{
other.package.SimpleClass.prototype.__proto__ = parent.ClassAsParent.prototype
}
}


Это недостаток instanceof, в силу кривой реализации классов в AS1/AS2.

я прошу прощения, я не до конца обьяснил суть проблемы. Тут дело не в том что instanceof работает неправильно, а
дело в том что раньше SimpleClass работал и наследовался от ClassAsParent нормально. Тоесть методы ClassAsParent работали в SimpleClass, но в какой-то момент SimpleClass перестал наследоваться.
Если вы грешите на instanceof. то такой код
public function SimpleClass()
{
trace(this instanceof ClassAsParent);
trace(this.__proto__ == ClassAsParent);
}

выдаёт два раза False.
я уже вторые сутки пытаюсь понять что именно привело к такому результату и как это исправить. неужели никто не сталкивался с такой проблемой?

з.ы. компилирую в flash cs4. попробовал mtasc (версии 1.14) - результат такой же.

Добавлено через 6 минут
А на каком этапе наследования инстансоф становится якобы не ребенком суперкласса?

компилируется без ошибок. при запуске swf у класса не работают методы парента

chingachgoog
11.02.2009, 14:19
Возможно дело в этом:


Returns
Boolean - If object is an instance of or a subclass of classConstructor, instanceof returns true, otherwise it returns false. Also, _global instanceof Object returns false.


Я тут где-то писал, как возможно(!) на самом деле создаются классы компилятором из-под AS2. И Гурский что-то об этом писал. Там как раз классы - т.е. обычные функции - заносяться в _global.

add:

А вообще попробуйте вместо


trace(this instanceof ClassAsParent);


проверить реального родителя:


trace(this.prototype.__proto__ == ClassAsParent.prototype)


Если уж это покажет false, значит вы запутались в путях классов и ClassAsParent просто не является родителем класса SimpleClass.

silin
11.02.2009, 14:32
не удалось воспроизвести: упорно пишет что (this instanceof ClassAsParent) - true и методы родителя вызывает..
нужен живой пример трабла

camelot
11.02.2009, 16:10
после запарок с классом SomeClass выяснилось что проблема с классом ClassAsParent так как все потомки потеряли наследование от него.

я кодю на Eclipse 3.4 (Ganymede) + FDT 3.1.0.11 Enterprise.
Проект на AS2.
Файл класса ClassAsParent был в кодировке винды (то бишь cp1251).
Я работал совсем над другой частью проекта когда появились баги после компиляции. Долго искав, нашёл трабл в том что у класса потерялась наследственность. Парился,парился - пытался заставить наследоваться. Начал этот топик. Потом выяснилось что, что-то не то с классом родителя. Он компилируется без ошибок и в присутствует в swf но другие классы не хотят от него наследоваться.

за последние несколько часов был непонятный прорыв в плане:
1. взял файл класса ClassAsParent
2. убрал весь функционал и методов. короче выкинул всё что можно. остались только строки вида public function someMethod(){return false;}
3. откомпилил - в CS4 - наследования нет.
4. удалил.
5. создал новый файл в кодировке utf8 (BOM)
6. перенес из файла "обрезанный фукнционал" в этот файл код класса.
7. откомпилировал
8. НАСЛЕДОВАНИЕ ПОЯВИЛОСЬ.
9. нарадостях начав грешить на кодировки и т.д. востанавливаю функционал класса.
10. компилирую - наследования нет....
11. создаю новый файл в utf8 (BOM) с обрезаным функционалом (тоесть вернутся к пункту 5.)
12. компилирую
13. наследования нет

сижу разбираюсь дальше

Добавлено через 53 минуты
нашёл строчку которая нарушает наследование:

dynamic class obj.action.ActionBasic
{
....
private var _distMax:Number = Lib.grid_radius;
....
}

вот часть Lib
class Lib
{
....
static var grid_radius:Number = 6;
....
}

делаю
//private var _distMax:Number = Lib.grid_radius;

наследование востанавливается
есть у кого-нибудь почему так происходит?

silin
11.02.2009, 17:17
дал бы минимальный пример, который косит
каким боком здесь ActionBasic ?
а если инициализацию _distMax перенести в конструктор тоже косит?

crazyone
11.02.2009, 17:47
Действительно, без минимального примера, который косит, врятли тут кто-то чем-то поможет.

camelot
11.02.2009, 17:57
дал бы минимальный пример, который косит
каким боком здесь ActionBasic ?
а если инициализацию _distMax перенести в конструктор тоже косит?

это типа SimpleClass
import obj.action.ActionBasic;
import Lib;

dynamic class obj.action.Purchase extends ActionBasic
{
public function Purchase()
{
super();
trace('purchase constr ' + (this instanceof ActionBasic) );
}
}


есть еще несколько классов наследующихся от ActionBasic.
классы ActionBasic и Lib дал выше.

если перенести инициализацию в констуктор то наследование сохраняется.

public function ActionBasic()
{
trace('ACTIONBASIC CONSTRUCTOR ');
_distMax = Lib.grid_radius;
}


Добавлено через 1 минуту
я так понимаю что я единственный кто с этим столкнулся.
хотя любые идеи приветствуются

silin
11.02.2009, 18:09
>>если перенести инициализацию в констуктор то наследование сохраняется.
так надо перенести и не парится, с инициализацией свойств в классе в AS2 мутновато все..

chingachgoog
11.02.2009, 20:13
Да нет, как инициализируются свойства в AS2 и вообще в AVM1 как раз понятно.
Тут мутно с порядком наследования, что от кого наследуется плюс пути к классам.

silin
11.02.2009, 21:47
вопрос не в том как инициализируются свойства, а в том когда и где они при этом хранятся

при инициализации в самом классе в коде инициализации создается свойство в prototype, для элементарных типов это проходит в любом раскладе, но для объектов (или ссылок) уже критично чтобы объект, поставляющий значение, уже существовал.., если его класс инициализируется позже, то имеем undefined..
еще один нюанс с этим же связанный: свойство неэлемнтарного типа всех экземпляров ссылается на один и тот же объект в прототипе

при инициадизации в конструкторе все нормально: на момент создания все классы уже проинициализированы, в каждом экземпляре создается свой объект

chingachgoog
11.02.2009, 22:19
вопрос не в том как инициализируются свойства, а в том когда и где они при этом хранятся


Это не вопрос
Создается мувиклип в библиотеке с id=__Packages.имя_Класса
Это мувик с экспортом на первый фрейм и кодом в #initclip
Код и собирает в _global нужную функцию-класс, прописывая в ее prototype наследуемые своейства
(особенность для ФП6 (http://flasher.ru/forum/showpost.php?p=797617&postcount=5))

Конечно, #initclip идет в порядке наследования классов, но не мудрено поставить его в тупик:


class A {
static var id="A"
static var brother=B.id
}

class B{
static var id="B"
static var brother=A.id
}


Но такие коллизии компилятор все же отлавливает. Интересно, как автор темы сумел обмануть компилятор.