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

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

Оценить эту запись

Меняем константы где захотим.

Запись от Aquahawk размещена 21.03.2012 в 04:05

Немного магии рантайма.
Иллюстрация того что можно менять константы объекта. Их менять можно только в конструкторе. Но вот ссылку на конструктор можно сохранить. И получить немного магии.
Ловкость рук и никакого мошенничества. Код валиден и не генерирует варнингов в строгом режиме компиляци.
Код AS3:
package {
	import flash.display.Sprite;
 
	public class Main extends Sprite {
		public function Main():void {
			var test:ConstTest = new ConstTest(15); 
			trace(test.constValue);
			test.setConstValue(10); // some magic :)
			trace(test.constValue);
			test.setConstValue(20);
			trace(test.constValue);
		}
	}
}
Код AS3:
package {
	public class ConstTest extends ConstTestBase {
		private var _construcorMethod:Function;
		private var _inited:Boolean = false;
		private var _tempValue:int = 0;
		public const constValue:int = 0;
 
		public function ConstTest(someParam:int = 0) { // Можем юзать любые параметры. Но обязательно задать значение по умолчанию
			if (!this._inited) {
				super(); //NOTE: ОБЯЗАТЕЛЬНО. иначе компилятор сам добавить вызов конструктора предка выше и он будет вызываться много раз.
				this._construcorMethod = arguments.callee;
				this._inited = true;
				// обычный код коструктора который нам нужен
				trace("ConstTest constructed, param:",someParam);
			}
			else {
				this["constValue"] = this._tempValue; //NOTE: в строгом режиме компиляци явно менять константы нельзя вообще, поэтому перенесём резолвинг в рантайм.
			}
		}
 
		public function setConstValue(value:int):void {
			this._tempValue = value;
			this._construcorMethod();
		}
	}
}
Код AS3:
package {
	public class ConstTestBase {
		public function ConstTestBase() {
			trace("ConstTestBase constructed"); // Это чтоб показать что конструктор предка вызывается корректно
		}
	}
}
На выводе имем
Код:
ConstTestBase constructed
ConstTest constructed, param: 15
0
10
20
Проект FD
Всего комментариев 15

Комментарии

Старый 21.03.2012 13:12 Aquahawk вне форума
Aquahawk
 
Аватар для Aquahawk
Менять подобным образом статические константы уже не получится. Пробовал. Там конечно ссылку на cinit получить у меня не получилось. Точнее я не могу написать as3 код который мне её вернёт. В байткоде есть мысли как это можно сделать, как нибудь потом поробую. Это раз. Второе, это то, что для статик констант даже в сините нельзя присвоить значение несколько раз, так что даже если и удастся получить ссылку на cinit, менять статик константы не получится.
Старый 21.03.2012 15:36 BuKT вне форума
BuKT
 
Аватар для BuKT
А где вообще применимы константы, где неприменимы геттеры?
Да, и какой толк менять константу пользовательского класса? Вот если бы можно было взять произвольный класс, расширить его, получить super() и так далее..
Старый 21.03.2012 15:40 КорДум вне форума
КорДум
 
Аватар для КорДум
Мне кажется, автор просто показал, что есть и как можно сделать. А-ля идиотизмы Блуда.
Старый 21.03.2012 16:01 Aquahawk вне форума
Aquahawk
 
Аватар для Aquahawk
Цитата:
Мне кажется, автор просто показал, что есть и как можно сделать. А-ля идиотизмы Блуда.
Истинно так. Я никогда не применял это нигде. Просто придумал что так можно делать. Где-то в доках увидел что константы можно править в конструкторе. Ещё слышал утверждение что в as3 не констант уровня объекта и знакомые плюсовики говорили что это плохо. Вот показал что таковые константы есть. Правда не совсем константы.

Цитата:
Вот если бы можно было взять произвольный класс, расширить его, получить super() и так далее..
а в байткоде есть такая инструкция constructsuper называется. Именно в неё компилятор превращает super() в конструкторе. Так вот её можно звать откуда угодно, с любого метода, и это работает. Правда только в байткоде. Я не знаю как написать такую конструкцию на as3 вне конструктора которая после компиляции в даст вызов суперконструктора. "И так далее ..." уже сложности. От возможности вызывать конструктор предка возможности менять его константы у нас не появится.

Тут другой вопрос в том что константы объекта они не статические, и соответственно наследуются. Однако изменить их значения из конструктора наследника не дают. Проверил.
Обновил(-а) Aquahawk 21.03.2012 в 16:04
Старый 21.03.2012 16:06 Aquahawk вне форума
Aquahawk
 
Аватар для Aquahawk
На самом деле я просто увидел http://jacksondunstan.com/articles/1774 и был возмущён тем что там написано. Откомментил ему и решил до кучи сюда написать. А придумал я это ещё осенью в качестве разминки для мозгов.

Цитата:
А где вообще применимы константы, где неприменимы геттеры?
Вообще суть константы это показать что это константа и она никогда не будет меняться. Её например кешировать можно или ещё что-нибудь. Геттеры это немного другое. Константа как бы говорит программисту который смотрит на такой код что меняться эта константа не будет. Другой вопрос что в as3 как таковых констант нет а есть то что в плюсах называют константным указателем. Т.к. объект в константе может менять свои свойства, но не может быть пересоздан.
Обновил(-а) Aquahawk 21.03.2012 в 16:09
Старый 21.03.2012 17:50 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Старый 21.03.2012 18:01 Aquahawk вне форума
Aquahawk
 
Аватар для Aquahawk
Тигра. Так как у тебя написано можно делать только в конструкторе. Я читал этот пост давно когда-то. Это даже в доке написано, только малясь кривовато. Тут вся фишка в том что потом, после создания объекта можно будет изменить его константу.
Старый 21.03.2012 18:22 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Мне твой трюк с сохранением конструктора понравился, кстати.
Старый 21.03.2012 18:29 Aquahawk вне форума
Aquahawk
 
Аватар для Aquahawk
Аналогичным образом можно и на сеттеры и на геттеры ссылку получить.
Старый 24.03.2012 16:28 dimarik вне форума
dimarik
 
Аватар для dimarik
оч круто! респект.
Конструктор можно проще получить. this.constructor
Старый 24.03.2012 23:17 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
ну ваще это не магия, а запланированная фича. всё работает по спеке ES. даже синтаксис специальный для этого есть, но увы компилятор у нас не такой умный как положено.
Старый 25.03.2012 00:29 Aquahawk вне форума
Aquahawk
 
Аватар для Aquahawk
Цитата:
всё работает по спеке ES.
Я собственно прочитав спеку ES и AVM это и придумал, а решил поведать людям, когда jacksondunstan написал неправду.
dimarik
Код AS3:
trace(this["constructor"]);
Неправду говорите. Будет:
Код:
[class Main]
В данном случае там класс инстансом которого является данный объект.
Это в джаваскрипте так будет, как вы сказали(правда там классов то нет как таковых). Или в AS если вы создадите объект как new someFunction(), которая возвращает что-то. Вот тогда этому объекту(динамическому) будет приписана эта функция в свойство конструктор. Ещё точно можно определить такой геттер у не динамического класса, и можно просто переписать это свойство у динамического. Создавать у не динамического поле с таким именем я не пробовал.
Старый 25.03.2012 00:48 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
Цитата:
Я собственно прочитав спеку ES и AVM это и придумал, а решил поведать людям, когда jacksondunstan написал неправду.
у него в последнее время всё не правда. а ещё ему начали нравится тесты, в которых он сравнивает мух с травой.

Цитата:
Это в джаваскрипте так будет, как вы сказали(правда там классов то нет как таковых).
заблуждение. классы там есть. просто они выглядят не так как в АС3. ещё так же будет в АС1/2. связано это с тем, что там конструктор и класс являются ссылками на один и тот же объект.
Старый 25.03.2012 00:56 Aquahawk вне форума
Aquahawk
 
Аватар для Aquahawk
Не буду спорить о классах. В том смысле в котором классы понимаются в Java, C++, C#, AS3 в javaScript их нет. Есть прототипное наследование. Есть объектная модель. Но я не могу назвать это классами. Возможно это изъян моей личной терминологии.
Старый 05.04.2012 23:54 Aquahawk вне форума
Aquahawk
 
Аватар для Aquahawk
Увидел тут. Иногда могут возникнуть проблемы. Если кроме констант в классе есть поля или константы сложных типов, для которых заданы значения по умолчанию. Создание этих объектов и присвоение будет производиться в коде конструктора перед всем тем кодом который написал юзер. И в таком случае при повторном вызове конструктора произойдёт повторная инициализация полей.
 

 


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


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