3

This is a pretty basic question and I'm sure there's an answer somewhere but for the life of me I can't find it. Anyways, I had a lot of variables of a new instance of an object to change and, for fun mostly, I thought I'd try and shorten the syntax or chain it together. But I can't. Here's some example code:

var text = new TextObjectThing(0, 0, 500, "Text");
text.color = 0xFFFFFFFF;
text.size = 26;
text.scrollFactor.x = 0;
text.scrollFactor.y = 0;

as you can see you have to do that "text.property" thing several times. This is fine in a practical sense, but I was just wondering if anyone knew how to re-organise that a bit.

EDIT: I guess this would be important if you wanted/needed to have an anonymous object for some reason. You can't set those variables like that if it's anonymous.

3 Answers 3

3

You can use a trick to chain call without modify your Object :

var shape : Shape = new Shape;
// Chain property init
Initializer.init(shape).x(100).y(100).alpha(.5);

// Chain function call
Initializer.init(shape.graphics).beginFill( 0xFF0000 ).drawCircle( 100, 100, 50).endFill().beginFill( 0xFFFFFF ).drawCircle( 100, 100, 10).endFill();

addChild(shape);

And the initializer class :

package
{
    import flash.utils.Proxy;
    import flash.utils.flash_proxy;

    public dynamic class Initializer extends Proxy
    {
        // To avoid new instance
        private static var _instance : Initializer = new Initializer(null);;

        // Current target Object
        private var _target : Object;

        // Constructor
        public function Initializer(target : Object){
            _target = target;
        }

        // Call it to avoid new Initizer instance
        public static function init(target : Object) : Initializer{
            _instance._target = target;
            return _instance;
        }

        // Catch function call and return initializer to chain call
        override flash_proxy function callProperty(name:*, ... rest):* {
            if(_target)
            {
                // Emulate function setter
                if(_target.hasOwnProperty(name) && !(_target[name] is Function))
                    _target[name] = rest[0];

                // If not a property, call as a classic function
                else
                    _target[name].apply(_target, rest);
            }
            return this;
        }
    }
}

It is just for fun because proxy call add a very small time for each call, if you want to use it very very often (ex: 10000 per frame), it will be faster to use classic approach.

You can also use "with" keyword like (please note the ; char after constructor):

var tf : TextField = new TextField(); with(tf) {
    text = "Hello";
    alpha = .5;
    setTextFormat( new TextFormat( "Verdana", 16, 0xFF0000) );
}

Or chain when values are the same :

var text = new TextObjectThing(0, 0, 500, "Text");
text.scrollFactor.x = text.scrollFactor.y = 0;
Sign up to request clarification or add additional context in comments.

1 Comment

This is wrong for so, so many reasons! First, the instance is static. Which means: 1. this class works with a single instance at a time - you cannot use it multiple times; 2. it keeps reference to the object; 3. it can lead to tremendous errors, as some functions may return values that are needed, but you override them and return the instance so it can be chained; While it will actually work, I find it as absolute tragedy. I'm not downvoting as your answer is actually correct, but I find it necessary to say how bad idea it is :)
1

If you make methods return this, you can chain it.

public method setColor(hex:uint):this
public method setSize(size:Number):this

and then you can make

text.setColor(0xFFFFFF).setSize(26);

you can also make one method that will take many arguments, and to leave the default arguments unchanged

2 Comments

This is definitely a good solution, and I think the right one. But, just because I'm curious, is there a way to do this without editing the original object?
Yes, you can extend that object and then create methods that will return that object.
0

You can organize the relative properties together as a new data struct.

For example flash.text.TextFormat. It contains the properties could be used in text.

You could pass the data struct object instead of several separate properties.It will make your code more simple and clearer. For example, you want to copy same text style for from another text, you just need to get the textFormat of target text and set it to your text.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.