Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Actionscript 3 在运行时重新定义命名函数_Actionscript 3 - Fatal编程技术网

Actionscript 3 在运行时重新定义命名函数

Actionscript 3 在运行时重新定义命名函数,actionscript-3,Actionscript 3,我想做的有点奇怪,但我想知道是否有人能想出一个聪明的方法来做我想做的事。基本上,我想在运行时重新定义一个命名函数。我可以用匿名函数来实现这一点,但我想不出一种方法来实现命名函数。我希望这样做,以便能够在测试框架的对象上实现“间谍”功能(Jasmine到Flex的端口) 以此类为例: public class TestClass { public var anonymous:Function = function():void { trace("original anon

我想做的有点奇怪,但我想知道是否有人能想出一个聪明的方法来做我想做的事。基本上,我想在运行时重新定义一个命名函数。我可以用匿名函数来实现这一点,但我想不出一种方法来实现命名函数。我希望这样做,以便能够在测试框架的对象上实现“间谍”功能(Jasmine到Flex的端口)

以此类为例:

public class TestClass
{
    public var anonymous:Function = function():void { 
        trace("original anonymous"); 
    };

    public function named():void {
        trace("original named");
    }
}
我可以很容易地重新定义匿名函数,因为它只是一个变量。Javascript经常使用这个习惯用法

var testClass:TestClass = new TestClass();
testClass.anonymous = function():void { trace("overridden anonymous"); }
但是,当我对命名函数执行相同的操作时,会出现编译时错误:

// Does not compile
testClass.named = function():void { trace("overridden named"); }
我试图让它更“粘”一点,但这会导致运行时失败“无法分配给TestClass上命名的方法”


有比我更聪明的人能想出破解这个的方法吗?字节码能被劫持吗?什么?

我有一个关于制作函数“缓存”的想法。这可能适用于您需要的内容

假设您有一个类“Car”,其中包含一个需要在运行时重新定义的方法:

public class Car extends Sprite
{
    private var functionCache:Function;

    public function Car()
    {
        super();
    }

    public function flexibleFunction(functionBody:*=null):void{
        if(functionBody is Function){
            functionBody.call();
            functionCache=functionBody;
        } else {
            functionCache(functionBody);
        }
    }
}
用法:

public class Main extends Sprite
{
    private var car:Car;

    public function Main()
    {
        car = new Car();

        car.flexibleFunction(function(){trace("redefine test #1")});

        car.flexibleFunction();

        car.flexibleFunction(function(doParametersWork:String="let's see"){trace("redefine test #2: " + doParametersWork);});

        car.flexibleFunction("yes they do");

        car.flexibleFunction();

    }
}

要实现您想要的功能,一个简单的方法是将新函数传递给原始函数并从那里执行:

package
{
//Imports
import flash.display.Sprite;

//Class
public class RedefineFunction extends Sprite
    {
    //Constructor
    public function RedefineFunction()
        {
        originalFunction();

        originalFunction(redefinedFunction);
        }

    //Original Function
    public function originalFunction(redefinition:Function = null):void
        {
        if  (redefinition != null)
            redefinition();
            else
            trace("Original Function Definition");
        }

    //Redefined Function
    private function redefinedFunction():void
        {
        trace("Redefined Function Definition")
        }
    }
}
跟踪:

Original Function Definition
Redefined Function Definition
我想修改一个对象,而不是一个 阶级

但对象不包含函数,只包含非静态变量。我尝试使用
prototype
属性并替换那里的方法,但仍然调用原始方法,而不是注入方法


关于“hack”字节码,你是说“hack”已经在运行时加载了SWF吗?我认为这是不可能的。不过,我确信,您可以使用类似于as3swf的东西解析SWF,在字节码中查找方法,替换它并将结果保存到新的SWF中。

我对actionscript几乎一无所知,但听起来您想进行方法调用拦截/面向方面的编程。希望有人为此编写了一些代码,以便与actionscript配合使用。+1个好问题。我尝试扩展代理类,但没有解决您的问题。现在已经很晚了,所以我的想法可能不正确,但是你能不能扩展
TestClass
并用新功能覆盖命名函数?@Chris:是的,我总是可以扩展
TestClass
,但我想修改一个对象,而不是类。我不希望创建类似这样的模拟对象(ASMock、Mockito和Mockolate按照您的建议执行)。我想“监视”一个对象的功能。至少,我正试图在不需要新范式的情况下实现Jasmine拥有的相同功能(
spyOn(myObject,“theMethod”)
)。我很想知道这个问题的答案。如果你真的通过这里或外部找到了答案,请告诉我们。@Chris:看一个朋友指给我的真正的黑客。使用as3commons字节码加载SWF,拦截加载,解析字节码(使用as3commons API),使用修改的操作码重新编写类,并将新修改的SWF传递给加载程序。不确定我会走那么远。。。我们拭目以待。。。不过,有一些非常酷的选项可以这样做:)是的,它允许函数直接扩展,但不允许以这种方式编写的对象正常工作。如果我只是修改类以支持这样的函数更改,我只会转到匿名函数。我的目标是在任何对象上执行此操作,而不仅仅是编写为这样修改的对象。不过,谢谢。我能想到的另一件事是,一旦我(错误地)将一个SWF加载到我的应用程序中,它与我的应用程序中的现有类具有相同的包路径和类名。新代码代替旧代码运行。也许你可以在运行时重写定义灵活函数的类,看起来你可以这样做:然后再次尝试加载它?aaaand我刚刚意识到ruedaminute之前的答案与我的答案几乎相同。自我提示:在回答之前先阅读前面的答案。对:)但它并不能满足我的需要。。。注入一个我无法控制的物体。我认为有一种方法。。。做一些运行时AOP的愚蠢行为。。。但是怎么说呢?你说的“对象不包含函数,只包含非静态变量”是什么意思。命名函数像对象上的非静态变量(
object['funcName']()
)一样公开,但当它们是“命名函数”时,它们就是不可写的。即使修改原型确实有效,那仍然是修改类,而不是实例(对象)。我将调查as3swf。认为这仍然会影响到全班,尽管。。。当它是我关心的实例时,我的意思是对象实例不包含对其所有函数的引用,它们通过类进行解析,并且每个类存储一次,而不是每个对象。有一个全局函数getSize(),它为新建的空类上的对象报告24个字节。如果我添加新函数,这个数字不会改变。如果我给类添加数字,它会增加8个字节。对于记录,你是正确的。你问我“破解”字节码是什么意思。。。我指的是这种方法,它可以让你在运行时修改字节码。。。您可以在加载代码之前执行此操作。当然是哈奇。仍然很酷:
Original Function Definition
Redefined Function Definition