<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>FlashFuck.it &#187; Spring</title>
	<atom:link href="http://www.flashfuck.it/tag/spring/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.flashfuck.it</link>
	<description>flash platform, gaming and 3D</description>
	<lastBuildDate>Mon, 23 Jan 2012 18:11:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>AS3 Reflection crapyness :\</title>
		<link>http://www.flashfuck.it/2009/12/02/as3-reflection-crapyness/</link>
		<comments>http://www.flashfuck.it/2009/12/02/as3-reflection-crapyness/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 12:58:10 +0000</pubDate>
		<dc:creator>pigiuz</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[Improvements]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.flashfuck.it/?p=164</guid>
		<description><![CDATA[Today I spent a whole morning to figure out that AS3 sucks. Today I&#8217;ve been implementing a simple factory method which receives a Class object and some parameters to be passed to the concrete class instance, something with a signature like this: static public function createInstance(c:Class, ... args):Object BUT&#8230;the implementation of such a clear and [...]]]></description>
			<content:encoded><![CDATA[<p>Today I spent a whole morning to figure out that AS3 sucks.</p>
<p>Today I&#8217;ve been implementing a simple factory method which receives a Class object and some parameters to be passed to the concrete class instance, something with a signature like this:</p>
<pre lang="actionscript">
static public function createInstance(c:Class, ... args):Object
</pre>
<p>BUT&#8230;the implementation of such a clear and simple method has been a bloody bath, because AS3 doesn&#8217;t support a really cool way to do really cool stuff like this <img src='http://www.flashfuck.it/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /><br />
I thought the implementation would be simply something like</p>
<pre lang="actionscript">
static public function createInstance(c:Class, ... args):Object
{
return new c(args);
}
</pre>
<p>or any other easy way (python taught me to think simple <img src='http://www.flashfuck.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) BUT&#8230;<br />
&#8220;new c(args);&#8221; means my class constructor accepts one parameter typed as an Array, and I really don&#8217;t want my custom classes to have this defect of form nor my custom factory not to be able to instance classes written by someone else, so the solution &#8220;classes to be instanciated by the factory must accept an array as constructor parameter&#8221; is absolutely out.</p>
<p>Next approach, &#8220;reflect all properties instead of having parameters passed to the constructor&#8221;&#8230; not really a solution. Not always classes&#8217; properties have the same name\type\whatever of constructor parameters. It&#8217;s a compromise that my factory can&#8217;t accept because I wouldn&#8217;t be able to create whatever class instance but only &#8220;some&#8221; class instance :\. out.</p>
<p>Next approach, &#8220;use <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/Function.html#apply%28%29">Function.apply</a> to pass some parameters (array) to a function as they were single variables&#8221;..hey! that&#8217;s a good one! Let&#8217;s try it with some function</p>
<pre lang="actionscript">
class MyClass{
public function myfunc(foo:String,bar:uint):void
{
trace(foo, bar);
}
}

class MyOtherClass{
public function callmyfunc(... args):void
{
var c:MyClass = new MyClass();
c.myfunc.apply(null,args);
}
}
</pre>
<p>HEY! IT WORKS! holy crap! AS3 rocks!&#8230;wait, let&#8217;s try it with a constructor function&#8230;</p>
<pre lang="actionscript">
class MyClass{
public function MyClass(foo:String,bar:uint):void
{
trace(foo, bar);
}
}

class MyOtherClass{
public function callmyfunc(... args):void
{
var c:MyClass = new MyClass().apply(null,args);
}
}
</pre>
<p>&#8230;ok, it doesn&#8217;t work :\ and throws a runtime error :/ &#8220;Property apply not found on MyClass and there is no default value&#8221;&#8230;mmm<br />
ok, maybe I have to reference the constructor function, but how can I do it!?<br />
let&#8217;s try with &#8220;<a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/Object.html#constructor">Class.prototype.constructor</a>&#8221;</p>
<pre lang="actionscript">
class MyClass{
public function MyClass(foo:String,bar:uint):void
{
trace(foo, bar);
}
}

class MyOtherClass{
public function callmyfunc(... args):void
{
var c:Class = MyClass;
var f:Function = c.prototype.constructor;
}
}
</pre>
<p>&#8230;error&#8230; Class.prototype.constructor returns the type of the caller class (in this case MyClass)&#8230;<br />
so&#8230;what can I do?</p>
<p>Discarded solutions:<br />
- <del datetime="2009-12-02T12:02:52+00:00">&#8220;classes to be instanciated by the factory must accept an array as constructor parameter&#8221;<br />
</del><br />
- <del datetime="2009-12-02T12:02:52+00:00">&#8220;reflect all properties instead of having parameters passed to the constructor&#8221;</del><br />
- <del datetime="2009-12-02T12:02:52+00:00">&#8220;use Function.apply to pass some parameters (array) to a function as they were single variables&#8221;</del><br />
here&#8217;s the solution: (drums) <strong>THE CRAPY ONE</strong>!<br />
better known as &#8220;switch it all baby&#8221;&#8230;.</p>
<pre lang="actionscript">
static public function create(c:Class, ... args):Object {
			switch(args.length){
				case 0: return new c();
				case 1: return new c(args[0]);
				case 2: return new c(args[0],args[1]);
				case 3: return new c(args[0],args[1],args[2]);
				case 4: return new c(args[0],args[1],args[2],args[3]);
				case 5: return new c(args[0],args[1],args[2],args[3],args[4]);
				default: throw new Error("too many arguments");
			}
			return null;
		}
</pre>
<p>if you need to pass more than 5 arguments just add some lines to the factory and you&#8217;re done&#8230;</p>
<p>I was completely pissed off when I found this horrible lack in AS3, really, I was about for starting to cry, so I submitted a feature request on bugs.adobe&#8230; I think it&#8217;s really a MUST for a &#8220;respectable&#8221; language, if you find it as necessary as I think take a minute to vote this feature.<br />
<a href="https://bugs.adobe.com/jira/browse/FP-3364">https://bugs.adobe.com/jira/browse/FP-3364</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.flashfuck.it/2009/12/02/as3-reflection-crapyness/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

