|
metadata
Sorry about the late reply; I didn’t notice your response until now.
> *Originally posted by **[skyboy](/forums/4/topics/202566?page=1#posts-4399084):***
>
> ClassC will return true. ClassB will return false. a ClassB instance will return true for `is ClassZ`. superclass goes one level up, just one.
Are you sure?
`
trace("MovieClip inherits from DisplayObject: " + subclassOf(MovieClip, DisplayObject)); //true
trace("BitmapData inherits from Object: " + subclassOf(BitmapData, Object)); //true
trace("BitmapData inherits from MovieClip: " + subclassOf(BitmapData, MovieClip)); //false
trace("int \"inherits\" from int: " + subclassOf(int, int)); //true
`
Though I did have to make a couple small changes to get it working:
`
/**
* Returns whether type is superClass or is a subclass of superClass.
*/
public static function subclassOf(type:Class, superClass:Class):Boolean {
if(superClass == Object) {
return true;
}
try {
for(var c:Class = type; c != Object; c = Class(getDefinitionByName(getQualifiedSuperclassName(c)))) {
if(c == superClass) {
return true;
}
}
} catch(e:Error) {}
return false;
}
`
You may have a point about efficiency, but extensibility also has to be a concern, and I don’t think trying to store an identifier for each allowed class is very extensible.
I’m also a little suspicious of `describeType()`. I mean, I realize this code is pretty inefficient, but getting (and parsing!) an XML object with lots of superfluous data seems likely to be worse.
|
|
|
metadata
Also made me think of something – if you use my method which is undoubtedly faster than above,
`
ClassA.prototype instanceof ClassB
`
And ClassA and ClassB are the same type (say Sprite), it will end up returning false. So just a warning to watch out for that. And of course you can handle that easily, as skyboy did below.
|
|
|
metadata
What about `ClassA.prototype is ClassB`
|
|
|
metadata
`
trace(Sprite.prototype instanceof Sprite); //false
trace(Sprite.prototype is Sprite); //false
trace(int.prototype instanceof int); //false
trace(int.prototype is int); //false
trace(Sprite.prototype instanceof DisplayObject); //true
trace(Sprite.prototype is DisplayObject); //false
trace(int.prototype instanceof Object); //true
trace(int.prototype is Object); //true
`
|
|
|
metadata
Speed shouldn’t be a concern.
player\_03’s is fine.
|
|
|
metadata
> *Originally posted by **[player\_03](/forums/4/topics/202566?page=2#posts-4455092):***
>
> Are you sure?
i missed the for loop on my initial glance, but for just a single call to superclass i was sure.
> *Originally posted by **[BobTheCoolGuy](/forums/4/topics/202566?page=2#posts-4455517):***
>
> Also made me think of something – if you use my method which is undoubtedly faster than above,
>
> `ClassA.prototype instanceof ClassB`
>
> And ClassA and ClassB are the same type (say Sprite), it will end up returning false. So just a warning to watch out for that.`function subclassOf_fast(a:Class, b:Class):Boolean {
if (int(!a) | int(!b)) return false;
return (a == b || a.prototype instanceof b);
}`
|
|
|
metadata
> *Originally posted by **[skyboy](/forums/4/topics/202566?page=2#posts-4458264):***
>
> `function subclassOf_fast(a:Class, b:Class):Boolean {
> if (int(!a) | int(!b)) return false;
> return (a == b || a.prototype instanceof b);
> }`
That seems like a much better solution, even though it gives a warning about the `instanceof` operator being deprecated.
|
|
|
metadata
> Sprite.prototype is DisplayObject //false
The heck? Why? I am confuse. EVERYTHING I KNOW IS A LIE!
|
|
|
metadata
> *Originally posted by **[truefire](/forums/4/topics/202566?page=2#posts-4459793):***
>
> The heck? Why? I am confuse. EVERYTHING I KNOW IS A LIE!
the prototype property is an object that is shared between the class and every instance of it. the prototype object is not an instance of the class it is found on it, it is an instance of the generic Object class.
> *Originally posted by **[player\_03](/forums/4/topics/202566?page=2#posts-4459603):***
>
> That seems like a much better solution, even though it gives a warning about the `instanceof` operator being deprecated.
it does offer up a potential problem, though. the prototype properties are checked for exact matches (iirc) and on-up the prototype chain – that would mean, you could create an unrelated class that is not a subclass, but shares all of the properties. assigning an instance of that to a variable of the other class will thrown an error but `subclassOf` will return true. while not a subclass, it is a compatible class; sadly, strict types don’t work on the premise of compatible.
i’m not sure that is an actual problem, just the potential is there based on what i know
|
|
|
metadata
Wow. This thread was featured in [Jackson Dunstan’s article](http://jacksondunstan.com/articles/1440). Didn’t know he read Kong forums. :)
|
|
|
metadata
> `
> | Version | Time |
> | Skyboy | 64 |
> | player_03 | 1137 |
> `
Leave it to skyboy…
> Didn’t know he read Kong forums.
He probably doesn’t, if this was the most interesting thread he’s seen recently ;P
I have a question regarding your code, skyboy.
`
int(!a) | int(!b)
//--------------
(!a || !b)
`
Why do you do the former rather than the latter? I can’t imagine any way it would be faster. You’re casting… twice even. (Class → Bool, then Bool → Int)
Or is this just an exploitation of the Adobe compiler? (Maybe the usual way doesn’t produce optimal bytecode, but this does for some reason?)
|
|
|
metadata
For me, the former is faster when compiled in release mode and the latter is faster when compiled in debug mode.
> *Originally posted by **[truefire](/forums/4/topics/202566?page=2#posts-4537867):***
> > Didn’t know he read Kong forums.
>
> He probably doesn’t, if this was the most interesting thread he’s seen recently ;P
What do you think would be a better article? This seems like it could be a somewhat common problem.
|
|
|
metadata
> What do you think would be a better article? This seems like it could be a somewhat common problem.
90% of everything is crap (but that doesn’t make the rest of it _good_)
|
|
|
metadata
Nah. Really, you should NEVER have to be doing this. All of these checks are entirely avoidable pre-compile.
The one case I can think of where you might want to is if you’re creating a library or framework for others to use.
|
|
|
metadata
> *Originally posted by **[truefire](/forums/4/topics/202566?page=2#posts-4537867):***
>
> He probably doesn’t, if this was the most interesting thread he’s seen recently ;P
Oi!
|
|
|
metadata
> *Originally posted by **[skyboy](/forums/4/topics/202566?page=2#posts-4460161):***
>
> it does offer up a potential problem, though. the prototype properties are checked for exact matches (iirc) and on-up the prototype chain – that would mean, you could create an unrelated class that is not a subclass, but shares all of the properties. assigning an instance of that to a variable of the other class will thrown an error but `subclassOf` will return true. while not a subclass, it is a compatible class; sadly, strict types don’t work on the premise of compatible.
> i’m not sure that is an actual problem, just the potential is there based on what i know
I’ve attempted to reproduce (produce?) this error, but I haven’t been able to. I’m still not that familiar with prototypes, so I might not have done it correctly, but as far as I can tell, a class’s constructor will uniquely identify that class’s prototype object.
Another note:
`
function subclassOf(a:Class, b:Class):Boolean {
if (int(!a) | int(!b)) return false;
return (a == b || b.prototype.isPrototypeOf(a.prototype));
}
`
This function (described by BlooDHounD on Jackson’s site) produces the same results as skyboy’s, though it is a little slower. I would recommend that you use it instead of the version with `instanceof`, because that way you won’t get the warning, and of course using a deprecated operator means your application might break after a future update.
> *Originally posted by **[Draco18s](/forums/4/topics/202566?page=2#posts-4538338):***
>
> 90% of everything is crap (but that doesn’t make the rest of it _good_)
Actually, I’m pretty sure that one of the main points of Sturgeon’s Law is that 10% of everything _is_ (at least relatively) good.
|
|
|
metadata
`isPrototypeOf` it is, then
|
|
|
metadata
> *Originally posted by **[truefire](/forums/4/topics/202566?page=2#posts-4537867):***
> > `| Version | Time |
> > | Skyboy | 64 |
> > | player_03 | 1137 |`
>
> Leave it to skyboy…
>
> > Didn’t know he read Kong forums.
>
> He probably doesn’t, if this was the most interesting thread he’s seen recently ;P
>
> I have a question regarding your code, skyboy.
>
> `int(!a) | int(!b)
> //———————
> (!a || !b)`
>
> Why do you do the former rather than the latter? I can’t imagine any way it would be faster. You’re casting… twice even. (Class → Bool, then Bool → Int)
>
> Or is this just an exploitation of the Adobe compiler? (Maybe the usual way doesn’t produce optimal bytecode, but this does for some reason?)
my optimization wasn’t really an optimization, and was written solely in this textarea. but it does exploit Adobe’s backend for the checking, which is in C++. so.
and the casting isn’t true casting, it’s not a function call. in release compiles the function calls are stripped away and replaced with a single, very fast, op code. internally Bool/int are stored in a way that they can be changed with a simple XOR to the first 3 bits of the Atom; this is exploited for int/bool casts both ways, and converting any object to a bool is as simple as checking that it’s not an instance of the undefined Atom or Null Atom (there’s only one each.) and that ints aren’t 0. converting to a Boolean from anything, even the slow as hell Strings, is virtually O(1) across the board.
also, since it strips out two whole branchs on false, you get those cycles back
> *Originally posted by **[BobTheCoolGuy](/forums/4/topics/202566?page=2#posts-4537917):***
>
> For me, the former is faster when compiled in release mode and the latter is faster when compiled in debug mode.
debug mode doesn’t get the JIT, and there are additional slowdowns from the debug player, which should exhibit slower runtimes for this than release does.
> *Originally posted by **[truefire](/forums/4/topics/202566?page=2#posts-4538919):***
>
> Nah. Really, you should NEVER have to be doing this. All of these checks are entirely avoidable pre-compile.
>
> The one case I can think of where you might want to is if you’re creating a library or framework for others to use.
or, you know, loading classes in from outside the SWF. runtime shared libraries. they’re extremely common.
> *Originally posted by **[player\_03](/forums/4/topics/202566?page=2#posts-4539309):***
>
> This function (described by BlooDHounD on Jackson’s site) produces the same results as skyboy’s, though it is a little slower. I would recommend that you use it instead of the version with `instanceof`, because that way you won’t get the warning, and of course using a deprecated operator means your application might break after a future update.
no. the operator will remain for the remainder of AS3 — if they decide to strip it out, they _have_ to leave it in for previous versions of SWFs. that’s why they’re not that keen about fixing minor problems. they would have to duplicate much of the code, and execute two sets provisionally based on version. this adds function calls and comparison overheads to the routines, slowing them down dramatically. Adobe is not fond of doing that.
but yes, this method will become obsolete in AS4. along with this problem entirely, i suspect.
* * *
edit: i blew the textile engine with my post’s length. **again**. this gets so frustrating sometimes.
|
|
|
metadata
> *Originally posted by **[player\_03](/forums/4/topics/202566?page=2#posts-4539309):***
> > *Originally posted by **[Draco18s](/forums/4/topics/202566?page=2#posts-4538338):***
> >
> > 90% of everything is crap (but that doesn’t make the rest of it _good_)
>
> Actually, I’m pretty sure that one of the main points of Sturgeon’s Law is that 10% of everything _is_ (at least relatively) good.
Emphasis on _relatively._
For example, if I create a collection that consists in its entirety of only things from the top 10% of other groups (that is: the 10% best science fiction, the top 10% fantasy, top 10% crime, top 10% romance, etc.), is 90% of my collection crap?
Likely, yes.
Thus even in the top 10% there’s stuff that isn’t so hot (the 91st percentile). Hence my point. Just because it’s better than 90% of what’s out there doesn’t mean it’s any good (it just means it’s not complete and utter shit).
Example: The King’s League. The game got badges and has a 4.38 rating (it’s better than 90% of Kongregate). But it’s still not a _great_ game.
|
|
|
metadata
> **Posted by truefire**
> The one case I can think of… is… a library> **Posted by skyboy**
> Or, you know… libraries.
Hrm…
|
|
|
metadata
> *Originally posted by **[truefire](/forums/4/topics/202566?page=2#posts-4542878):***
> > **Posted by truefire**
> > The one case I can think of… is… a library> **Posted by skyboy**
> > Or, you know… libraries.
>
> Hrm…
You’re both right and both wrong.
Truefire said _creating_ libraries
Skyboy said _using_ libraries
|
|
|
metadata
In the case of using libraries, you can avoid precompile, with knowledge of the inheritance tree in the lib.
In the case of making them, your users can too, but you can’t do anything to ensure that they will.
|
|
|
metadata
And we could just have every variable typed as \* or `Object` also.
Heck, we could eliminate any strict type of variable!
|
|
|
metadata
If that was sarcasm (It better have been), I’m not getting the point you were trying to make.
|
|
|
metadata
> *Originally posted by **[truefire](/forums/4/topics/202566?page=2#posts-4543480):***
>
> If that was sarcasm (It better have been), I’m not getting the point you were trying to make.
Yep :D
I was just (ignoring the performance benefits of typing variables) saying that it primarily helps you to find and debug errors in code, along with handling different situations easier. Basically, you can get many of the same benefits as typing variables.
|