Is it possible to pass a parameter to a method ByRef (or out etc) in ActionScript 3?
I have some globally scoped variables at the top of my class and my method will populate that variable if it's == null.
I'm passing in the variable which needs to be populated but so far my efforts have returned a locally populated variable leaving the globally scoped version of it still null.
The variable being passed to my method varies so I can't hardcode it in my method and simply set it.
ActionScript 3 passes params by reference by default, like Java - except for primitive types. But what you are trying to have it do isn't passing by reference. The parameter passed in is a reference to an object(in the case when it's not a primitive type), which you may well modify inside of the function.
But, to answer your question. Here is a solution:
function populateIfNull(variableName, value){
this[variableName] = this[variableName] || value
}
Which you can use like:
populateIfNull('name', 'Bob')
populateIfNull('age', 20)
AS3 does not have pass by reference (it is similar to Java in this regard, in that it passes references by value).
Something similar can be simulated if you control the client code by wrapping the object in another object:
var myObj = null;
myFun({ a: myObj });
function (param) {
if (param.a == null) {
param.a = "Hello";
}
}
Use objects.
eg:
var myObj : Object = new Object();
var myArr : Array;
myObj.arr = myArr;
function populateViaRef(obj : Object) : void {
obj.arr = new Array();
for(var i : Number = 0; i < 10; i++)
obj.arr[i] = i;
}
populateViaRef(myObj);
for(var i : Number = 0; i < 10; i++)
trace(myObj.arr[i]);
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.
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f56.html
In Java arguments are passed by value.
http://javadude.com/articles/passbyvalue.htm
Related
Is there a way to check if your session variable contains something... Just like a list has a method "Contains". Is there something similar to that? Some method or something?
Hi you can try casting your session so it can have a type for example
var listofperson = Session["ListofPerson"] as List<string>;
var hasGeorge = listofperson.Contains("George");
When you retrieve items from Session, they are of type System.Object. This means that you don't get any of the actual methods available for the object's real type. You can do so by casting it to the correct type. In this case, it sounds like you're storing a List<string>. So we can use the as operator. If the object is not of that type or was null to begin with, myList will null. Otherwise it will be of the type you specify.
List<string> myList = Session["myKey"] as List<string>();
if(myList == null)
{
//either Session["myKey"] was null or the object wasn't a List<string>
}
else
{
if(myList.Contains("fuzzy puppies"))
{
//your list contains fuzzy puppies
}
else
{
//your list doesn't contain fuzzy puppies
}
}
Calling .ToString() on an object gives you different results based on the object type. The default behavior is to print out the type of the object. But types can override this behavior. For example, calling .ToString() on a string just gives you the string itself. Calling .ToString() on an object that represents some XML might give you the XML as a string. Since List<string> doesn't override the default behavior of System.Object.ToString(), it just prints out "System.Collections.Generic.List`1[System.String]"
First, check if Session["yoursession_var"] is null. Then cast to List(). Then use Exists(), as described here: how to use Exist in List<string> in C#
When using a {} as follows:
var m = {};
Then m is an Object that does not possess the methods of a Dict. You can see by pasting into jsfiddle
var m = {};
m['a'] = 'x';
alert(m.keys());
This will not run - since keys() is not a method on the given object. So then - how to get a dictionary with all its methods?
Update From #SLaks suggestion: Changing the original line to
var m = new Map();
does the trick
There is no such thing as a dictionary in Javascript.
You can use a regular object as a dictionary, as you're doing, and use methods like Object.keys() to help you.
If you use ES6 (or a polyfill), you can use the Map class, which is a normal class with get() and set() methods.
{} is an "object literal". It has no methods or properties other than what's part of the object prototype (a limited set of functions, such as toString, hasOwnProperty, etc), and what you define on it. It is otherwise empty and does not expose functionality you'd expect on a Dictionary. That's where Object comes in.
The static Object reference has an API on it that you can provide your objects to and effectively exposes a set of functions that can be performed on your object as if they were default methods a "dictionary" might expose.
var m = {};
m.a = 'x';
Object.keys(m) // => ['a']
You can find more methods that Object supports on MDN, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
There is no "Dictionary", but an object in JavaScript can be used in a very similar way to a Map in Java.
var myObject = {}
...
for (var key in myObject) {
if (myObject.hasOwnProperty(key)) {
var value = myObject[key];
}
}
The hasOwnProperty() check is to avoid finding keys higher up JavaScripts prototype chain.
I want to pass an optional data parameter to some callbacks, but only to callbacks that support a single parameter; right now, I have a moderately-sized code base of callbacks that cannot accept a parameter at all. How can I check what parameters a Function object supports?
Function is an Object.
Every function has a read-only property named length that stores the number of parameters defined for the function.
Use it.
If your function is declared in a class use the function describeType it will return an XML you can parse and look at your function name with his arguments
The arguments array is an array of all the parameters passed into a function. Maybe that is what you are looking for?
function traceArgArray(x:int):void
{
for (var i:uint = 0; i < arguments.length; i++)
{
trace(arguments[i]);
}
}
Example taken from livedocs.adobe.com
I have a "format" method that works in a similar manner to the C# String.Format method, with the following signature:
In a class named StringTools:
/**
* Formats a string, based on C# String.Format method.
* #param raw A string with numbered tokens, such as "{0}, {1}"
* #param rest Values that replace the numbered tokens in raw.
*/
public static function format(raw:String, ...rest:*):String;
StringTools.format("{0}, {1}", "Hello", "World") returns the string "Hello, World" as expected. Now, I'm trying to get my logging class to use this method, but I'm having trouble passing the optional variables through. The signature of the method in the logging class is:
public static function infof(raw:String, ...rest:*):String;
If I pass "rest" directly into StringTools.format(raw, rest), it's passed in as an array, and not as a series of parameters, so if I call it liks this: infof("{0}, {1}", "Hello", "World"), I get the string "Hello,World, {1}", since it replaces the first token with the entire array of values.
I also tried constructing an arguments array, and calling the method like this:
var collectArgs:Array = [raw];
for (var i:Number = 0; i < rest.length; i++)
{
collectArgs.push(rest[i]);
}
var callFunction:Function = StringTools.format.call;
trace(callFunction.apply(null, collectArgs));
However, this traces "World,6". So, it looks like the parameters are shifted. So, I tried initializing collectArgs as [null, raw], and I get "Hello World,6. The number is {1}" again.
Am I doing something wrong? What is the correct way to pass optional parameters from one method that expects optional parameters to another method that expects optional parameters?
Thanks!
I think you are on the right lines using apply. This seems to do illustrate the behaviour you want:
static function f1(raw:String, ...rest:*):void
{
trace("f1: "+raw+" "+rest);
rest.unshift(raw);
f2.apply(null, rest);
}
static function f2(raw:String, ...rest:*):void
{
trace("f2: "+raw+" "+rest);
}
function passSomeArguments():void
{
f1("A",1,2,3);
}
EDIT: You need to pass 'null' as the 1st parameter to apply because the first parameter is what is considered to be 'this' when the function is called. Since the functions are static (and in any case have no dependency on 'this') you can pass null, but you must pass something.
You could also do something like this (of course this is not best implementation for the string formatting):
public static function format(raw:String, ...rest:*):String {
if (rest[0] is Array && rest.length == 1) {
rest = rest[0];
}
var r:RegExp = /(\{\d+\})/g;
var matches:Array = raw.match(r);
for (var i:Number = 0; i < rest.length; i++) {
raw = raw.replace(matches[i], rest[i]);
}
return raw;
}
Then your infof function would just look like this:
public static function infof(raw:String, ...rest:*):void {
var formatted = StringTools.format(raw, rest);
}
As mentioned in my comment, if you remove the call method from the end of you callFunction setter, then you do not need to supply null as the first argument. See http://livedocs.adobe.com/ to understand what the call method actually does, and what the first parameter is for.
As #stephen mentioned, it is a lot simpler to unshift your raw var onto the rest array, rather than building up a new one.
Actually, just found that it's my problem. It should work fine using the argument collection method described, as long as the first element in the arguments array is null. I'm not sure why null is necessary, but it works fine this way.
I am a Java programmer and need to work on a Flex/ActionScript project right now. I got an example of using ITreeDataDesriptor from Flex 3 Cookbook, but there is one line of actionscript code that's hard for me to understand. I appreciate if someone could explain this a little further.
public function getData(node:Object, model:Object=null):Object
{
if (node is Office) {
return {children:{label:node.name, label:node.address}};
}
}
The part that I didn't understand was "{children:{label:node.name, label:node.address}}". Office is simply a value object that contains two String properties: name and address.
The following return expression (modified from the question) ...
return {children:{label:node.name, body:node.address}}
... is functionally equivalent to this code ...
var obj:Object = new Object();
obj.children = new Object();
obj.children.label = node.name;
obj.children.body = node.address;
return obj;
The anonymous object returned in the question code complicates matters because it defines a property twice. In that case, the first declaration is used, and the subsequent one(s) are ignored. No compile-time or runtime error is thrown.
I think in Java you would call that a map or an associative array. In Javascript and Actionscript you can say this to create an object with certain properties:
var myobject = {
'prop1': 100,
'prop2': {
'a': 1
}
}
trace( myobject.prop1 ); // 100
trace( myobject.prop2.a ); // 1
In your example it's just returned as a nameless object.
return {children:{label:node.name, label:node.address}};
Means you are returning a new Object. The {} are the Object's constructor, and in this case its an Anonymous object.
Thank you both for the quick response. So if I understand your explanations correctly, the return statement is returning an anonymous object, and this object has only one property named "children", which is again an associative array - ok, here is the part I don't quite understand still, it seems that both properties in this array are named "label", is this allowed?