How to define the return type of AS3 method that may return or not return a result? - actionscript-3

public function t()
{
if(xxx)return xxx;
//don't return anything
}
How to define the return type for such method?

A function either has to return nothing, or return something - it can't do both. The reason being, what if you write this code:
var someValue = someFunction();
How would this code be handled if sometimes someFunction returned a value, and sometimes it didn't?
Your problem is a really common one, though, and there are several ways to work around it.
Sentinel Values
You can return special-case values that you treat as non-values (such as null, NaN, "", or -1). These special-case values are called sentinel values. The users of your function (maybe your own code) would check the result after calling it. If it gets one of the sentinel values back, it doesn't use the result.
Try-style Functions
You could also use a pattern commonly used in C#/.Net that they call "Try-methods", but you can call "Try-functions". Actionscript doesn't work exactly like C#, but we can get close enough for this pattern to work.
To do this, return Boolean, returning true if you have a value, and false if you don't. Then give your function an Object parameter, and populate a property with the actual return value:
function trySomeFunction(result:Object) : Boolean
{
if(xxx)
{
result.Value = xxx;
return true;
}
return false;
}
// ...
var result:Object = { Value:null };
if(trySomeFunction(result))
{
// Do something with the value here
}
Exceptions
If your method failed to do what it promised to do, you can throw an exception. Then you don't have to worry about what gets returned, because your code just dies.
Exceptions are great because people who call your code don't have to learn as much. They don't have to know that your function only succeeded if it doesn't return some magic value that is different for every function, they don't need to check if your function returns true/false, and they don't need to know that some property gets populated on an object when the function succeeded.
Without exceptions, if they forget to check for your special value, or the result of a "Try-function", an error might happen further on in the program. Or it might not happen at all, and the program will continue running, but be broken. In these cases, it is much harder to track down the problem.
With exceptions, your code just blows up the second it detects a problem, and gives you the line of code where your program realized it couldn't work correctly.
If it is normal and okay for your function to fail, though, you probably shouldn't throw an exception. You should probably use a "Try-function" or a sentinel value instead.

Everything that Merlyn says is fine, though perhaps a bit of overkill. If your method needs the potential to return null, then just pass xxx back whether it's null or not...
public function t():MyReturnType
{
return xxx;
}
... since you're going to have to do check the special condition in the calling method anyway:
public function caller():void
{
var value:MyReturnType = t();
if (value)
doSomethingPositive();
else
copeWithNullState();
}
Some people think that this is wrong and advocate creating a special 'null value' object in your return class, like this:
public class MyReturnType
{
public static const NULL:MyReturnType = new MyReturnType(null);
public function MyReturnType(identifier:String)
...
}
then in your function either return an interesting MyReturnType or NULL:
public function t():MyReturnType
{
return xxx || MyReturnType.NULL;
}
but then you've not really improved your caller method so why bother?
public function caller():void
{
var value:MyReturnType = t();
if (value != MyReturnType.NULL)
doSomethingPositive();
else
copeWithNullState();
}
Whatever you choose to do, eventually you're just going to have to test for special cases in the caller method. Personally I'd say it's better to keep it as simple as possible, and the special 'null value' in your class is over-complication.

I write plenty of functions that might return an object reference, but may also return null, like this:
public function findThingById( id:int ):MyThingType
{
... code here to search for/load/lookup thing with matching id
if (found)
{
return thing;
}
return null;
}
Wherever you call a function that might return null, you would either test the return value for null explicitly, or if you expect null just don't do anything with the return value. For built-in data types, you would use a special value rather than null (like NaN for Numbers illustrated above), but the principle is the same.

public function t():type
{
if(xxx)return xxx;
//don't return anything
}
so something like:
private function derp():void{
}
private function derp2():int{
}
private function derp3():Boolean{
}
etc
its always good practice to define the return type, and return an indicator variable if false (i.e return -1 for number), but if its really necessary you can do this:
public function t()
{
if(xxx)return xxx;
//don't return anything
}
don't specify a return type at all, and either it will return xxx or undefined, but I highly encourage using a return type.
But since flash runs on virtual memory it can basically adapt to your return type so it makes it a little flexible so you can return what ever.
EDIT:
public function t()
{
if(true){
return xxx; //xxx can by of any type
}
return NaN
}
EDIT:
so lets say you want the condition with a return type of int you would have
public function t():int
{
if(true){
return xxx; //where xxx != -1
}
return -1
}
this when we get back any number other then negative 1 we know the condition was true, but if we get -1 the condition was false. But if you numbers are any real numbers, use NaN keyword:
public function t():Number
{
if(true){
return xxx; //where xxx != -1
}
return NaN
}
this way if you get NaN back it means your condition was false
I should also mention that when your dealing with NaN use the isNaN() to determine if the return type was NaN or not:
example:
if(isNaN(t()) == true){
//if condition in function t() was false;
}

There is no way a single function can return void as well as returning a type. This is because void is not part of any inheritance chain, it is a top level concept meaning something very specific; it doesn't return anything.
Don't get confused between null and void, undefined and void, NaN and void. They are different concepts.
The answer to your question is simply that it can't, nor should it be done. When you hit a problem like this, it's good practice to step back and ask 'why' do you need to do this.
I would highly encourage that you mark this question as closed, and instead posted a higher level problem. For example,
How would I structure a class that has a variable xxx that does this and that and will be eventually set to a number when the user clicks. But if the user never clicks, it will be unset.... ecetera ecetera....
If you are 100% convinced you should do something like you're asking, you could 'fake' it by
function f():* {
var xxx:Number = 999;
if(xxx) {
return xxx;
} else {
return undefined;
}
}
var xx:* = f();
trace(xx);
But remember, from that point onwards you will need to check everytime xx is used to see if it undefined. Otherwise it will lead to errors.

Related

JUnit: should I do null-checks after assertNotNull

Should I do null-checks after assertNotNull to avoid null-pointers in test code? E.g.
assertNotNull(foo);
if (foo != null) {
assertNotNull(foo.getBar());
}
Or just
assertNotNull(foo);
assertNotNull(foo.getBar());
You are doing right with...
assertNotNull(foo);
assertNotNull(foo.getBar());
You don't need to set another condition to check the same if you previously did it.
Using assertX methods ensure the condition is actually asserted. So, by using assertNotNull you ensure that something is not null.
The correct way is as you showed:
assertNotNull(foo);
assertNotNull(foo.getBar());
If you start digging deeper into the assertNotNull method, you will see this calls:
// First call
static public void assertNotNull(Object object) {
assertNotNull(null, object);
}
// Second call
static public void assertNotNull(String message, Object object) {
assertTrue(message, object != null);
}
// Third call
static public void assertTrue(String message, boolean condition) {
if (!condition) {
fail(message);
}
}
Quoting the assertTrue documentation:
Asserts that a condition is true. If it isn't it throws an AssertionError with the given message.
Conclusion, you don't have to do null checks after asserting for not null values since junit is taking care of that for you
You even don't need to have the first null check. The test will fail with a NullPointerException if foo is null. It is a matter of taste whether to have the null check or not.

Which is better for returning result of some method or instance of a class? and why?

I was just wondered which is better way for returning some result of function or instance of Class?
1)
FN() {
var result = callSomeFN();
return result;
}
InitClass(int typeId): MyClass {
MyClass class = new MyClass(typeId);
return class;
}
2)
FN() {
return callSomeFN();
}
InitClass(int typeId): MyClass {
return new MyClass(typeId);
}
The only difference I see here is the declaration of a variable. I wouldn't say one is better than the other. If the variable is never going to be used why bother defining it? Just return.
I suppose if you really wanted to nitpick it would depend on if you're returning a value or reference type. If it's a reference it doesn't matter since you're going to store something in memory and return a pointer (both the variable and the return value are just pointers to the same memory space). If it's a value type it will end up copying the value and disposing of the version within the function scope. If the variable is never used why create something just to destroy it? The default behavior would be highly language dependent, which you didn't specify.

Interface function returning untyped value (*) while implementation return specific type?

Out of curiosity I was wondering if it was possible to have an interface definition returning untyped values, while its implementations return typed value ?
For example, having the following interface :
interfaceExample
{
function someExampleFunction():*
}
implemented the following way :
classA implements interfaceExample
{
public function someExampleFunction():Int{ ... }
}
classB implements interfaceExample
{
public function someExampleFunction():String{ ... }
}
( I've googled with no result, maybe I haven't been able to ask the right way )
I guess the answer is 'no it's not possible in any way, Interface aren't designed like that' -- so what could be a friendly way to achieve such a thing ?
You're right, this won't compile. This is because the compiler doesn't support overloading of the signature of methods from parent classes or interfaces.
If you think about it, it doesn't really make sense to override the return type when implementing an interface because the code consuming your interface API should not depend on the implementation (int or String return value).
The solution to use really depends on what you are trying to do in the end. In general, the return type should be the common denominator between the different types you could produce. This could also be another interface that describes what to expect from the return value.
While I'm not heavily familiar with interface definitions, I do know that I write a lot of functions that work with typed and untyped arguments and returns.
In the event that what you're describing is not possible, and depending on what you're doing, I would recommend writing a simple function that can convert an untyped variable into a typed variable. They're fairly simple. Then, you could call this function to handle whatever data comes in via the interface definition.
A rough example (untested):
function convertDataTo(type:String, input:*):*
{
var rI:int;
var rN:Number;
var rS:String;
var rB:Boolean;
switch(type)
{
case "int":
if(isNaN(int(input))
{
rI = 0;
}
else
{
rI = int(input);
}
break;
case "Number":
if(isNaN(Number(input))
{
rN = 0;
}
else
{
rN = Number(input);
}
break;
case "Boolean":
if(input == "true")
{
rB = true;
}
else if(input == "false")
{
rB = false;
}
else
{
rB = Boolean(input);
}
return rB;
break;
case "String":
rS = input.toString();
break;
default:
trace("Invalid data type!");
return 0;
break;
}
}
You can also rewrite this function to convert from String type to any other type, and have your interface definition always return strings. On the other end, you can have a similar function that converts all variables to strings that can be interpreted by this function.
By the way, I've had to use that kind of string interpretation in writing my own scripting language for use inside one of my larger projects.
Of course, I don't pretend this answers your question directly, but I wanted to throw out this contingency in case what you're looking for doesn't work.

How to always return a java.util.Vector

If the value in my control only have one value the following code will return a String, if there are more than one value the code will return a java.util.Vector.
getComponent("mycontrol").getValue();
I want this code to return a vector even if there is only one value.
I have seen several code snippets that converts my string to an Array, but I want to get back a vector.
There is no way to force a singular value to be returned as a java.util.vector (or Array for that matter). The only way would be to test to see if it is a vector, then build a vector if not. You could place it into a function and wrap the call into that... for example (this is untested code so you'll need to verify syntax, etc):
asVector(getComponent("mycontrol").getValue());
function asVector(obj) {
if (obj.constructor === java.util.Vector) {
return obj;
} else {
var x:java.util.Vector = new java.util.Vector();
x.add(obj);
return x;
}
}

Error Returning Value From Switch Case?

after coding a custom event in AS3, i've come across a curious problem:
override public function toString():String
{
switch (type)
{
case CHANGE: return formatToString("HistoryEvent", "type", "action", "name", "data");
case ABILITY: return formatToString("HistoryEvent", "type", "undoable", "redoable");
}
}
the above code returns the following compile-time error:
1170: Function does not return a
value.
i can remedy the problem easily by adding return null; at the end of the function, but that's redundant and it annoys me that it seems to be the only solution.
why is returning a value from a switch case not seen by the compiler? is this an issue specific to the AS3 compiler or am i actually attempting something here that is so completely dangerous and adverse that it shadows counterculturists the world over.
It is possible that your switch doesn't match, and in that case the function can't return anything. That's why the compiler complains. Adding default: return null; to your switch statement solves the problem as well as adding return null at the end of your function.
You have to add default block to your switch statement.Then the compiler won't complain to return value