In Python, I can create objects from JSON pretty easily. I can either populate classes or just create a generic object. I see that Chapel has a read method for JSON, but I'm not sure how to use it.
If I have:
class Fighter {
var subclass:string;
var level:int;
}
and a string:
s = "{'subclass':'Ninja', 'level':7}"
How do I get a Fighter object?
And are there methods like:
n = json.loads(s)
n['subclass'] # = 'ninja', but just as a field key
Or:
Hattori = Fighter.read(s);
Hattori['subclass'] # = 'ninja'
Thanks!
It would be possible to make something like json.loads(s) work by creating some particular type (e.g. JSONNode) and populating it.
However right now we can get something in your example to work:
class Fighter {
var subclass:string;
var level:int;
}
var mem = openmem();
var writer = mem.writer().write('{"subclass":"ninja", "level":7}');
var reader = mem.reader();
var f = new Fighter();
reader.readf("%jt", f);
writeln(f);
Note that the class instance currently has to be allocated before you read it. Or you can use a record, for which there isn't a nil value.
Related
I have a class
class Person{
String _fn, _ln;
Person(this._fn, this._ln);
}
Is there a way to get a list of variables and then serialize it? Essentially i want to make a toJson, but i wanted to have it generic enough such that key is the variable name, and the value is the value of the variable name.
In javascript it would be something like:
var myObject = {}; //.... whatever you want to define it as..
var toJson = function(){
var list = Object.keys(myObject);
var json = {};
for ( var key in list ){
json[list[key]] = myObject[list[key]] ;
}
return JSON.stringify(json);
}
Dart doesn't have a built in functionality for serialization. There are several packages with different strategies available at pub.dartlang.org. Some use mirrors, which is harmful for client applications because it results in big or huge JS output size. The new reflectable packages replaces mirrors without the disadvantage but I don't know if serialization packages are already ported to use it instead. There are also packages that use code generation.
There is a question with an answer that lists available solutions. I'll look it up when I'm back.
I have a column model like that:
...
{name:'password',index:'password', width:100},
{name:'type.name',index:'type.name', width:100},
...
My class like definitons:
var MyObject = function (password, type) {
this.password = password;
this.type = type;
};
var MyType = function (tname) {
this.tname = tname;
};
I populate my variables: like that:
var type = new MyType($('#typeList').val());
var myObject = new MyObject($('#password').val(), type);
I have a JSON data response from my server and some of it's elements are object as like type. When I want to show them at my grid its OK. However when I want to use addrowdata function I can not see anything at type column. I am doing like that:
$("#gridId").jqGrid('addRowData', myObject.password, myObject, "first");
class is the function that hold name, password etc. inside it. The problem is only with nested elements(I can see password etc. at my grid). addrowData fonction accepts an array but I send a abject that holds object. How can I convert my object of objects into a plaint object array?
Any ideas?
You should not use points in the name property! If needed you can use if in index or in jsonmap.
The usage of addRowData in your example seems me wrong. You should reread the documentation of addRowData method.
How can I achieve the following for any number of elements in the arg array? If it was a function, I'd use Function.apply(), but I can't figure out how to do it with the new operator.
var arg:Array = [1,2];
new MyClass( arg[0], arg[1] );
If you set up your class to accept a list of arguments using ... args you can pass in as many as you like. Then in the constructor you will access them just like a normal array.
class MyClass
{
public function MyClass(... args):void
{
//args is an Array containing all the properties sent to the constructor
trace(args.length);
}
}
Dont pass each element of the array, just pass the array.
var arg:Array = [1,2];
new MyClass(arg);
Then inside of your class, loop through the array.
It is unfortunately not possible, because there is no way to directly access the constructor method of a Class object.
Note: If you'd be using a Function object to make up your class (prototype inheritance), then it would be possible, but i figure, this is not an option for you.
You could work around the problem with a little (ugly) helper method, on which you can read about here: http://jacksondunstan.com/articles/398
As stated in the comments is is not possible to apply settings on the constructor, but you could use this trick to set properties on a new instance of a class (which should be public)
public function setProps(o:Object, props:Object):* {
for (var n:String in props) {
o[n] = props[n];
}
return o;
}
.. use it like this
var args:Object = {x:1, y:2};
var instance:MyClass = setProps( new MyClass(), args ) );
source:
http://gskinner.com/blog/archives/2010/05/quick_way_to_se.html
I am trying grab all the member variables in AS3, and then foreach one i would like to process it in various ways. I would need the name and then if it is a collection of some type I would like to loop through that collection as well. I am attempting to essentially serialize in a somewhat custom fashion.
Thanks!
If you're looking to serialize an object, you will definitely want to use JSON.
JSON basically converts objects into strings and also the other way round using an encode()/serialize() and decode()/deserialize() function.
There is a built-in JSON class in AS3, and it's really easy to use.
Once you do something like:
var myObject:Object = {};
var myObjectString:String = JSON.serialize(myObject);
After getting the string, you can do all your switch logic to manipulate each of your different variables and convert it back into an object via the deserialize() function.
You could use describeType. That returns information about the object as XML. By default, you can iterate over public properties in objects. You could try something like...
// the object to iterate over
var someObj:Object = {};
for(var prop:String in someObj) {
// check to see if its something you want to iterate over
if (someObj[prop] is Array) {
// iterator over the property here
}
}
I hope this answers your question.
So in actionscript 3, instances of the Object class can be used an as associative array:
var doNotHaveSexWith:Object = new Object();
doNotHaveSexWith['mum'] = new Person(...);
doNotHaveSexWith['dad'] = new Person(...);
doNotHaveSexWith['dave'] = new Person(...);
Say I have some class, and one of it's members is a read only 'Object' which contains my collection of people.
I think code readability takes a major hit if I return this 'Object', as how would the programmer know what to do with it?
The only way someone is going to know that it is a collection is if they read the code or the comments...
What's the best way to signal that an Object is a collection, rather than a simple object?
Options:
Create a dynamic class, simply
extending from Object, called
"AssociativeArray" or something, just
so the code becomes more readable...
Use something like the AS3
Datastructures Library, though this
seems like a bit of overkill.
Just append the word Collection to
the end of the variable name?
For example:
var hotPeopleCollection:Object = new Object();
hotPeopleCollection['me'] = new Person(...);
hotPeopleCollection['sandrasully'] = new Person(...);
What do you think?
Update: I've decided to go with a custom class extending Dictionary. This way I can wrap a sensible access function around the searching function: hasOwnProperty and give the class a meaningful name.
I chose Dictionary over Object for two reasons:
Dictionary makes more intuitive sense for a collection
Dictionary appears to perform at O(1) for searching. See this fairly
informal dictionary vs array vs object performance benchmark
Use a dictionary.
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/Dictionary.html
You can still use a string for your key, or any object for that matter.
var dict:Dictionary = new Dictionary();
var obj:Object = new Object();
var key:Object = new Object();
key.toString = function() { return "key" }
dict[key] = "Letters";
obj["key"] = "Letters";
dict[key] == "Letters"; // true
obj["key"] == "Letters"; // true
obj[key] == "Letters"; // true because key == "key" is true because key.toString == "key"
dict["key"] == "Letters"; // false because "key" === key is false
delete dict[key]; //removes the key
A lot of developer ( myself included ) will tell you: Never use an Object. You are basically blindfolding your compiler. Always either use a built in datatype or make your own. Now obviously you didn't know about dictionaries in this case, but as a general rule, if you think you want to use a plain old Object datatype, think again.
Update:
Another link you might find helpful:
http://www.gskinner.com/blog/archives/2006/07/as3_dictionary.html
I'll be contrary and spout the much-hated dynamic-type stance. Just use an Object. It is an associative array. The names of the variables and the context should make it clear enough. Don't make your code any more complicated than it needs to be. If you think it should be a class, make it a class. It it's a simple map, use an Object.
There's no reason to go overboard.