I've tested the following code:
function aa(...aArgs):void
{
trace("aa:", aArgs.length);
bb(aArgs);
}
function bb(...bArgs):void
{
trace("bb:", bArgs.length);
}
aa(); //calling aa without any arguments.
The output is:
aa: 0 //this is expected.
bb: 1 //this is not!
When I pass empty arguments (aArgs) to bb function;
shouldn't it return 0 length? Seems like function bb is treating the passed aArgs as non-empty / non-null..
What am I missing here?
Any help is appreciated.
regards..
It looks like aArgs going to the bb() function would be an empty array, but an array none the less... I would say that output is to be expected. I'm not really sure though how I would format it differently though to get the desired output...
Update 1:
I wanted to clarify a little bit. What you have is basically the same thing as:
function aa(...aArgs):void
{
myArray:Array = aArgs;
bb(myArray);
}
function bb(...bArgs):void
{
trace("bb:", bArgs.length);
}
aa(); //calling aa without any arguments.
If you saw this code, you would expect bb:1 yes?
Update 2:
This thread: filling in (...rest) parameters with an array? looks as though it would be relevant. It uses the apply() function to pass in an array as an parameter list. http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/Function.html#apply()
Don't know if this is still relevant but you could try this:
function aa(...aArgs):void {
var myArray:Array = aArgs;
bb.apply( this, myArray );
}
function bb(...bArgs):void {
trace("bb:", bArgs.length);
}
aa(); //calling aa without any arguments.
Basically Function.apply is your friend here.
This makes perfect sense, and working properly. ...rest always creates an Array, if there are no values passed in it creates an empty Array, as you see by tracing its length. So the reason why bb has one object in its ...rest array is that you are passing the empty array into bb as a value, which gets inserted into the first position of the Array generate by bb's ...rest, giving it a length of one.
Related
I am trying do this:
I want to do function which receives
one node as a parameter. and I it should return a string.
so I need to loop node and I don't know more details,
but I want to concatenate a new json type of string
and returns it.
but seems to be difficult, because I don't know xquery well.
my idea is
declare function local:Do_the_thing($my_node as node()*) as xs:string{
for ($element at $col in (attribute_list($my_node))
let $complete_row_information := concat ("test", "test2");
return $complete_row_information
}
can someone say me, what is going wrong and how to fix it?
if this thing is not in a function it works
I have a function that takes a vector as a parameter, scan this vector and generates a random word. It's expected from me that the generated words' letters are different from each other. So, I want to check it with a simple if-else condition inside the same function. If all letters are different, function returns this word. If not, I need to use the same function which I am already inside while using conditions. But first parameter that I used in the main function doesn't work when I attempt to use it for the second time. Here the generateaRandomWord(vector a) function:
vector<string> currentVector;
string generateaRandomWord(vector<string> a) {
currentVector = a;
string randomWord;
int randomNumber = rand() % currentVector.size();
randomWord = currentVector.at(randomNumber);
if (hasUniqueChars(randomWord)) {
return randomWord;
}
else {
generateaRandomWord(currentVector);
}
}
I thought that it is a good idea to keep a vector (currentVector) outside of the function. So, for the first time I use the function this vector will be defined and I will be able to use it if using recursion is necessary. But that didn't work either.
The main problem you have is that your recursive case doesn't return anything -- it throws away the returned value from the recursive call, then falls off the end of the function (returning garbage -- undefined behvaior). You need to actually return the value returned by the recursive call:
return generateaRandomWord(currentVector);
I was able to store functions into a table. But now I have no idea of how to invoke them. The final table will have about 100 calls, so if possible, I'd like to invoke them as if in a foreach loop. Thanks!
Here is how the table was defined:
game_level_hints = game_level_hints or {}
game_level_hints.levels = {}
game_level_hints.levels["level0"] = function()
return
{
[on_scene("scene0")] =
{
talk("hint0"),
talk("hint1"),
talk("hint2")
},
[on_scene("scene1")] =
{
talk("hint0"),
talk("hint1"),
talk("hint2")
}
}
end
Aaand the function definitions:
function on_scene(sceneId)
-- some code
return sceneId
end
function talk(areaId)
-- some code
return areaId
end
EDIT:
I modified the functions so they'll have a little more context. Basically, they return strings now. And what I was hoping to happen is that at then end of invoking the functions, I'll have a table (ideally the levels table) containing all these strings.
Short answer: to call a function (reference) stored in an array, you just add (parameters), as you'd normally do:
local function func(a,b,c) return a,b,c end
local a = {myfunc = func}
print(a.myfunc(3,4,5)) -- prints 3,4,5
In fact, you can simplify this to
local a = {myfunc = function(a,b,c) return a,b,c end}
print(a.myfunc(3,4,5)) -- prints 3,4,5
Long answer: You don't describe what your expected results are, but what you wrote is likely not to do what you expect it to do. Take this fragment:
game_level_hints.levels["level0"] = function()
return
{
[on_scene("scene0")] =
{
talk("hint0"),
}
}
end
[This paragraph no longer applies after the question has been updated] You reference on_scene and talk functions, but you don't "store" those functions in the table (since you explicitly referenced them in your question, I presume the question is about these functions). You actually call these functions and store the values they return (they both return nil), so when this fragment is executed, you get "table index is nil" error as you are trying to store nil using nil as the index.
If you want to call the function you stored in game_level_hints.levels["level0"], you just do game_level_hints.levels["level0"]()
Using what you guys answered and commented, I was able to come up with the following code as a solution:
asd = game_level_hints.levels["level0"]()
Now, asd contains the area strings I need. Although ideally, I intended to be able to access the data like:
asd[1][1]
accessing it like:
asd["scene0"][1]
to retrieve the area data would suffice. I'll just have to work around the keys.
Thanks, guys.
It's not really clear what you're trying to do. Inside your anonymous function, you're returning a table that uses on_scene's return value as keys. But your on_scene doesn't return anything. Same thing for talk.
I'm going to assume that you wanted on_scene and talk to get called when invoking each levels in your game_level_hints table.
If so, this is how you can do it:
local maxlevel = 99
for i = 0, maxlevel do
game_level_hints.levels["level" .. i] = function()
on_scene("scene" .. i)
talk("hint" .. i)
end
end
-- ...
for levelname, levelfunc in pairs(game_level_hints.levels) do
levelfunc()
end
I seem to remember there being a special name for a function whose output is always identical to its input, e.g.:
var whatsMyName = function (a) {
return a;
};
Does anyone know what such a function -- which, in practice, is pretty pointless -- is called?
It's the identity function.
Any idea how to return multiple variables from a function in ActionScript 3?
Anything like VB.NET where you can have the input argument's variable modified (ByRef arguments)?
Sub do (ByRef inout As Integer)
inout *= 5;
End Sub
Dim num As Integer = 10
Debug.WriteLine (num) '10
do (num)
Debug.WriteLine (num) '50
Anything apart from returning an associative array?
return {a:"string 1", b:"string 2"}
Quoting a googled source:
In ActionScript 3.0, all arguments are passed by reference because all values are stored as objects. However, objects that belong to the primitive data types, which includes Boolean, Number, int, uint, and String, have special operators that make them behave as if they were passed by value.
Which led me to look up the canonical source.
It appears that Strings, ints, units, Booleans are passed by Value.
I tried this little snippet in Flash and the results were negative:
function func(a:String){
a="newVal";
}
var b:String = "old";
trace(b) // old
func(b);
trace(b) // old
So... is String a blacklisted data type too? Boolean too?
I mean whats a sure way of telling which types are passed by reference?
Everything in AS3 is a reference aside from [u]ints. To generalize, everything that inherits Object will be given to the function by a reference.
That being said, the only way I believe you can do it is use a container class like an Array or a String ("5" and do the conversion+math).
It's all by value, if you understand C programming you will be familiar with the concept of pointers.
Think about a pointer as pointing to something in memory, and all variable names "bob from (bob = new person();)" Are essentially pointers that you work with.
Now, when you declare a function, since they are all By Value
function Test(a:Object, b:Object):void {
a = b;
}
You can think about both "a" and "b" being new pointers, so only within the "Test" function do both "a" and "b" exist and point to something in memory.
So let's use it
var s1:Sprite = null;
var s2:Sprite = new Sprite;
Test(s1,s2);
So the s1 and s2 pointers will ALWAYS point to "null" and "a new Sprite in memory" respectively, unless they are modified as s1 and s2 within their "Scope" <- Please make sure you understand variable scope before even trying to tackle this.
And within the function we now have two new pointers "a" pointing to "null" and "b" pointing to "the same sprite in memory as s2". so Since objects and arrays are essentially collections of pointers and only two new pointers have been created by the function for use "a" and "b" any properties/exposed variables "pointers to data in memory" of "a" or "b" will still be exactly the same as the ones for "s1" and "s2" and are the exact same pointers.
So within the function when "a" gets set to be "b", really all that happens is the "a" pointer now points to the same thing as "b". But "s1" and "s2" still point to what they were pointing to before.
!!!!
If this was by reference you would not be able to think of "a" and "b" as new pointers, they would actually be "s1" and "s2" themselves, except you write them out as "a" and "b".
Wrong Wrong Wrong and Wrong.. every Argument is passed by value!!!
the fact you can change a property inside the object passed doesn't mean you can change the object itself. try the following code
function Test(a:Object, b:Object):void {
a = b;
}
function Test2():void {
var s1:Sprite = null;
var s2:Sprite = new Sprite;
Test(s1,s2);
Trace(s1);
Trace(s2);
}
and here's the trace result :
null
[object Sprite]
Note the subtle difference between DarthZorG's example and this one from the Flash docs:
function passByRef(objParam:Object):void
{
objParam.x++;
objParam.y++;
trace(objParam.x, objParam.y);
}
var objVar:Object = {x:10, y:15};
trace(objVar.x, objVar.y); // 10 15
passByRef(objVar); // 11 16
trace(objVar.x, objVar.y); // 11 16
Point Being:
You can't change what the reference is pointing to but you can change the data that the reference is pointing to, so long as that reference is an Object/Array.