Related
Is there any difference of use, efficiency or background technique between
var mc:MovieClip = MovieClip(getChildByName("mc"));
and
var mc:MovieClip = getChildByName("mc") as MovieClip;
?
The choice is just matter of convention, preference or are there cases where you can't use one?
This article describes the differences well:
A key difference between casting and the as operator is the behavior
on failure. When a cast fails in ActionScript 2, null is returned.
When a cast fails in ActionScript 3, a TypeError is thrown. With the
as operator in ActionScript 3, whenever a cast fails the default value
for the datatype is returned.
as also allows you to cast to Array, which wasn't possible before since the conversion function Array() took precedence.
EDIT: concerning performance, using as is reported to be faster than the function call style casting in various articles: [1] [2] [3]. The first article cited looks at the performance differences in depth and reports that as is 4x-4.5x faster.
EDIT 2: Not only is as 4x-4.5x faster in the normal best case, but when you wrap the (cast) style conversion in a try-catch block, and an error actually ends up being thrown, it's more like 30x - 230x faster. In AS3, if you think you're going to do something exceptional (in that it could throw an error) then it's clear that you should always look before you leap. Never use try/catch unless forced to by the API, and indeed that means to never (cast) It also is instructive to look at the performance implications of try/catch even when no exception is thrown. There's a performance penalty to setting up a try/catch block even in the happy case that nothing goes wrong.
Since nobody answered the performance aspect directly yet, and it was in your question, as is dramatically more efficient and faster at runtime than (cast) in AS3.
http://jacksondunstan.com/articles/830
Combined with all the other factors I see absolutely no reason to ever use (cast) and feel it should be avoided completely.
Retracted comment below actually reminds me of a good point as well in regards to this. If you (cast) then you're almost assuredly going to find yourself in a situation where you'll have to try/catch
try{
SubType(foo).bar();
}catch(e:TypeError){
// Can't cast to SubType
}
Which is murderously slow. The only way around that is an is check first
if(foo is SubType){
SubType(foo).bar();
}
Which just seems wrong and wasteful.
AS3 Casting one type to another contains the answer that answers this as well: the "as" keyword assigns null when the conversion fails, otherwise it throws a TypeError.
It is best practice to use the as keyword.
as has the advantage of not throwing an RTE (run-time error). For example, say you have a class Dog that cannot be cast into a MovieClip; this code will throw an RTE:
var dog:Dog = new Dog();
var mc:MovieClip = MovieClip(Dog);
TypeError: Error #1034: Type Coercion failed: cannot convert Dog to MovieClip.
In order for you to make this code "safe" you would have to encompass the cast in a try/catch block.
On the other hand, as would be safer because it simply returns null if the conversion fails and then you can check for the errors yourself without using a try/catch block:
var dog:Dog = new Dog();
var mc:MovieClip = Dog as MovieClip;
if (mc)
//conversion succeeded
else
//conversion failed
Prefer the use of a cast to the use of the as operator. Use the as operator only if the coercion might fail and you want the expression to evaluate to null instead of throwing an exception.
Do this:
IUIComponent(child).document
Not this:
(child as IUIComponent).document
Coding Conventions
(cast) and "as" are two completely different things. While 'as' simply tells the compiler to interpret an object as if it were of the given type (which only works on same or subclasses or numeric/string conversions) , the (cast) tries to use a static conversion function of the target class. Which may fail (throwing an error) or return a new instance of the target class (no longer the same object). This explains not only the speed differences but also the behavior on the Error event, as described by Alejandro P.S.
The implications are clear:
'as' is to be used if the class of an object is known to the coder but not to the compiler (because obfuscated by an interface that only names a superclass or '*'). An 'is' check before or a null check after (faster) is recommended if the assumed type (or a type compatible to auto-coercion) cannot be 100% assured.
(cast) is to be used if there has to be an actual conversion of an object into another class (if possible at all).
var mc:MovieClip = MovieClip(getChildByName("mc"));
will DIRECTLY SET IT AS movieclip
var mc:MovieClip = getChildByName("mc") as MovieClip;
will make mc act like a movieclip, if required type are same
Further to launch or not RTE, or return null, there is a significant difference when we manage errors in a swf loaded into a separate application domain.
Using Loader.uncaughtErrorEvents to handle errors of the loaded swf; if we cast like 'event.error as Error', the resulting error will have the original stack trace (the same that had been caught in the swf that caused the error) while if cast that with Error (event.error), the stack trace of the error will be changed by the current stack trace (in which the cast was made).
Sample Code:
if (event && event.error && event.error is Error) {
debug ("Casting with 'as Error'")
debugStackTrace (event.error as Error);
debug ("casting with 'Error (...)'");
debugStackTrace (Error (event.error));
}
Sample output:
Casting with 'as Error'
ReferenceError: Error # 1056
at Player / onEnterFrame ()
casting with 'Error (...)'
Error: ReferenceError: Error # 1056
at package :: HandlerClass / uncaughtErrorHandler ()
at EventInfo / listenerProxy ()
//
// To Throw
void PrintType(object obj)
{
if(obj == null)
{
throw new ArgumentNullException("obj")
}
Console.WriteLine(obj.GetType().Name);
}
//
// Not to Throw
void PrintType(object obj)
{
if(obj != null)
{
Console.WriteLine(obj.GetType().Name);
}
}
What principle to keep?
Personally I prefer the first one its say developer-friendly(notified about each "anomaly").
The second one its say user-friendly(let user continue work even if "inside" not everything does right).
I think that is more complicated to find errors and bugs in the maintenance phase when you silently let the things to go on. If something goes wrong you are not notified at once, and sometimes have errors far away from the main error cause, and spend a lot of time to find it.
What do you think?
The second one is lethal. Failing silently is always the wrong thing to do. Suppose this were the banking system in the bank that holds your account. Would you like it if there was a problem paying in your salary and the system silently ignored it?
If the method body handles the null obj properly (in other words, obj != null is not a requirement), then there's no need to throw an exception.
In all other cases: Throw. Let the client take responsibility for their flawed input.
Throwing an exception (if null is an error) seems far better than silently ignoring an error.
There is a third option you can consider:
void PrintType(object obj)
{
Console.WriteLine(obj.GetType().Name);
}
This also throws an exception when obj is null. The advantage of this, is that less code is involved. The disadvantage of this approach is that it is more difficult to tell whether obj can be null.
Throw.
Let the caller of a function determine if it is important enough to throw an exception to the user on a null value, but the function itself should throw because of the invalid argument.
I'd say that it depends on your (developer) preference. From the user perspective, he should never see an unhandled exception, but it does not mean you cannot use exceptions.
I prefer the first one, because I find null to be a totally unnecessary (and annoying) construct, so I make effort to code without it. If there is a null somewhere, someone made a mistake, so the best thing is to just barf out instead of pretending everything is ok.
In the end it depends on what you consider to be the semantics of the method. If the method is supposed to accept nulls, then you should pick option number two. If the method is supposed to only accept real arguments (which I prefer), then you should pick option number one.
Always Throw, except in debugging/diagnostic code. It is most embarassing to have a NullPointerException that occurs in production code at a point where only a debugging message should be generated, e.g.
log.debug("id of object is " + obj.getId())
where the logger is turned off, and obj is null.
It is highly subjective, but I always prefer to just ignore non-fatal or recoverable errors. Put them in logs, if you must, but if you know how to continue - please do so.
Note, that when I say fatal, it actually depends on the function itself. Say, there's API function that gets ID and handful of other parameters. Suppose, that this ID also can be guessed from those other stuff that is passed in. API function should guess it if it can but the function somewhere inside that does all the work should get non-null ID and throw otherwise. Because for high level API function it is not fatal, it knows how to guess it, but for low level function it is fatal, it supposed to do something with that ID and with null value it can't continue.
All fatal errors should be noted, of course.
If you api if exposed outside, do always argument checking and throw a argument based exception so the api user can get the result.
Consider using the Null Object pattern is very useful to not clutter your code with try-catch, null checks (or god forbid swallowed errors).
In this particular example, giving nothing to a printer is like saying "print nothing", thus working as it should.
I do know this is an example, but it's just to clarify that this is relative.
If your code displays user-friendly messages on exceptions somehow, what difference does it make ? the first one would be both developer and user friendly.
It really depends on what your invariants are. If the parameter is optiona, then ignoring a null parameter is just fine, but if the parameter is required then that will hide a bug in your application. Also, and depending on the language, if the invariant is bad enough you may consider a third option: abort the application.
All discussions on whether to use or not exceptions can always be mapped to the decision on whether the situation is exceptional or not, and if it is exceptional, throwing or rather aborting the application depends on whether it is recoverable or not.
Id go for
void PrintType(object obj)
{
Console.WriteLine(obj.GetType().Name);
}
Third option, half in pseudocode:
// To Throw A Clean Error
void PrintType(object obj)
{
if(obj == null)
{
throw new ArgumentNullException(STANDARD_ERROR_MESSAGE, obj)
}
Console.WriteLine(obj.GetType().Name);
}
Either catch all errors and wrap them in a single place, so the user sees standard text:
There has been an error. If this error
persists, please contact an
administrator.
Or throw a select few errors, all of which are user-friendly, and display them directly to the user. "A connection error has occurred." "An authentication error has occurred." "A system error has occurred." And so on.
On the backend, have all errors and their stack trace logged, so you can use the debugging information that way.
It really depends on what the function is defined to do. The most important aspect is to have a clearly defined behavior and for the function to implement it correctly.
Now, if the question is whether is better to define the function to accept null and print it out, or to not accept it and throw an exception, I would say the latter, because it's probably less error prone for the user to check for null before calling the function, if that is a possibility.
I have been doing some work with python-couchdb and desktopcouch. In one of the patches I submitted I wrapped the db.update function from couchdb. For anyone that is not familiar with python-couchdb the function is the following:
def update(self, documents, **options):
"""Perform a bulk update or insertion of the given documents using a
single HTTP request.
>>> server = Server('http://localhost:5984/')
>>> db = server.create('python-tests')
>>> for doc in db.update([
... Document(type='Person', name='John Doe'),
... Document(type='Person', name='Mary Jane'),
... Document(type='City', name='Gotham City')
... ]):
... print repr(doc) #doctest: +ELLIPSIS
(True, '...', '...')
(True, '...', '...')
(True, '...', '...')
>>> del server['python-tests']
The return value of this method is a list containing a tuple for every
element in the `documents` sequence. Each tuple is of the form
``(success, docid, rev_or_exc)``, where ``success`` is a boolean
indicating whether the update succeeded, ``docid`` is the ID of the
document, and ``rev_or_exc`` is either the new document revision, or
an exception instance (e.g. `ResourceConflict`) if the update failed.
If an object in the documents list is not a dictionary, this method
looks for an ``items()`` method that can be used to convert the object
to a dictionary. Effectively this means you can also use this method
with `schema.Document` objects.
:param documents: a sequence of dictionaries or `Document` objects, or
objects providing a ``items()`` method that can be
used to convert them to a dictionary
:return: an iterable over the resulting documents
:rtype: ``list``
:since: version 0.2
"""
As you can see, this function does not raise the exceptions that have been raised by the couchdb server but it rather returns them in a tuple with the id of the document that we wanted to update.
One of the reviewers went to #python on irc to ask about the matter. In #python they recommended to use sentinel values rather than exceptions. As you can imaging just an approach is not practical since there are lots of possible exceptions that can be received. My questions is, what are the cons of using Exceptions over sentinel values besides that using exceptions is uglier?
I think it is ok to return the exceptions in this case, because some parts of the update function may succeed and some may fail. When you raise the exception, the API user has no control over what succeeded already.
Raising an Exception is a notification that something that was expected to work did not work. It breaks the program flow, and should only be done if whatever is going on now is flawed in a way that the program doesn't know how to handle.
But sometimes you want to raise a little error flag without breaking program flow. You can do this by returning special values, and these values can very well be exceptions.
Python does this internally in one case. When you compare two values like foo < bar, the actual call is foo.__lt__(bar). If this method raises an exception, program flow will be broken, as expected. But if it returns NotImplemented, Python will then try bar.__ge__(foo) instead. So in this case returning the exception rather than raising it is used to flag that it didn't work, but in an expected way.
It's really the difference between an expected error and an unexpected one, IMO.
exceptions intended to be raised. It helps with debugging, handling causes of the errors and it's clear and well-established practise of other developers.
I think looking at the interface of the programme, it's not clear what am I supposed to do with returned exception. raise it? from outside of the chain that actually caused it? it seems a bit convoluted.
I'd suggest, returning docid, new_rev_doc tuple on success and propagating/raising exception as it is. Your approach duplicates success and type of 3rd returned value too.
Exceptions cause the normal program flow to break; then exceptions go up the call stack until they're intercept, or they may reach the top if they aren't. Hence they're employed to mark a really special condition that should be handled by the caller. Raising an exception is useful since the program won't continue if a necessary condition has not been met.
In languages that don't support exceptions (like C) you're often forced to check return values of functions to verify everything went on correctly; otherwise the program may misbehave.
By the way the update() is a bit different:
it takes multiple arguments; some may fail, some may succeed, hence it needs a way to communicate results for each arg.
a previous failure has no relation with operations coming next, e.g. it is not a permanent error
In that situation raising an exception would NOT be usueful in an API. On the other hand, if the connection to the db drops while executing the query, then an exception is the way to go (since it's a permament error and would impact all operations coming next).
By the way if your business logic requires all operations to complete successfully and you don't know what to do when an update fails (i.e. your design says it should never happen), feel free to raise an exception in your own code.
Does anyone know the real difference between the two ways of type casting in Flex 3?
var myObject1:MyObject = variable as MyObject;
var myObject2:MyObject = MyObject(variable);
I prefer to use the second method because it will throw an Error when type cast fails, whereas the first method will just return null. But are there any other differences? Perhaps any advantages to using the first method?
The second type of casting has different behaviour for top level(http://livedocs.adobe.com/flex/2/langref/) types, e.g. Array(obj) does not cast in the straightforward way you describe; it creates a new Array if possible from obj, even if obj is an Array.
I'm sure the times this would cause unexpected behaviour would be rare but I always use "as" for this reason. It means if I do
int(str)
I know it's a cast in the "attempt to convert" sense of the word not in the "I promise it is" sense.
ref: got some confirmation on this from http://raghuonflex.wordpress.com/2007/07/27/casting-vs-the-as-operator/
The as method returns null if cast fails.
The () method throws and error if the cast fails.
If the value of variable is not compatible with MyObject, myObject1 will contain null and you will be surprised by a null pointer error (1009 : cannot access a property or method of a null object reference.) somewhere later in the program when you try to access it. Where as if you are casting using the MyObject(variable) syntax, you will get a type coercion error (1034 : Type Coercion failed: cannot convert _ to _) at the same line itself - which is more helpful than getting a 1009 somewhere later and wondering what went wrong.
I think I read somewhere on this site that as is slighty faster than (), but I can't find the question again.
Beside that this question have been asked many times, you will find an more in-depth answer here.
I recently discovered the very useful [] tag when searching on StackOverflow, it allows to only search in questions tagged with the specified tag(s). So you could do a search like [actionscript-3] as vs cast. There are more search tips here: https://stackoverflow.com/search.
And no; the irony in that I can not find the question about performance and write about how to search is not lost on me ;)
I think as returns back the base class and not null when the casting fails and () throws an error.
Is using an if coupled with an immediate return like in the example below an acceptable practise instead of having a if with a block of code inside {} ? Are these equivalent in practise or is there a disadvantage to one of the approaches ?
An example in Java:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext sc = this.getServletContext();
// Throw exception for fatal error (Servlet not defined in web.xml ?)
if( sc == null )
return; // old-style programming
// Careful with silent bugs ! Correct way of handling this is:
// throw new RuntimeException( "BookDetail: ServletContext is null" );
BookList bookList = WebUtil.getBookList( sc );
Martin Fowler would favour the early return, and calls the idea a Guard Clause.
Personally, I don't like it in Java, as I prefer one return per method. However this is subjective and I may be in the minority.
I've blogged about this for and against.
That is not a return, it's an exception. The code is perfectly ok tho.
Even if you'd replace that throw with a "return something", it would still be ok.
I think it comes down to readability. The code should function the same either way.
I use stuff like this all the time
Function Blah() As Boolean
If expr Then
Return False
End If
Do Other work...
Return result
End Function
For error conditions, generally it's best to throw an exception - exception handling was invented to get rid of the manual return code style error checking in C that comprises about 30% of a C program.
However, early returns are fine - they are far more readable than adding an extra scope with curly braces.
if (!_cache.has_key(key))
return null;
return _cache[key]
Is better than:
if (_cache_has_key(key))
{
return _cache[key]
}
else
return null;
And it only gets more obvious the more early returns that you add, 5 early returns beats the hell out of 5 nested if statements.
Note that I didn't return null on an error condition, it's expected that often the key won't be in the cache - but it still means the caller has to write code to check the result. In .NET there's a better pattern of returning a boolean, and setting the result via an out parameter. The methods beginning with Try usually follow this pattern:
Foo foo;
if (!TryGetCachedFoo("myfoo", foo))
{
foo = new Foo(...);
AddToCache("myfoo", foo);
}
// do something with foo
As long as you're using them for conditional escapes as the first thing in the routine. I think the fact that they are obvious in that location, and avoid at least one level of indentation outweighs the negative of having a multiple returns.
In the example you give, I'd favor throwing an exception because a null ServletContext is usually a sign that something has gone wrong. However, there are times when checking whether a parameter is null and returning immediately from the method is both useful and valid.
For instance, if you are gathering contact information about a user and the user has the option of providing a phone number. In that case, you may have a method that validates that the phone number contains all numbers, has the correct number of digits, etc, but which would immediately return if the phone number was empty or null.
public void validatePhone(String phoneNumber) throws ValidationException {
if (phoneNumber == null || phoneNumber.equals("")) {
return;
}
//do validation stuff, throwing exception if not valid
In your example, there is no return after the if statement; you are throwing an exception. (edit: I see you have changed the code since I posted this answer).
There are purists who think that you should have only one return statement in a method (at the end of the method). There's some merit to that idea - it makes the code more clear, it makes it easier to see what can be returned for the method, and especially when you need to cleanup resources (especially in a language without garbage collection; or in Java where you need to close for example an InputStream) it's more clear and easier if you have just one return at the bottom, and do the cleanup code just before the return.
I would not have any objection against the code in your example, however.
I have a few (subjective, or not) remarks:
I always use accolades with a if even the block contains only one line
I don't like to have many return on one method
I don't think that this null check is necessary. If getServletContext() returns null, then you have a much bigger problem with your webapp that should definitely be fixed. In that case, having a NullPointerException later in the code is an exceptional error so I wouldn't bother handling it.