Coldfusion Proxy混淆

时间:2013-07-02 17:53:23

标签: coldfusion

我在coldfusion组件中使用代理/委托模式,并且从我的角度来看,我得到了意想不到的结果。下面是我的代理组件 - 非常简单,我只是使用我想委托的实际组件初始化CFC,然后将命名函数从该CFC映射到代理函数(以下简化为此示例)< / p>

我创建了一个代理组件,如下所示:

component output="false"{

    /** Constructor for proxy - requires an instance of myFusebox **/
    public MyFuseboxProxy function init( Required any myFb ){
        variables.myFusebox = arguments.myFb;
        return this;
    }

    this.do = variables.proxy;
    this.getApplication = variables.proxy;
    this.getApplicationData = variables.proxy;

    private any function proxy(){    
        var local.functionName = getFunctionCalledName();
        var local.function = variables.myFusebox[local.functionName];
        var local.returnVal = local.function( argumentCollection=arguments );

        return local.returnVal;
    }
}

从我的应用程序中,我调用以下代码:

    variables.myFusebox = new ab.MyFuseboxProxy( variables.myFusebox );
    variables.myFusebox.getApplicationData().startTime = now();

现在,在上面的场景中,我希望我的代理组件将getApplicationData()函数直接映射到原始的myFusebox组件(通过我的proxy()函数)。

底层组件中的该函数如下:

<cffunction name="getApplicationData" returntype="struct" access="public" output="false"
            hint="I am a convenience method to return a reference to the application data cache.">
    <cfreturn getApplication().getApplicationData() />
</cffunction>

该代理一切正常,但是,一旦我在原来的myFusebox中的上述函数中,我得到以下错误:

Message: Variable GETAPPLICATION is undefined.
StackTrace: coldfusion.runtime.UndefinedVariableException: Variable GETAPPLICATION is undefined.

如果我在该函数中转储“this”,它实际上会转储我的代理对象。

任何人都可以解释这个或我做错了什么吗?我期待一旦函数调用在底层对象中,它就会从那里使用它自己的上下文(我的代理只是真正传递给委托)

1 个答案:

答案 0 :(得分:1)

我认为这是关键点:

  

我期待一旦函数调用在底层内部   对象

你有这个:

private any function proxy(){    
    var local.functionName = getFunctionCalledName();
    var local.function = variables.myFusebox[local.functionName];
    var local.returnVal = local.function( argumentCollection=arguments );

    return local.returnVal;
}

当你这样做时:

var local.function = variables.myFusebox[local.functionName];

您正在有效地提取local.functionName的{​​{1}} out 引用的函数,并将其放入当前函数中variables.myFusebox实例的上下文中

所以当你这样做时:

MyFuseboxProxy

您没有运行var local.returnVal = local.function( argumentCollection=arguments ); (因此在variables.myFusebox[local.functionName]()的上下文中),但您正在运行variables.myFusebox(因此在代理对象的上下文中)。

我没有耐心试图在这里遵循你的逻辑,但我仍然感到惊讶你得到了这个错误。我原以为这会发生:

  1. local.function()(对local.function的{​​{1}}的引用)运行getApplicationData
  2. variables.myFusebox实例的上下文中的
  3. getApplication()应该是对getApplication()的引用。
  4. MyFuseboxProxy将代理函数解析为variables.proxy(),并将其从variables.proxy()中拉出,并在getApplication()实例的上下文中运行。
  5. 您没有在variables.myFusebox中包含MyFuseboxProxy函数的代码,所以我不知道接下来会发生什么,但这不是您想要发生的事情。
  6. 无论如何,关键是 - 我认为 - 不是在getApplication()内运行函数,而是在variables.myFusebox实例中运行它们。如果你想进行这种代理(并且暂时忽略了variables.myFusebox专门用于执行此操作),您仍需要在其原始上下文中调用该函数,而不是在某些新上下文中引用它。

    我猜你正在做这一切,因为ColdFusion不喜欢这种语法:

    MyFuseboxProxy

    它以invoke()符号表示无效。然而,解决方案不是这样的:

    someOutOfContextReference = someObject [someMethodName]    result = someOutOfContextReference()

    就是这样:

    someObject.someInContextReference = someObject [someMethodName]    result = someObject.someInContextReference()

    看到细微差别?

    ColdFusion函数本质上不是闭包,这就是你需要它们以你想要的方式工作。