Is it possible to intercept attribute getting/setting in ActionScript 3? - actionscript-3

When developing in ActionScript 3, I often find myself looking for a way to achieve something similar to what is offered by python's __getattr__ / __setattr__ magic methods i.e. to be able to intercept attribute lookup on an instance, and do something custom.
Is there some acceptable way to achieve this in ActionScript 3? In AS3 attribute lookup behaves a little differently for normal (sealed) and dynamic classes -- ideally this would work in the same way for both cases. In python this works beautifully for all kinds of objects (of course!) even for subclasses of dict itself!

Look a the flash.utils.Proxy object.
The Proxy class lets you override the
default behavior of ActionScript
operations (such as retrieving and
modifying properties) on an object.

In AS3 you can code explicit variables accessors.
Example Class1:
private var __myvar:String;
public function get myvar():String { return __myvar; }
public function set myvar(value:String):void { __myvar = value; }
Now as you create an instance of Class1 you can access __myvar through the accessor functions.
if you want to set bindable that var you have to put the [Bindable] keyword upon one of its accessors.
Further, you can also implement the getter or the setter only, so your var will be read or write only.
I hope it helps.

Related

Return read-only ui component in Flex

In Flex, I want to create some variable that would hold a dictionary of ui components used throughout my application. Ideally, there would be a function in Application component that would return component for id:
public function getComponent4Id(id:String):UIComponent {}
Then I would access component using the following line:
var myComponent:UIComponent = FlexGlobals.topLevelApplication.getComponent4Id("someId");
Now, the only problem is: I want the component returned to be read-only.
It is very convenient to read some properties of myComponent from every corner of application, but I don't want my developers to abuse it and change myComponent.
Is it possible to return a copy of myComponent? Or is it possible to make it read-only somehow?
In the situation you describe, it is not possible to retrieve read only components.
You can create read only variables by implementing get methods without set methods. Something like this:
public var get myValue():UIComponent{
return UIComponent;
}
This would allow you to retrieve the UIComponent instance, myValue, from the component; but you would not be able to set it.
However, this would not prevent people from changing properties on the returned UIComponent unless those properties were also implemented as read only.
I'll add that there is already a method, getChildByName() to retrieve a child component by name. If you have an instance to a parent, you can use this to access the children.
All that said, I'm not sure I completely understand what you hope to achieve; with this functionality.

Is there a way to access entry point class object from other classes of the app?

Just wonder if I can reference entry point object from any place in the app? Is it maybe assigned to some global object, like stage is for example?
Currently I use static methods and variables, but this breaks encapsulation.
If someObject is in display list, then you have a someObject.root reference which is what you are looking for. If you remove someObject from display list, you loose that reference.
My answer is no, there is no direct way to access entry object, and there shouldn't be: that's what incapsulation is about. Accessing something globally is pretty much AS1 way. When you access main instance by implicitly referencing MainClass, you make parts of your application tightly coupled, which is generally bad.
However, if you do need to have it, you may choose from several options.
Use static var: MainClass.instance
Use singletone-like access through MainClass.getInstance()
Create a package-level variable or a package level getter method
I would choose the latter.
package com.smth.application
{
public var mainObject:MainClass;
}
// in main app
package com.smth.application
{
public function MainClass()
{
mainObject = this;
}
}
It may look somewhat similar to static acces, but I think this way your code will retain some flexibility.
stage is a reference to the top level of your application, which you can access though any display object that is on the display tree as myDisplayObject.stage. When using a custom document class, it will be the first child (index 0) of stage, unless you manually force something else into the 0 index as Bakapii says.

Actionscript-3 prototype inheritance

Basically, I want to modify the constructor of the Object
class. Since every class extends Object, I hope whenever any
object of any class is instantiated, the modified function will
be called.
So I did this :
Object.prototype.constructor = function (){
trace("it was called;");
};
and put a breakpoint on the trace statement.
But it didn't stop there.
The trace statement did not get executed also.
Any solutions/suggestions?
In which context are you coding?
If you're using the Flex Compiler MXMLC (default, if you're in FlashBuilder), than you could add the compiler option -es. This should make AS3 feel more like AS2 and JS and support the prototype chain inheritance.
-compiler.es alias -es
"use the ECMAScript edition 3 prototype based object model to allow dynamic overriding of prototype properties. In the prototype based object model built-in functions are implemented as dynamic properties of prototype objects. (advanced)"
I don't know, if this plays well with all the extensions Adobe added to the ECMA Script standard, like packages, namespaces and classes. But you could give it a try.
I don't think it's possible in AS-3, but it was in AS-2.

Resolve parameters with a custom class

I have a Domain Specific Language, and I would like to register objects that can be instantiated inside.
For instance a class that can do httprequests.
[IoC("HttpRequest", typeof(DslScriptObject), IoCAttribute.IoCLifestyleType.Transient)]
internal class WebRequestDslObj : DslScriptObject
{
[DslNew]
public WebRequestDslObj() : this(null, null)
{}
[DslNew]
public WebRequestDslObj([DslParam("uri")]string uristring, [DslOptionalParam("contenttype")] string contenttype) : this(uristring, null)
{}
}
I then have a class that maps types from my dsl datatypes to c# datatypes (I have them as an IList if that makes any difference), and this works ok, if I do not use Castle to instantiate the object.
But as soon as I want to use IoC to autoregister the various types, then I dont know what to do about the constructors. I have tried to look at setting a CustomComponentActivator, but I got stuck at not being able to find any good example or documentation. Is that a viable path to take? (and will I be able to get around the funny special case for null parameters?)
Anyone have an example of where I can start?
So what are you trying to do with Windsor, because I'm not sure I see where you're going with it...
If you want to affect how component gets register in Windsor, for example rename parameters, you can write custom ComponentModel construction contributor to do it.

Registering derived classes with reflection, good or evil?

As we all know, when we derive a class and use polymorphism, someone, somewhere needs to know what class to instanciate. We can use factories, a big switch statement, if-else-if, etc. I just learnt from Bill K this is called Dependency Injection.
My Question: Is it good practice to use reflection and attributes as the dependency injection mechanism? That way, the list gets populated dynamically as we add new types.
Here is an example. Please no comment about how loading images can be done other ways, we know.
Suppose we have the following IImageFileFormat interface:
public interface IImageFileFormat
{
string[] SupportedFormats { get; };
Image Load(string fileName);
void Save(Image image, string fileName);
}
Different classes will implement this interface:
[FileFormat]
public class BmpFileFormat : IImageFileFormat { ... }
[FileFormat]
public class JpegFileFormat : IImageFileFormat { ... }
When a file needs to be loaded or saved, a manager needs to iterate through all known loader and call the Load()/Save() from the appropriate instance depending on their SupportedExtensions.
class ImageLoader
{
public Image Load(string fileName)
{
return FindFormat(fileName).Load(fileName);
}
public void Save(Image image, string fileName)
{
FindFormat(fileName).Save(image, fileName);
}
IImageFileFormat FindFormat(string fileName)
{
string extension = Path.GetExtension(fileName);
return formats.First(f => f.SupportedExtensions.Contains(extension));
}
private List<IImageFileFormat> formats;
}
I guess the important point here is whether the list of available loader (formats) should be populated by hand or using reflection.
By hand:
public ImageLoader()
{
formats = new List<IImageFileFormat>();
formats.Add(new BmpFileFormat());
formats.Add(new JpegFileFormat());
}
By reflection:
public ImageLoader()
{
formats = new List<IImageFileFormat>();
foreach(Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if(type.GetCustomAttributes(typeof(FileFormatAttribute), false).Length > 0)
{
formats.Add(Activator.CreateInstance(type))
}
}
}
I sometimes use the later and it never occured to me that it could be a very bad idea. Yes, adding new classes is easy, but the mechanic registering those same classes is harder to grasp and therefore maintain than a simple coded-by-hand list.
Please discuss.
My personal preference is neither - when there is a mapping of classes to some arbitrary string, a configuration file is the place to do it IMHO. This way, you never need to modify the code - especially if you use a dynamic loading mechanism to add new dynamic libraries.
In general, I always prefer some method that allows me to write code once as much as possible - both your methods require altering already-written/built/deployed code (since your reflection route makes no provision for adding file format loaders in new DLLs).
Edit by Coincoin:
Reflection approach could be effectively combined with configuration files to locate the implmentations to be injected.
The type could be declared explicitely in the config file using canonical names, similar to MSBuild <UsingTask>
The config could locate the assemblies, but then we have to inject all matching types, ala Microsoft Visual Studio Packages.
Any other mechanism to match a value or set of condition to the needed type.
My vote is that the reflection method is nicer. With that method, adding a new file format only modifies one part of the code - the place where you define the class to handle the file format. Without reflection, you'll have to remember to modify the other class, the ImageLoader, as well
Isn't this pretty much what the Dependency Injection pattern is all about?
If you can isolate the dependencies then the mechanics will almost certainly be reflection based, but it will be configuration file driven so the messiness of the reflection can be pretty well encapsulated and isolated.
I believe with DI you simply say I need an object of type <interface> with some other parameters, and the DI system returns an object to you that satisfies your conditions.
This goes together with IoC (Inversion of Control) where the object being supplied may need something else, so that other thing is automatically created and installed into your object (being created by DI) before it's returned to the user.
I know this borders on the "no comment about loading images other ways", but why not just flip your dependencies -- rather than have ImageLoader depend on ImageFileFormats, have each IImageFileFormat depend on an ImageLoader? You'll gain a few things out of this:
Each time you add a new IImageFileFormat, you won't need to make any changes anywhere else (and you won't have to use reflection, either)
If you take it one step further and abstract ImageLoader, you can mock it in Unit Tests, making testing the concrete implementations of each IImageFileFormat that much easier
In vb.net, if all the image loaders will be in the same assembly, one could use partial classes and events to achieve the desired effect (have a class whose purpose is to fire an event when the image loaders should register themselves; each file containing image loaders can have use a "partial class" to add another event handler to that class); C# doesn't have a direct equivalent to vb.net's WithEvents syntax, but I suspect partial classes are a limited mechanism for achieving the same thing.