Вызываемые объекты на ActionScript? - PullRequest
0 голосов
/ 28 апреля 2010

возможно ли иметь вызываемые объекты на ActionScript? Например:

class Foo extends EventDispatcher
{
  Foo() { super(); }

  call(world:String):String
  {
    return "Hello, " + world;
  }
}

И позже ...

var foo:Foo = new Foo();
trace( foo("World!") );    // Will NOT work

Ответы [ 5 ]

0 голосов
/ 01 мая 2010

Один из вариантов - использовать замыкание:

public function Foo():Function {
    var bar:String;
    return function (world:String):String {
        var msg:String;
        if (bar) {
            msg = bar + ' says "Hello, ' + world + '"';
        } else {
            msg = "Hello, " + world;
        }
        bar = world;
        return msg;
    }
}
...
var foo = Foo();
trace( foo("World!") );

Это очень упрощенный случай более широкой схемы реализации объектов как функций. Как таковой, он более полезен в языках, которые поддерживают FP, но не ООП, но технически дают вам вызываемый «объект». Синтаксис может быть немного неправильным, но:

public function createFoo(barInit, ...):Function {
    var slots = {
        greeter: barInit, ...
    };
    var methods = {
        'get': function(name) { return slots[name]; }
        'set': function(name, value) { slots[name] = value; }
        greet: function(whom) {
            var msg = slots.greeter + ' says "Hello, ' + whom + '"'
            slots.greeter = whom;
            return msg;
        },
        ...
    };
    return function (method:String):* {
        args = Array.splice.call(arguments, 1);
        return methods[method].apply(null, args);
    }
}

var foo = createFoo('Kermit');
trace(foo('greet', "World"));
trace(foo('greet', "Sailor"));

Вы, вероятно, не хотите делать это в AS.

0 голосов
/ 01 мая 2010

Как уже говорили другие, вы не можете иметь вызываемые объекты. Однако, если по какой-то причине вы хотите иметь функции с состоянием, вы можете достичь этого с помощью статических переменных класса и функций уровня пакета. Например:

// com/example/foo/Helper.as
package com.example.foo {
    public class Helper {
        private static var _instance:Foo;

        public static var data:String;

        public static function get instance():Helper
        {
            if(!_instance) { _instance = new Helper(); }
            return _instance;
        }
    }
}

// com/example/foo/hello.as
package com.example.foo {
    public function hello(world:String):void
    {
        if(Helper.instance.data)
        {
            trace("Bye, " + Helper.instance.data);
        }
        trace("Hello, " + world);
        Helper.instance.data = world;
    }
}

При использовании он будет печатать разные вещи.

hello("World!");   // traces "Hello, World!"
hello("People");   // traces "Bye, World!" and "Hello, People"
0 голосов
/ 28 апреля 2010

Зачем вам это нужно? (Я не критикую, просто интересуюсь!) Функции в AS3 сами являются первоклассными гражданами и могут быть переданы в качестве аргументов.

, например

public function main(foo:Function):void
{
    trace(foo("World!")); // Will work, assuming foo = function(str:String):String {...}
}
0 голосов
/ 29 апреля 2010

Нет, только функции / методы могут быть вызваны таким образом. Если единственной причиной является то, что вы хотите ввести меньше символов, то вам следует сократить длину имен экземпляров и методов.

0 голосов
/ 28 апреля 2010

примечание: и конструктор, и объявление метода пропускают даже ключевые слова public function для компиляции, но я предполагаю, что это не оригинальный код :)

ответ: вы не можете.
мой вопрос: что вы хотите достичь?

Function s - единственные вызываемые значения. И Function s являются примитивами в ActionScript, так же, как int s или Boolean s, поэтому нет никакого значимого способа их расширения.

Если вы хотите, чтобы это был объект, сделайте это способом Java, определив интерфейс ICallable, и фактически вызовите метод, или просто используйте функцию. замыкания предоставляют наиболее простую и гибкую возможность создавать функции с состоянием, если вы этого хотите.

edit: ну, вы можете сделать это (как пример):

private var fooInst:Foo = new Foo();
protected var foo:Function = fooInst.call;

, а затем следующие работы, как вы хотите:

<mx:Label text="{foo('Whatever')}"/>

это может быть даже немного более гибко, хотя вы теряете преимущества строгой печати. ​​

Greetz
back2dos

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...