Monday, July 2, 2007

Get/Set in ActionScript 3 Explained

Introduction

If you have seen ActionScript 3 in Flash CS3 or Flex 2, you may have noticed the get and set statements. Correctly written, these statements follow this format (minus ASDoc comments and bindable metadata tags):

public function get name():String {
return _name;
}

public function set name(value:String):void {
_name = value;
}
Note that the private class variable is _name. This is a standard for get/set methods and somewhat a standard for any private variable in Flex. The underscore (_) is required because the functions are named the same as the variable and the compiler (and those viewing the code) would be confused as to which was being referenced.

Naming the set parameter "value" is a common practice and works well when renaming variables.


What Do get/set Offer?

They act as if the class had a public variable but allow you to do more. If this is to be a read-only property, simply provide only the get function. If this is to be a write-only property (rare), simply provide only the set function. You may also write code to do additional work such as log something, check permissions, set a different variable, or do extra business logic.


ASDoc get Methods

It is a little odd to ASDoc these methods. Remember Get methods should come before set methods. The get should be documented with a short explanation of what the variable represents.
/**
* The first name provided by the credit card
*/
private function get firstName():String {
return _firstName;
}
Remember, just like in Java, documentation of the "firstName" property of the "Person" class shouldn't say "The first name of the person". Offer something more to the reader. Where could the first name come from (credit card, typed by person, typed by customer service agent, parsed from fullName)? What letters could it contain? Could a middle initial exist here?


ASDoc set Methods

Documenting the set methods is a little different. Since the meaning of the variable was explained in the get, it does not need to be repeated in the set. To accomplish this, mark the set as private in the ASDoc.
/**
* @private
*/
private function set firstName(value:String):void {
_firstName = value;
}
This will produce one comment in the generated documentation.

See the livedocs reference for more information:

http://livedocs.adobe.com/flex/201/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&file=asdoc_127_9.html


Bindable get/set Methods

Normally, I mark the class as Bindable so all get/set methods are marked as bindable. It does so with an event named "variableChange" where variable is the get/set method name. Simply putting [Bindable] just above your class definition will accomplish this.

If you need more control, you may write the following at the top of your get method (assuming this is the firstName property):
[Bindable(event="firstNameChange")]
This works the same for public variables. See livedocs for more information:

http://livedocs.adobe.com/flex/201/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&file=asdoc_127_9.html


In Other Languages

Java uses getFirstName() and setFirstName() functions which can be generated by NetBeans using the "refactor" option (also has a keyboard shortcut). They don't name the private variables differently because there is no need. The parameter for the setFirstName is typically the same as the private variable and is assigned by stating: this.firstName = firstName;

VB6 had the get/set functionality in the form of: public property let, public property set, and public property get. Where let was by value and set was by reference (for Objects).

I'm sure there are plenty of other implementations.


My 2 Cents

I use these for every private variable; however, it is much easier to have a public variable and change it to private scope and write get/set functions later if you ever need to do more processing or if you like the ASDoc output better. This does not change the API for the class and allows it to be written much faster.

I like the Flex method the best for simple getters/setters; however, if the function does more work than meets the eye, it should be written as normal get/set methods. This allows you to provide more parameters and alerts users of the class that it may do some additional processing.