Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting multiple object variables in a chain?

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.

like image 892
Daniel Jones Avatar asked May 11 '26 02:05

Daniel Jones


2 Answers

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;
like image 81
Simon Eyraud Avatar answered May 14 '26 21:05

Simon Eyraud


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

like image 29
ThanksBro Avatar answered May 14 '26 19:05

ThanksBro



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!