Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Регистрация Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > Psycho Tiger

Рейтинг: 4.67. Голосов: 6.

Тонкости и трюки ActionScript`а, которые... бесполезны

Запись от Psycho Tiger размещена 10.05.2011 в 00:22
Обновил(-а) Psycho Tiger 10.05.2011 в 23:12

Есть такие вещи в ActionScript`е, которые в нормальных ситуациях просто неприменимы. Я даже скажу иначе: те, которые сложно применить даже в наркотическом опьянении.
Весь код, написанный на ActionScript`е при компиляции превращается в байт-код: последовательность команд, которую исполняет виртуальная машина Tamarin, встроенная в Flash Player. Эти последовательности команд выполняются линейно. Небольшая проблема встречается в том, что код, который мы пишем чаще всего нелинейный: в нём очень много ветвлений — условия, циклы. Собственно, в теории трансляции языков данная проблема решается очень просто: код "развертывается" в набор линейных команд, а все эти ветвления реализуются в виде условных переходов на необходимый участок кода. Проще говоря, при исполнении код "скачет" по линейному набору разных команд. Что я хочу сказать?
Я хочу сказать, что при исполнении этот код частенько не подвергается разным проверкам на валидность. Чаще всего подобные проверки делает компилятор. Поэтому имея в руках спецификацию формата и какой-нибудь редактор байт-кода (даже HEX-редактор подойдёт) мы можем творить несусветную вакханалию... которая будет валидной.
Но нет, сегодня мы не будем уходить за рамки того, что можно скомпилировать из чистого AS3.

1) Множественный вызов... конструктора?
Наш участник BlooDHounD ещё давно писал статью о том, что можно обмануть компилятор и не вызвать конструктор суперкласса... никогда. Например, вот так:
Код AS3:
if (!true) super();
super() никогда не вызовется. Это приводит нас к мысли о том, что в коде всего-лишь должен появится super(), а где — не важно.
Создадим класс SuperClass, в конструкторе которого напишем, например:
Код AS3:
trace("Hello from superclass!");
после создадим класс Descendant, который будет наследоваться от SuperClass (Descendant extends SuperClass).
В конструкторе Descendant напишем следующее:
Код AS3:
var i:int=10;
while (i--) super();
И да. Мы увидим в панеле output "Hello from superclass!" 10 раз.

2) Обращение к методам суперкласса до его инстантиации.
Меня всегда смущало, что я не могу писать вот так:
Код AS3:
super.addEventListener(...);
super();
Конечно, по логике то что я пишу в принципе не может быть верным. Но смущение наступает, когда следующий код признается валидным и валидно исполняется:
Код AS3:
addEventListener(...); //без super.
super();
Что это значит? Это значит что вовсе необязательно дёргать super() перед тем, как обратиться к методу суперкласса. Но, предположим, тот же addEventListener переопределен в текущем классе, а нам нужно обратиться к addEventListener именно суперкласса до вызова его конструктора. Что делать? Нужно всего лишь вынести это обращение в другой метод. Компилятор не будет копать так глубоко, а интерпретатору, честно говоря, пофиг.
Код AS3:
public function Constructor(){
someMethod();
super();
}
private function someMethod():void{
super.addEventListener(...);
}
3) Отмена инкапсуляции.
Это нельзя отнести к глупостям или странностям, но меня это забавляет.
Вот такой вот метод:
Код AS3:
public function getEverything(name:String):*{
return this[name];
}
позволит достать из класса всё что угодно. Однако, что радует, приватные поля суперкласса таким образом заполучить не удастся.

4) Нет уверенности в завтрашнем дне, мы меняем константу.
Константы это то, что нельзя изменить. Важно понимать разницу между изменить и "залезть внутрь".
Например, массив-константа:
Код AS3:
public static const ARRAY:Array = [];
может наполняться содержимым с помощью метода push класса Array, но не может быть заменен другим массивом. (я не могу написать ARRAY=[1,2,3]).
Теперь давайте объявим не-статическую константу:
Код AS3:
private const obj:String="10";
Попробовав её изменить мы получим ошибку компиляции. Это нормально. Но давайте не забывать о том, что у нас есть динамический доступ: меняем константу вот так:
Код AS3:
this["obj"]=30;
и... вуаля.
Но, что странно, если константа помечена как static — во время её изменения мы, слава богу, получим RTE.

5) Интересный интеллект компилятора
Я не знаю, как назвать этот пункт. Наверное, ни для кого не секрет, что FlexSDK как компилятор имеет достаточно низкий порог оптимизаций: во время компиляций он не складывает даже константы!
Вот такой вот код:
Код AS3:
var a:int=5+5+10;
попадет в байт-код именно как 5+5+10. Хотя, хотелось бы, чтобы он попал туда как 20.
Но... услужливый компилятор скажет, что через ссылку на класс, которую я присвою в рантайме идёт динамическое обращение к константе (!!!).
Между слов, проще выразить это в коде (Класс Main):
Код AS3:
private static const obj:String="5";
...
var cl:Class = Main;
var cl2:Class = cl;
cl2.obj = "30";
Причина отказа в компиляции: Error: Illegal assignment to a variable specified as constant.
Офигеть.
Всего комментариев 25

Комментарии

Старый 10.05.2011 02:55 Котяра вне форума
Котяра
 
Аватар для Котяра
Про множественный вызов суперконструктора прикольно. Копай ещё.
А отмена инкапсуляции похожа на антипаттерн Public Morozov
Старый 10.05.2011 05:12 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
про константу и Array не в тему. это абсолютно нормальное поведение. свойства массива же не помечены как константа.
Старый 10.05.2011 12:15 Zebestov вне форума
Zebestov
 
Аватар для Zebestov
Вроде про Array сказано так, к слову. А вот константа как раз помечена как константа, но ее можно изменить через this[] — не особо как-то нормально.
Старый 10.05.2011 16:12 incvizitor вне форума
incvizitor
 
Аватар для incvizitor
Ага, а еще в AS3 методы тоже могут быть динамическими:

Код AS3:
public dynamic function foo() {
	trace("Ы");
}
И компилятор даже ни намекает на ошибку.
Старый 10.05.2011 17:05 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
это косяки последнего компилятора. раньше он палил это. сейчас dynamic перестал быть стронг кейворд.
Старый 10.05.2011 17:57 Волгоградец вне форума
Волгоградец
 
Аватар для Волгоградец
Я что-то последний пример не пойму - это типа тоже 'косяки компилятора/интерпретатора'??
Старый 10.05.2011 19:50 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Нет, это забавляха от компилятора, умный настолько, что при компиляции видит достаточно сложную ошибку, но и настолько же глупый, что не может во время компиляции сделать элементарные арифметические преобразования.

@BlooD, да, было сказано вскольз. Меня могут читать совсем молодые девелоперы )
Старый 10.05.2011 20:57 i.o. вне форума
i.o.
 
Аватар для i.o.
чО-то не понял.. Типа по-идее у "динамического метода" могут быть свои свойства?
типа так?:
Код AS3:
foo["myProp"] = "Lalala";
foo.myPropA = "Lalala2";
проверять в лом
Старый 10.05.2011 21:40 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Нет, сказали же, это тупо баг компилятора )
Старый 11.05.2011 01:20 alatar вне форума
alatar
 
Аватар для alatar
Цитата:
Отмена инкапсуляции.
В чем собственно отмена? Объект сам, как Павлик Морозов, сдает свое нутро.
Обновил(-а) alatar 11.05.2011 в 01:28
Старый 11.05.2011 16:29 chabapok вне форума
chabapok
а собственно, ну и что?
ну работает оно так. Но это же редкие случаи.
Никому никогда в голову не приходило так делать, и смысла в этих примерах мало. И даже если это исправят, от этого станция в фукусиме и коррупция в кремле не исчезнут, образно говоря.
Старый 11.05.2011 17:54 Котяра вне форума
Котяра
 
Аватар для Котяра
Ну как бы это пост и не претендовал на открытие Истины.
2 alatar. на самом деле это не совсем павлик морозов, ибо родительское приватное он всё-таки отдать не может, только протектед, поэтому полностью реализовать Public Morozov в AS3, к счастью, не получится.
Обновил(-а) Котяра 11.05.2011 в 17:57
Старый 11.05.2011 19:35 alatar вне форума
alatar
 
Аватар для alatar
2 Котяра, я об этом и говорил. Нет там никакой отмены инкапсуляции. Абсолютно логичное и ожидаемое поведение. В полном соответствии с ООП.
Старый 11.05.2011 19:52 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Тебе конкретно название не нравится?
Старый 12.05.2011 02:12 alatar вне форума
alatar
 
Аватар для alatar
Аха
Старый 12.05.2011 17:52 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Предложи своё название для этого трюка )
Старый 12.05.2011 18:34 alatar вне форума
alatar
 
Аватар для alatar
ООП Там нет никакого трюка. Точно так же можно отдать свои приватные переменные.
Старый 12.05.2011 19:00 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Я ещё в самой статье сказал, что это вполне нормальное поведение. Трюками я называю интересные штуки, которые можно сделать из ожидаемого поведения. Неожидаемые поведения я называю тонкостью.
Старый 13.05.2011 13:17 Rzer вне форума
Rzer
 
Аватар для Rzer
Цитата:
И вытворял он эти трюки, пока не стал страдать тонкостью
Как жизненно.
Старый 15.11.2011 22:11 PainKiller вне форума
PainKiller
 
Аватар для PainKiller
множественный вызов конструктора это просто класс - не знаю где это можно применить, но на заметку возьму :-) Спасибо за подборку, восхитило!
Старый 21.11.2011 14:45 kackbip вне форума
kackbip
 
Аватар для kackbip
Код AS3:
private const obj:String="10";
Код AS3:
this["obj"]=30;
Даже тип сменила? Ахренеть.
Старый 21.11.2011 15:31 in4core вне форума
in4core
 
Аватар для in4core
про тип это очепятка
Старый 21.11.2011 19:51 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Нет, не опечатка.
При подобном присвоении компилятор не может проверить присвоение во время компиляции, и это отдается на откуп интерпретатору, который решает лучшим решением просто дёрнуть toString.
Код AS3:
this["obj"]=new Sprite();
trace(this["obj"]); //[object Sprite], но это строка, а не спрайт
Старый 22.11.2011 02:47 Котяра вне форума
Котяра
 
Аватар для Котяра
Цитата:
Трюками я называю интересные штуки, которые можно сделать из ожидаемого поведения. Неожидаемые поведения я называю тонкостью.
Обычно наоборот. Тонкость, это вроде как и из обычного поведения, но есть нюанс.
А трюки и хаки - это нечто недокументированное либо хитрое следствие из, хоть и документированного, но не очевидного.
Старый 22.11.2011 10:13 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
По разному можно, не считаю за суть )

П.с. Первый пост на флешер с айфони
 

 


Часовой пояс GMT +4, время: 03:39.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.