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

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

обо всем по-немногу...
Оценить эту запись

UnsecurityDisplayLoader - обертка для несекьюрной загрузки дисплей контента

Запись от cleptoman размещена 12.02.2011 в 12:28
Обновил(-а) cleptoman 14.02.2011 в 08:58

Итак. Понадобилось в очередной раз "обмануть систему" и получить доступ к контенту, к которому с классическим подходом оного не дают. Т.е. нет возможности залить crossdomain.xml, а картинки на сервере страсть какие красивые.

Небольшое отступление:
Я, ни в коем случае, не пропагандирую использование контента без ведома владельца.Необходимо помнить, что у любого контента в сети есть владелец и есть законодательство РФ. Пусть оно и хромое, но тем не менее.

В дебаг-плеере, где безопасность игнорируется мы можем достучаться к любому контенту, который нам нужен. пробуем:

Код AS3:
var loadeer:Loader			= new Loader();
loadeer.contentLoaderInfo.addEventListener(Event.INIT, _handler);
loadeer.load(new URLRequest("http://img.yandex.net/i/www/logo.png")) //  надеюсь яндекс не обидится. я их лого использую для обучающих/ознакомительных целей, а не коммерческих.
 
function _handler(e:Event):void{
trace(e.target.loader.content); // [object Bitmap]
}
Ага, все работает. отлично. пробуем закинуть нашу незамысловатую SWF на хост и повторить процедуру. залили, открываем флэшку. Дебаг плагин нам выносит вердикт.

Цитата:
SecurityError: Error #2122: Нарушение изолированной среды: Loader.content: http://cleptoman.ru/test/dr.swf не может осуществить доступ к http://img.yandex.net/i/www/logo.png. Необходим файл политики, но, когда были загружены эти мультимедийные данные, флаг checkPolicyFile не был установлен.
Флаг ставить мы не будем. потому что точно знаем, что яндекс забыл внести наш домен в список разрешенных в свой кроссдомен (да, да, и такое бывает).

Ну что же, пора немного покурить интернеты. Долго курить не приходится, потому что вспомнил, что на флэшере Димарик проводил изыскания на эту тему, за что ему огромная благодарность и бронзовый памятник.)
Вдохновившись прочтенным закрадывается мыслишка накидать класс-обертку над лоадером для реализации идеи.

собсно продукт:

Код AS3:
package ru.cleptoman.net {
	import flash.display.MovieClip;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;
 
	[Event(name = "open", type = "flash.events.Event.OPEN")]
	[Event(name = "complete", type = "flash.events.Event.COMPLETE")]
	[Event(name = "init", type = "flash.events.Event.INIT")]
	[Event(name = "progress", type = "flash.events.ProgressEvent.PROGRESS")]
	[Event(name = "securityError", type = "flash.events.SecurityErrorEvent.SECURITY_ERROR")]
	[Event(name = "ioError", type = "flash.events.IOErrorEvent.IO_ERROR")]
 
	/**
	 * @langversion 	Action Script 3.0
	 * @see				http://cleptoman.free-lance.ru
	 * @author 			Kutov Aleksey aka cleptoman
	 * @version 		0.02
	 * @playerversion	9
	 * Класс-надстройка над Loader. Предназначен для загрузки медийного контента форматов JPEG,GIF,PNG,SWF при необходимости игнорируя политику безопасности Flash Player.
	 */
	public class UnsecurityDisplayLoader extends EventDispatcher{
 
		protected var _loader:Loader;
		protected var _parameters:Object;
		protected var _loading:Boolean;
		protected var _isAfterFirstError:Boolean;
		protected var _content:DisplayObject;
		protected var _extractor:IContentExtractor;
 
		public function UnsecurityDisplayLoader() {
			super();
		}
 
		private function _create():void {
			_loader						= new Loader();
			_configHandlers();
		}
 
		private function _removeHandlers():void {
			var li:LoaderInfo			= _loader.contentLoaderInfo;
			li.removeEventListener(Event.COMPLETE, _onHandler);
			li.removeEventListener(Event.INIT, _onHandler);
			li.removeEventListener(ProgressEvent.PROGRESS, _onHandler);
			li.removeEventListener(Event.OPEN, _onHandler);
			li.removeEventListener(IOErrorEvent.IO_ERROR, _onHandler);
			li.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, _onHandler);
		}
 
		private function _configHandlers():void {
			var li:LoaderInfo			= _loader.contentLoaderInfo;
			li.addEventListener(Event.COMPLETE, _onHandler);
			li.addEventListener(Event.INIT, _onHandler);
			li.addEventListener(ProgressEvent.PROGRESS, _onHandler);
			li.addEventListener(Event.OPEN, _onHandler);
			li.addEventListener(IOErrorEvent.IO_ERROR, _onHandler);
			li.addEventListener(SecurityErrorEvent.SECURITY_ERROR, _onHandler);
		}
 
		private function _skipLoad():void {
			if (_loader && _loading) {
				_loader.close();
			}
			_extractor					= null;
			_content					= null;
			_isAfterFirstError			= false;
			_parameters					= null;
			_loading					= false;
		}
 
		/**
		 * Пробуем достучаться до content у LoaderInfo. если не получается, то грузим байты методом loadBytes. Пробуем еще раз. если не получается, то думаем,что делать дальше с ексепшном )
		 * @param	e
		 */
 
		private function _onHandler(e:Event):void {
			if (e.type === Event.INIT) {
				if (_isAfterFirstError) {
					_content			= _extractor.extract(_loader.content);
					_isAfterFirstError			= false;
				}else{
					try{
						_content		= _loader.content;
					}catch (err:SecurityError) {
						_extractor				= (_loader.contentLoaderInfo.contentType.substring(0,5) === "image") ? new BitmapExtractor() : new MovieClipExtractor();
						_isAfterFirstError		= true;
						_loader.loadBytes(_loader.contentLoaderInfo.bytes);
						e.stopPropagation();
						return;
					}
					_parameters		= _loader.contentLoaderInfo.parameters;
				}
				_loading					= false;
			}
 
			if (e.type === ProgressEvent.PROGRESS && _isAfterFirstError) {
				return;
			}
			super.dispatchEvent(e);
		}
 
		public override function dispatchEvent (event:Event) : Boolean {
			throw new Error("Класс не реализует данный метод");
		}
 
		/**
		 * @return Возвращает последний объект, переданный в URLReqest#data в метод load. Не равен content.loaderInfo.parameters, если загрузка прошла игнорируя безопасность.
		 */
 
		public function get parameters():Object { return _parameters; }
 
 
		/**
		 * @return Возвращает медийный контент. Если загрузка произошла игнорируя политику безопасности, то content.loaderInfo.contentType для объектов будет application/x-shockwave-flash, а не image/jpeg.
		 */
		public function get content():DisplayObject { 
			return _content; 
		}
		/**
		 * @return Возвращает состояние: происходит загрузка в данный момент или нет.
		 */
		public function get loading():Boolean { return _loading; }
 
		public function load(request:URLRequest,context:LoaderContext = null):void {
			_skipLoad();
			if (!_loader) {
				_create();
			}
 
			_parameters				= request.data;
			_loader.load(request,context);
			_loading				= true;
		}
		public function loadBytes(bytes:ByteArray):void {
			_skipLoad();
			if (!_loader) {
				_create();
			}
			_parameters				= _loader.contentLoaderInfo.parameters;
			_loader.loadBytes(bytes);
			_loading				= true;
		}
		public function unload():void {
			_skipLoad();
			if(_loader){
				_loader.unload();
			}
		}
		public function unloadAndStop(gc:Boolean = true):void {
			_skipLoad();
			if(_loader){
				_loader.unloadAndStop(gc);
			}
		}
		public function close():void {
			_skipLoad();
		}
 
		/**
		 * Удаляет внутренние ссылки на используемые объекты. сохраните ссылку на полученный в ходе загрузки content перед вызовом метода
		 */
		public function destroy():void {
			if (_loader) {
				_skipLoad();
				_removeHandlers();
				_loader				= null;
			}
		}
 
 
	}
 
}
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
interface IContentExtractor {
	function extract(content:DisplayObject):DisplayObject;
}
class BitmapExtractor implements IContentExtractor {
	public function extract(content:DisplayObject):DisplayObject {
		return (content as DisplayObjectContainer).getChildAt(0);
	}
}
class MovieClipExtractor implements IContentExtractor {
	public function extract(content:DisplayObject):DisplayObject {
		return content;
	}
}
пример применения:
Код AS3:
package {
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.net.URLRequest;
	import ru.cleptoman.net.UnsecurityDisplayLoader;
 
 
 
	/**
	 * ...
	 * @author Kutov Aleksey aka cleptoman
	 */
	public class Main extends Sprite {
 
		public function Main():void {
			if (stage) init();
			else stage.addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void {
			super.removeEventListener(Event.ADDED_TO_STAGE, init);
 
			var loader:UnsecurityDisplayLoader = new UnsecurityDisplayLoader();
			loader.addEventListener(Event.INIT, _onComplete);
			var req:URLRequest		= new URLRequest("http://img.yandex.net/i/www/logo.png");
			loader.load(req);
 
		}
 
		private function _onComplete(e:Event):void {
			var loader:UnsecurityDisplayLoader = e.target as UnsecurityDisplayLoader;
			this.addChild(new Bitmap((loader.content as Bitmap).bitmapData));
 
		}
 
	}
 
}
ну и линк, где можно посмотреть

класс особо в коментариях не нуждается. основной интерес, возможно, представляет метод _onHandler, обработчик событий.

Код AS3:
private function _onHandler(e:Event):void {
	if (e.type === Event.INIT) {
		if (_isAfterFirstError) {
			_content			= _extractor.extract(_loader.content);
			_isAfterFirstError			= false;
		}else{
			try{
				_content		= _loader.content;
			}catch (err:SecurityError) {
				_extractor				= (_loader.contentLoaderInfo.contentType.substring(0,5) === "image") ? new BitmapExtractor() : new MovieClipExtractor();
				_isAfterFirstError		= true;
				_loader.loadBytes(_loader.contentLoaderInfo.bytes);
				e.stopPropagation();
				return;
			}
			_parameters		= _loader.contentLoaderInfo.parameters;
		}
		_loading					= false;
	}
 
	if (e.type === ProgressEvent.PROGRESS && _isAfterFirstError) {
		return;
	}
	super.dispatchEvent(e);
}

Итак:

По событию INIT смотрим флаг _isAfterFirstError. если он false, значит ошибок безопасности еще не было, отработает блок else. Тут интересней. Как упоминалось выше в примере, в случае нарушения изолированной среды нам выкинет SecurityError.
Это и используем. если выполнился блок try - дальше все идет по плану. Если нет, то отработает catch блок: выставит флаг _isAfterFirstError в true и попробует загрузить полученные байты (благо лоадерИнфо нам их оставил, за что ему и спасибо).
Интересный момент с конвертацией из Bitmap в MovieClip при загрузке байтов картинки. Он описан в вдохновении. Я , исходя из contentType выбираю нужное поведение, которое будет работать чуть ниже.
Еще один интересный момент заключается в том, что, если убрать строку e.stopPropagation();, то каким то неведомым образом INIT редиспатчится выше, где в обработчике пытаюсь взять контент, которого еще и получаю фейл. Если кому-то будет не лень покурить этот момент - будет супер.
Теперь при следующем INIT с нашим флагом _isAfterFirstError == true мы используем экземпляр _extractor, выбраный чуть выше.

Свойство parameters в случае с несекьюрной загрузкой будет просто хранилищем параметров, переданных в метод load и никакого отношения к LoaderInfo#parameters иметь не будет. Эдакий легализованный вагон с гестарбайтерами в составе поезда ФМС ). потому тут надо быть аккуратным или попросту удалить это свойство.
Собственно, полезность метода loadBytes тоже под вопросом.

Вот и все.

Выражаю благодарности dimarik за идею и Psycho Tiger за предварительную рецензию).

Если кому пригодится - хорошо. Не пригодится - значит название моего блога выбрано удачно ).

п.с. Ага, сбаянил)
Вложения
Тип файла: zip _dr.zip (65.5 Кб, 187 просмотров)
Всего комментариев 70

Комментарии

Старый 12.02.2011 20:48 etc вне форума
etc
 
Аватар для etc
Старый 14.02.2011 04:15 mayakwd вне форума
mayakwd
 
Аватар для mayakwd
За злоупотребление "_" хочется дать по рукам.
Старый 14.02.2011 11:08 cleptoman вне форума
cleptoman
 
Аватар для cleptoman
Денис, да, получается я изобретаю велосипеды )

Илья, а где злоупотребление? приватные и протектед всегда с "_"..а вообще, это ты достал очередной топор для холивара )
Старый 14.02.2011 11:46 3p.station вне форума
3p.station
 
Аватар для 3p.station
спасибо, очень интересно!
Старый 14.02.2011 13:20 in4core вне форума
in4core
 
Аватар для in4core
Код AS3:
if (e.type === Event.INIT) {
		if (_isAfterFirstError) {
			_content			= _extractor.extract(_loader.content);
			_isAfterFirstError			= false;
		}else{
			try{
				_content		= _loader.content;
			}catch (err:SecurityError) {
				_extractor				= (_loader.contentLoaderInfo.contentType.substring(0,5) === "image") ? new BitmapExtractor() : new MovieClipExtractor();
				_isAfterFirstError		= true;
				_loader.loadBytes(_loader.contentLoaderInfo.bytes);
				e.stopPropagation();
				return;
			}
			_parameters		= _loader.contentLoaderInfo.parameters;
		}
		_loading					= false;
Такую табуляцию невозможно читать вообще
Старый 14.02.2011 14:06 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
in4core, а как правильно?
Старый 14.02.2011 14:07 alatar вне форума
alatar
 
Аватар для alatar
Цитата:
В дебаг-плеере, где безопасность игнорируется мы можем достучаться к любому контенту, который нам нужен.
Дебаг-плеер не игнорирует политику безопасности. Это не от версии плеера зависит.
Старый 14.02.2011 15:06 in4core вне форума
in4core
 
Аватар для in4core
Причем тут как правильно, мне лично глаза ломает запись a _______________________________ = 10 я должен глазами бегать в лево и в право. Как минимум посмотреть как адобовцы пишут, я не спорю, что каждый пишет по своему, но я высказал мнение, что мне лично такой код читать не хочется
Старый 14.02.2011 15:22 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Ну вообще-то только на форуме ломается. В IDE красиво в столбик.
Старый 14.02.2011 15:56 cleptoman вне форума
cleptoman
 
Аватар для cleptoman
Цитата:
такой код читать не хочется
in4core, ну я переживу)
Старый 14.02.2011 15:57 cleptoman вне форума
cleptoman
 
Аватар для cleptoman
alatar, спасибо, что поправил..имелось ввиду дебаг сессия в ИДЕ
Старый 15.02.2011 01:45 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
cleptoman, при выкладывании подобного кода на форум переводите табы в пробелы. тогда ничего не сломается.
Старый 15.02.2011 10:23 zuxul вне форума
zuxul
Еще, есть одно маленькое правило, которое помогает не ломать восприятие кода в любых редакторах - использовать табуляцию только в началах строк. (если же нужно выровнять что-то - нужно использовать пробелы).
Старый 15.02.2011 11:22 etc вне форума
etc
 
Аватар для etc
mayakwd, скорее уже тогда за отсутствие this. И вообще, не понимаю, зачем там protected. А вот за методы с подчеркиваем — да, обязательно по рукам.
Старый 15.02.2011 12:05 cleptoman вне форума
cleptoman
 
Аватар для cleptoman
топик получился про "правописание")
спасибо за содержательные посты.
Старый 15.02.2011 16:34 in4core вне форума
in4core
 
Аватар для in4core
Код AS3:
public override function dispatchEvent (event:Event) : Boolean {
			throw new Error("Класс не реализует данный метод");
		}
 
		/**
		 * @return Возвращает последний объект, переданный в URLReqest#data в метод load. Не равен content.loaderInfo.parameters, если загрузка прошла игнорируя безопасность.
		 */
А где сам ретурн ? И у вас компилятор не ругается на такую порнографию ? Или это специально для поста убрали
Старый 15.02.2011 16:40 КорДум вне форума
КорДум
 
Аватар для КорДум
in4core, этот комментарий расположен под методом и относится к методу ниже. А он-то return имеет.
Старый 15.02.2011 16:48 cleptoman вне форума
cleptoman
 
Аватар для cleptoman
я даже не знаю что ответить...нет, компилятор не ругается.
Старый 15.02.2011 16:49 cleptoman вне форума
cleptoman
 
Аватар для cleptoman
КорДум, он про dispatchEvent, видимо
Старый 15.02.2011 17:36 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Кстати действительно интересно, почему не ругается.
Старый 15.02.2011 17:39 gloomyBrain вне форума
gloomyBrain
 
Аватар для gloomyBrain
Потому что выход из метода возможен двумя путями - либо по return, либо по throw (кстати, throw можно применять к любому объекту, не только к ошибке или исключению)
Старый 15.02.2011 18:24 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Понятно, спасибо.
Старый 19.02.2011 02:17 expl вне форума
expl
Цитата:
За злоупотребление "_" хочется дать по рукам.
В чужой монастырь со своим уставом? Мне например за this перед каждым полем хочется бить очень сильно, дальше что.

2 cleptoman:
Цитата:
Код AS3:
return (content as DisplayObjectContainer).getChildAt(0)
Это таким образом получилось достать Bitmap, а BitmapData из нее удачно достается?
Т.е., чтобы получить битмапу, стадию
Код AS3:
     var bd:BitmapData = new BitmapData(....
     bd.draw(content)
можно пропустить?

P.S. Стратегии IContentExtractor влепленные в класс на ровном месте весьма доставили
Обновил(-а) expl 19.02.2011 в 02:36
Старый 19.02.2011 04:29 Котяра вне форума
Котяра
 
Аватар для Котяра
На тему суперов.
Код AS3:
super.dispatchEvent(e);
вот смотри. я расширяю класс и хочу залогировать все отправляемые эвенты.
я переопределяю dispatchEvent
Код AS3:
override public function dispatchEvent(e:Event)
{
trace(e);
super.dispatchEvent(e);
}
Но что такое! Не работает!
_onHandler вызывает метод родителя, а не свой.
В чём умысел?
Старый 19.02.2011 08:39 cleptoman вне форума
cleptoman
 
Аватар для cleptoman
свой после переопределения не должен ничо коме эксепшна кидать. может я где чего не докурил, но так задумывалось.
больше интересен момент:
Цитата:
Еще один интересный момент заключается в том, что, если убрать строку e.stopPropagation();, то каким то неведомым образом INIT редиспатчится выше, где в обработчике пытаюсь взять контент, которого еще и получаю фейл.
Обновил(-а) cleptoman 19.02.2011 в 08:52
Старый 19.02.2011 08:40 cleptoman вне форума
cleptoman
 
Аватар для cleptoman
@expl, да достается. да, можно пропустить. да, в примере есть)

Код AS3:
this.addChild(new Bitmap((loader.content as Bitmap).bitmapData));
со стратегиями - да, возможно, перегиб. еще одного флага достаточно было бы.
Обновил(-а) cleptoman 19.02.2011 в 08:49
Старый 19.02.2011 14:10 expl вне форума
expl
Цитата:
@expl, да достается. да, можно пропустить. да, в примере есть)
Олично, надо будет выкинуть эту стадию из своего костыля.
Старый 21.02.2011 23:33 dimarik вне форума
dimarik
 
Аватар для dimarik
dimarik тоже внимательно наблюдает за комментариями к статье.

Цитата:
Сообщение от gloomyBrain
Потому что выход из метода возможен двумя путями - либо по return, либо по throw
Вот про throw, который возвращает null расскажите подробнее, пожалуйста.

Сама статья не очень свежа.
Старый 22.02.2011 00:32 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
димка, throw ничего не может возвращать ) но выкидывать null он может. я так сам делаю.
Старый 22.02.2011 01:17 dimarik вне форума
dimarik
 
Аватар для dimarik
Ээээ. Получается, что после нажатия кнопки "продолжить" в окошке, выброшенном дебаг-плеером, метод, возвращающий что-нибудь возвратит null?
Старый 22.02.2011 01:59 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
я ещё раз повторю. он ничего не вернёт. в лучшем случае undefined. но он ничего не вернёт. throw != return;
Старый 22.02.2011 04:01 in4core вне форума
in4core
 
Аватар для in4core
тут фишка впринципе понятна, не пробовал могу ошибаться, но поидее

Код AS3:
function test() {
 throw new Error('someerror')
 trace('ok')
}
Дальше throw не пойдет. и трейса мы не увидим. Тоесть в нашем случае
Код AS3:
throw new Error == return;
Да и кстати, даже

Код AS3:
function test():void {
  trace('ok');
}
Имеет свой return который наглядно ничего не вернет. но завершает функцию по окончанию чтения строк или выводу ошибки. В итоге void это тоже возвращаемая величина )))
Обновил(-а) in4core 22.02.2011 в 04:06
Старый 22.02.2011 04:22 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
@in4core, ну вот опять ересь какая-то.
по вашему throw поднимется только уровень выше? какой же это return?
если уж вы зацепили void, то открою вам тайну: void - не "величина", и уж тем более не "возвращаемая". void - специальный тип данных, который содержит единственное значение undefined. исходя из простых сведений мы можем заключить что любой метод "наглядно" возвращает значение. но удобнее опускать данное значение, и считать, что метод ничего не возвращает, так как undefined - и есть "ничего".
Старый 22.02.2011 11:09 dimarik вне форума
dimarik
 
Аватар для dimarik
Я понял. По throw просто прерывается исполнение кода. Ничего никуда не возвращается. Всем спасибо,
Старый 22.02.2011 12:31 in4core вне форума
in4core
 
Аватар для in4core
@BlooDHounD я все верно написал.

Код AS3:
по вашему throw поднимется только уровень выше? какой же это return?
Такой же, а причем тут уровень выше непонятно. я такого не говорил.

Код AS3:
function test() {
 trace('1');
 trace('2');
 throw new Error('someerror')
 trace('ok')
}
 
function test() {
 trace('1');
 trace('2');
 return;
 trace('ok')
}
Одинаково, разница лишь в том , что компилятор отдаст ошибку в 1 случае.
Цитата:
void - не "величина", и уж тем более не "возвращаемая". void - специальный тип данных, который содержит единственное значение undefined.
Вы протеворечите сами себе. void типа данных, а Undefined значение, значение возвращается.
int тип данных а 555 значение.... безсмысленный разговор.
Если хотите указать на ошибки, милости просим, но вот спам разводить не стоит
Обновил(-а) in4core 22.02.2011 в 12:40
Старый 22.02.2011 12:56 gloomyBrain вне форума
gloomyBrain
 
Аватар для gloomyBrain
Цитата:
Одинаково, разница лишь в том , что компилятор отдаст ошибку в 1 случае
Для компилятора throw не является ошибкой.

Цитата:
Вы протеворечите сами себе. void типа данных, а Undefined значение, значение возвращается
Код AS3:
private function returnVoid():void {
	// nothing here
}
...
 
trace(this.returnVoid()); // undefined
Так а где тут противоречия? Их тут нет.
Соответственно, вот это Ваше высказывание неверно:
Цитата:
В итоге void это тоже возвращаемая величина
Старый 22.02.2011 13:17 arkadattx вне форума
arkadattx
Код AS3:
trace(test());
	trace(4);
 
		private function test():int {
			trace(1);
			trace(2);
			throw new Error("error");
			return 100;
			trace(3);
		}
in4core, сравните в случае если закомментировать и раскомментировать строчку с ошибкой
Старый 22.02.2011 13:19 i.o. вне форума
i.o.
 
Аватар для i.o.
in4core, throw != return. Это абсолютно 2 разных оператора.
Первый выходит из стека, поднимаясь выше, пока не встретит try..catch.
Второй просто возвращает значение из функции.
Вещи совершенно разные, не находите?
Старый 22.02.2011 13:45 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
in4core, throw выбрасывает из стэка напроч. а return на уровень выше. а на счёт void я даже не хочу комментировать. научитесь читать что ли ...
Старый 22.02.2011 14:39 in4core вне форума
in4core
 
Аватар для in4core
Цитата:
Так а где тут противоречия? Их тут нет.
Соответственно, вот это Ваше высказывание неверно:
Вам же вернулось undefined! а это значение!. если бы ничего не вернулось тоесть пусто бы было, знеачит и возвращения нету.

Цитата:
in4core, throw != return.
Никто и не спорит, я лишь сказал что в данном случае, они наглядно выполнят одинаковые операции, с разницой в появлении ошибки в компиляторе. А то , что это разные вещи ясное дело.

@BlooDHounD

тоесть по вашему

Код AS3:
trace('333');
throw new Error()
Трейса мы не увидим ?
Старый 22.02.2011 14:58 i.o. вне форума
i.o.
 
Аватар для i.o.
Цитата:
Вам же вернулось undefined! а это значение!. если бы ничего не вернулось тоесть пусто бы было, знеачит и возвращения нету.
no comments
Старый 22.02.2011 15:22 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
@in4core, скажите пожалуйста, вы вообще воспринимаете внешний мир?
вы прочитайте, что Вы написали, и что я. сравните просто слегонца.
Цитата:
Сообщение от in4core
Имеет свой return который наглядно ничего не вернет. но завершает функцию по окончанию чтения строк или выводу ошибки. В итоге void это тоже возвращаемая величина )))
Цитата:
Сообщение от BlooDHounD
void - не "величина", и уж тем более не "возвращаемая". void - специальный тип данных, который содержит единственное значение undefined. исходя из простых сведений мы можем заключить что любой метод "наглядно" возвращает значение. но удобнее опускать данное значение, и считать, что метод ничего не возвращает, так как undefined - и есть "ничего".
Цитата:
Сообщение от in4core
Вы протеворечите сами себе. void типа данных, а Undefined значение, значение возвращается.

Цитата:
Сообщение от in4core
Никто и не спорит, я лишь сказал что в данном случае, они наглядно выполнят одинаковые операции, с разницой в появлении ошибки в компиляторе. А то , что это разные вещи ясное дело.
они наглядно выполняют разные функции. я даже не могу представить как они могут одно и тоже сделать.


Цитата:
Сообщение от in4core
тоесть по вашему
Код AS3:
trace('333');
throw new Error()
Трейса мы не увидим ?
с чего вы вообще решили мы не увидем трэйса? где вы такое вычитали?
Старый 22.02.2011 15:28 i.o. вне форума
i.o.
 
Аватар для i.o.
На всякий случай, все же, на 2х языках, с пояснением про void (нужное выделено)

На английском:
Цитата:
void Special Type
Usage
functionName():void {}

Language Version: ActionScript 3.0
Runtime Versions: Flash Player 9

Specifies that a function cannot return any value. The void type is a special type that contains exactly one value: undefined. It is special in that its use is limited to the return type of a function. You cannot use void as a type annotation for a property.
На русском:
Цитата:
void Специальный тип
Применение
functionName():void {}

Язык версии : ActionScript 3.0
Версии среды выполнения: Flash Player 9

Показывает, что функции не удается возвратить какое-либо значение. Тип void является особым типом, содержащим только одно значение: undefined. Его особенность заключается в том, его использование ограничивается возвращаемым функцией значением. Void нельзя использовать в качестве типа аннотации для свойства.
Ну и раз in4core считает, что он прав, то пусть скомпилирует сие в strict режиме:
Код AS3:
function voidTest():void
{
	return undefined;
}
Обновил(-а) i.o. 22.02.2011 в 15:40
Старый 22.02.2011 15:47 cleptoman вне форума
cleptoman
 
Аватар для cleptoman
Код AS3:
function test():String{
	throw addChild(new Sprite()).alpha.toString();
}
try{
	trace(test());
}catch(err:String){
	trace("children: " + numChildren);
}
output
Цитата:
children: 1
не знаю где это может пригодиться, но вот так, в качестве лирического отступления )
Старый 22.02.2011 15:56 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
брррр. зачем выкидывать строковое значение альфы, а потом трэйсть numChildren?
Старый 22.02.2011 15:57 cleptoman вне форума
cleptoman
 
Аватар для cleptoman
альфа - пережитки предыдущих извращений )
Старый 22.02.2011 15:57 ChuwY вне форума
ChuwY
 
Аватар для ChuwY
Код AS3:
try{
  throwSprite();
} catch (sprite : Sprite){
  addChild(sprite);
}
 
 
function throwSprite():Sprite{
  var sprite : Sprite = new Sprite();
  with(sprite.graphics){
    beginFill(0x0, 0.5);
    drawRect(0, 0, 100, 100);
    endFill();
  }
  throw sprite;
}
Так еще забавнее =D

И главное -- даже ворнинга не выдает компилятор.
Старый 22.02.2011 16:03 cleptoman вне форума
cleptoman
 
Аватар для cleptoman
ну а с чего его вываливать, если try?
выполняется expression после throw. результат этого выражения и вывалится в аутпут с указанием где все произошло, если без try. с ним выражение все равно выполнится, но результат выкинет в блок catch
Старый 22.02.2011 16:20 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
без try не бывает catch. я вообще потерял нить ваших извращений. то что throw выкидывает что угодно - это известный факт. но чего вы тут добиться пытаетесь?
Старый 22.02.2011 16:41 ChuwY вне форума
ChuwY
 
Аватар для ChuwY
Я не про то говорил. В сигнатуре функции throwSprite указано, что она возвращает спрайт.
Но return-а в функции нет.
Поидее должен написать компилятор:
"1170: Function does not return a value."
но нет.
Вот и радуюсь сижу.
 

 


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


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