- @blooddy: *ActionScript *идиотизм *странностиответ на #792281 не тривиален:
registerClassAlias( 'ASD', BitmapData );
describeType( BitmapData ).@alias - @blooddy: *ActionScript *идиотизм *Questесть 2 метода:
registerClassAlias
getClassByAlias
несомненно послезные методы, но кто-нить задумывался как AMF получает имя алиаса по классу? ведь метода getAliasByClass нету =)
когда я узнал, у меня задёргался левый глаз. - @blooddy: *ActionScript *bug *идиотизмнаконец удалость составить короткий пример проявления бага #785401
линуксоидам скажу сразу, что на бубунте воспроизвести не удаётся. а так не удаётся воспроизвести в ИЕ некоторых версий. в общем бага плавающая.
package {
import flash.display.Sprite;
import flash.utils.ByteArray;
public class test extends Sprite {
/**
* Constructor
*/
public function test() {
super();
// запускаем многократные тесты
for ( var i:uint = 0; i<10; i++ ) {
trace( '================== test ' + i );
binary_test();
}
}
private static const LENGTH:uint = 5e3;
private static function binary_test():void {
// создаём новый бинарник
var bytes:ByteArray = new ByteArray();
bytes.writeUnsignedInt( 10 ); // делаем запись
bytes.length = LENGTH; // меняем длинну
// проверяем что у нас лежит в бинарнике
var i:uint = 4;
do {
if ( bytes[ i ] != 0 ) {
trace( 'index: ' + i + ', value: ' + bytes[ i ] );
}
} while ( ++i < LENGTH );
// заполняем бинарник
i = 4;
do {
bytes.writeInt( i );
i += 4;
} while ( i < LENGTH );
bytes.clear(); // чистим
}
}
}
если менять местаим эти 2 строчки, то бага исправляется
bytes.writeUnsignedInt( 10 ); // делаем запись
bytes.length = LENGTH; // меняем длинну - @blooddy: *bug *идиотизм *ActionScriptсижу я, значит, пишу обновлении для своей крипто-библиотеки ( #755847 ), и случайно вывожу на экран 2 результата от 2 запусков PNGEncoder.
первый вариант 100% совпадает с оригиналом, а второй был слегка искажён. я сперва не сообразил, что произошло, а потом пришёл в состояние шока. решил добавить ещё парочку результатов, и получил, ещё более искажённые результаты.
flasher.ru
начал искать искать ошибки у себя в коде: переиспользование переменных; проверял везде ли чиститься память; заменял одни вызовы другим, но результат становился чаще хуже, чем лучше.
на протяжении всех 10 часов паники я общался с wvxvw ( flasher.ru ), и мы вместе пытались понять причину, но не ничего не выходило.
в конце концов в один из блоков я вставил код проверки на записанное значение в ByteArray. и оказалось, что там на 88731 индексе уже записано число отличное от 0.
глаза мои вылезли на орбиту: ведь этот массив был создан всего 2мя строчками выше, и в него ничего не писалось кроме одного числа в нулевой индекс! то есть фактически он был пуст.
передвинув проверку на строчку выше я удивился ещё больше, так как не только trace оказался чист, но и картинки отобразились корректно.
немного поигравшись с перемещением срок, я убедился, в зависимости бага от положения строк.
выяснилось следующие: при определённых обстоятельствах бинарник оказывался не девственно чистым. обстоятельства такого поведения обнаружить не удалось. но решение найдено таки было.
чистота бинарника зависит от первой операции проводимой с ним!
если первой операцией будет write, то в массиве может оказаться мусор. но если первой операцией задать ему нужную длину, то на протяжении всей длинны будут записаны только нули.
var b:ByteArray = new ByteArray();
b.writeUnsignedInt( value );
b.length = 1024; // может попасться мусор
var b:ByteArray = new ByteArray();
b.length = 1024; // мусора не будет
b.writeUnsignedInt( value );
судя по всему в бинарнике остаются значения от предыдущих вычислений, хоть я в конце каждого использования честно вызываю clear. - @blooddy: *php *идиотизм *haxeя тут задумался о ситуации с приватами в php ...
где-то я видел такие вот реализации:
вбиваешь в адресной строке что-то типа site.com
а в пхп происходит следующие:
создаётся экземпляр класса controler и вызывается у него метод method с передачей в него параметра arg.
выходит, что если я это на хаксе напишу, то у меня весь код — это сплошная injection уязвимость.
забавная идиология =) точнее идиома.#752260, 2 months ago - @blooddy: *haXe *идиотизмциклы, сцуко, коварны ...
при использовании загадочных for'ов и inline-методов надо быть острожным. загадочный компилятор хакса для своих тайных нужд, при сочетании этих двух слов создаёт локальную переменную, в которую записывает значение класса.
class A {
static inline function aaa() {
// <-- вот тут всовывается var loc_0:* = A;
var i:Int;
for ( i in 0...10 ) {
}
}
}
соответственно могут возникнуть неприятные последствия, при попытки сделать exclude классу A.
в общем пришлось отказаться в пользу while, с которым такого не бывает. - @blooddy: *ActionScript *идиотизм *странностиДениска ( etcs.ru ) меня сегодня порадовал ещё раз:
public function test()void {
var a:String;
trace( typeof a ); //string
}
в чём же прикол? по логике в a записан null а значит результатом должен быть object, но мы наблюдаем string.
оказывается компилятор превращает это вот такой вот код:
_as3_pushnull
_as3_coerce_s
_as3_setlocal <1>
_as3_findpropstrict trace
_as3_pushstring "string"
_as3_callpropvoid trace(param count:1)
в хуманабельном виде это выглядит так:
public function test() : void {
var _loc_1:String = null;
trace("string");
return;
}
тоесть копилятор оптимизирует выражение typeof a до выражение string, но этот же копилятор не умеет оптимизировать математические выражения =) лол. - @blooddy: *ActionScript *идиотизм *странностикак вы думаете что будет в результате:
trace( null + null );
по сообщение __etc ( etcs.ru ) будет 0. да, именно 0. я уже проверил =)
это прекрасно!
trace( typeof ( null + null ) );
выдаёт number. - @blooddy: *ActionScript *идиотизм *странностивот мне интересно как так устроенно AS3 API, что оно так странно работает? :)
простейший ( и при этом широко известный ) пример:
while ( numChildren ) {
removeChildAt( 0 );
}
этот код работает быстрее чем:
var i:int = numChildren;
while ( --i ) {
removeChildAt( i );
}
парадокс. казалось бы удаление последнего элемента массива должно занимать меньше времени чем первого, да и обращение к локальной переменной должно быть шустрее, чем к свойству объекта. ан-нет! нефига. устройство данной конструкции остаётся загадкой.
но при этом у нас есть 2 метода:
getDefinitionByName
getClassByAlias
объясните мне идиоту, почему приходится писать обёртки для этих методов? что в них такого страшного происходит, что приходится делать локальные хэши?
в результате через такой метод всё работает в N раз быстрее.
function get(name:String):Object {
var result:Object = _hash[ name ];
if ( !result ) {
_hash[ name ] = result = getDefinitionByName( name );
}
return result;
}
в чём ваще проблема сделать это на нативном уровне?
почему эти методы кидают исключение а не возвращают null? и как мне избегать исключения, если у меня нету метода hasDefinition, hasClassAlias?
точнее с дефинишем я, конечно, вру слегка. проверить можно так:
ApplicationDomain.currentDomain.hasDefinition
но если так проверять, то проще запросить тогда
ApplicationDomain.currentDomain.getDefinition
ведь последний метод возвращает null как и положено =)
p.s.: я не любитель try..catch, и всегда стараюсь избегать их используя if..else, если есть такая возможность. - @blooddy: *flash *идиотизм *FlexFlex *идиотизм кстати ... никто не задумывался над парадоксом: Flash делает адоба, Flex делает адоба, но рекламируют они его как разные продукты. причём равноправные. и тем самым самым тратють лишние бабки. эпопея с флексом зашла на столько далеко, что им пришлось переименовать FlexBuilder в FlashBuilder, так как люди перестали понимать что где, и откуда растёт...
- @blooddy: *ActionScript *идиотизм *странностине секрет, что в AS есть различные недокументированные багафичи.
например у класса Object есть такие вот методы:
protected static function _dontEnumPrototype(proto:Object):void;
protected static function _setPropertyIsEnumerable(o:*, V:String, enumerable:Boolean):void;
static function init():*;
а как обнаружил недавно Дениска ( etcs.ru ) если, попытаться объявить метод $construct у наследников DisplayObject, то получим следующие ошибки:
1021: Повторное определение функции.
1025: Невозможно переопределить окончательный метод.
ещё классов Vector, Math, единственные классы, у которых нету статического свойтсва length. а у классов Namespace, XML и XMLList у этого свойство отсутствует типизация.
полно недокументированных классов, или даже целых пакетов.
существует загадочный пакет adobe.utils, в составе которого есть класс ProductManager, а так же метод MMEndCommand.
есть пакет authoring с единственным классов authObject. да-да, класс название класса начинается маленькой буквы, зато все его методы и свойства начинают с большой =)
а кто-нить слышал про класс UninitializedError? я нет. а он существует =)
честно говоря в пакете flash.sampler гараздо больше барахла, чем нам рассказывает дока. ну и не забудем загадочные пакеты flash.profiler, flash.debuger и flash.trace. - @blooddy: *ActionScript *bug *идиотизму себя в проектах, я довольно часто использую метаданные ( help.adobe.com ).
в AS есть зарезервированный метатэг [Exclude], который скрывает указанную сущность в инспекторе билдера, и иногда в подсказках к коду. тэг должен применяться к классу. множество примеров можно обнаружить во Flex фрэймворке. но этот метатэг применим не только для флекса, но и к обычным pure as3 проектам.
так же этот тэг используется в стандартных классах. как известно у класса Stage есть ряд переопределённых свойств, которые кидают исключение при попытки обратится к ним. так вот эти свойства перечислены в [Exclude]-тэгах. правда идиотизм в том, что все эти тэги объявлены у свойства frameRate: blooddy.pastebin.com#585826, 5 months ago - @blooddy: *ActionScript *bug *идиотизмвсе знают, что у нас XML неправильный?
var node:XML = <node />;
node.appendChild( '<>&"' );
node.@prop = '<>&"';
в результате в теле не будет заменена " ( кавычка ), а в атрибуте как есть останется >.
на такое поведение ругнётся практически любой валидатор. почему спец символы не всегда заменяются на мнемоники, для меня загадка...
главный идиотизм заключается том, что это и исправить нельзя. при попытке передать > вместо > у него преобразуется &, что нормального человека не устроит. даже если парсить XML из строки, он всё равно испоганится.#585680, 5 months ago - @blooddy: *ActionScript *bug *идиотизмпонаписал всякого кода по идиотизмам и их исправлениям
#545813 — вторая ошибка у сокета
хукнутый Socket: blooddy.pastebin.com
#553911 — вызов load в конструкторе Sound
код с проявлением ошибки: blooddy.pastebin.com
код с иправленной ошибкой: blooddy.pastebin.com
#563468 — добавление детей в TextField
хукнутый TextField: blooddy.pastebin.com
#563595 — двойной addedToStage
код с проявлением ошибки: blooddy.pastebin.com
хукнутый Sprite: blooddy.pastebin.com
p.s.: если кому-то не лень, то можите запостить в жиру к адобе? а то у меня там чего-то с акком случилось, да и с английским беда =) читать и читаю, а вот связанный текст написать не получается.
только про TextField не пишите =) я считаю это фичёй =) - @blooddy: *ActionScript *идиотизмнашлось объяснение поведению описанному тут #565675
оказывается возникал конфликт имён:
var parameters:Object = ( LoaderConfig ? LoaderConfig.parameters : null );
тоесть вместо запроса обычного свойства у LoaderConfig, плэйер пытался сделать какой-то запрос используя локальную перменную parameters.
такое поведение предположил iNils ( flasher.ru ). и, дейсвительно, после преименования локальной перменной, всё начало работать правильно.
