简体   繁体   English

Coldfusion代理混淆

[英]Coldfusion Proxy confusion

I am using a proxy/delegate pattern in a coldfusion component, and am getting unexpected results (from my point of view). 我在Coldfusion组件中使用代理/代理模式,并且得到了意外的结果(从我的角度来看)。 Below is my proxy component - its pretty straight forward, I just init the CFC with the actual component I want to delegate to, and then map the named functions from that CFC through to a proxy function (the below is simplified for this example) 以下是我的代理组件-非常简单,我只是将CFC与要委托的实际组件一起初始化,然后将命名功能从该CFC映射到代理功能(此示例的以下内容得到简化)

I have created a proxy component as follows: 我创建了一个代理组件,如下所示:

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;
    }
}

From my application I call the following code: 从我的应用程序中,我调用以下代码:

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

Now, in the above scenario, I would expect my proxy component to map the getApplicationData() function straight through to the original myFusebox component (via my proxy() function). 现在,在上述情况下,我希望我的代理组件将getApplicationData()函数直接映射到原始myFusebox组件(通过我的proxy()函数)。

That function in the underlying component is as follows: 基础组件中的功能如下:

<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>

That proxy all works fine, however, once I am in the above function in the original myFusebox I get the following error: 该代理一切正常,但是,一旦我在原始myFusebox中处于上述功能中,就会收到以下错误:

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

And if I dump " this " inside that function, it actually dumps my proxy object. 如果我在该函数中转储“ this ”,它实际上会转储我的代理对象。

Can anyone explain this or what I have done wrong? 谁能解释这个或我做错了什么? I was expecting that once the function call was inside the underlying object, it would just use its own context from there (my proxy just being a pass through really to the delegate) 我期望一旦函数调用进入基础对象内部,它便会从那里使用它自己的上下文(我的代理实际上是真正传递给委托的对象)

I think this is the key point: 我认为这是关键点:

I was expecting that once the function call was inside the underlying object 我期望一旦函数调用位于基础对象内部

You've got this: 你有这个:

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;
}

When you do this bit: 当您执行此操作时:

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

you are effectively pulling the function referenced by local.functionName out of variables.myFusebox , and putting it into the current function, within the context of your MyFuseboxProxy instance. 您实际上是在MyFuseboxProxy实例的上下文中,将MyFuseboxProxy引用的local.functionName variables.myFusebox 拉出 ,并将其放入当前函数中。

So when you do this: 因此,当您执行此操作时:

var local.returnVal = local.function( argumentCollection=arguments );

You are not running variables.myFusebox[local.functionName]() (so in the context of variables.myFusebox ), but you are running local.function() (so in the context of your proxy object). 您没有在运行variables.myFusebox[local.functionName]() (因此在variables.myFusebox的上下文中),但是在运行local.function() (因此在您的代理对象的上下文中)。

I don't have the patience to try to follow your logic here, but I am still surprised you get that error. 我没有耐心尝试在此处遵循您的逻辑,但令您感到困惑的还是令我感到惊讶。 I would have expected this to happen: 我原本希望发生这种情况:

  1. local.function (a reference to getApplicationData from variables.myFusebox ) runs getApplication() . local.function (对variables.myFuseboxgetApplicationData )运行getApplication()
  2. getApplication() in the context of the MyFuseboxProxy instance should be a reference to variables.proxy() . MyFuseboxProxy实例上下文中的getApplication()应该是对variables.proxy()的引用。
  3. variables.proxy() resolves the proxied function as getApplication() , and pulls that out of variables.myFusebox , and runs it in the context of your MyFuseboxProxy instance. variables.proxy()将代理函数解析为getApplication() ,并将其从variables.myFusebox拉出,并在MyFuseboxProxy实例的上下文中运行它。
  4. You do not include the code of the getApplication() function from variables.myFusebox , so I dunno what would happen next, but this is not what you want to be happening. 您没有包含来自variables.myFuseboxgetApplication()函数的代码,因此我不知道接下来会发生什么,但这不是您想要发生的事情。

Anyway, the crux is - I think - that instead of running the functions inside variables.myFusebox , you're running them in your MyFuseboxProxy instance instead. 无论如何,症结是-我认为-而不是在variables.myFusebox内部运行函数,而是在MyFuseboxProxy实例中运行它们。 If you want to do this sort of proxying (and ignoring for a moment you have invoke() specifically for doing this), you need to still call the function in its original context, not reference it in some new context. 如果要进行这种代理(并且暂时忽略专门用于执行此操作的invoke() ),则仍需要在其原始上下文中调用该函数,而不是在某些新上下文中对其进行引用。

I guess you're doing all this horsing around because ColdFusion doesn't like this syntax: 我猜您正在做所有这些事情,因为ColdFusion不喜欢此语法:

someObject[someMethodName]()

It baulks at the []() notation. 它以[]()表示敬意。 However the solution is not this: 但是解决方案不是这样的:

someOutOfContextReference = someObject[someMethodName] result = someOutOfContextReference() someOutOfContextReference = someObject [someMethodName]结果= someOutOfContextReference()

It's this: 是这样的:

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

See the subtle difference? 看到细微的差别了吗?

ColdFusion functions are not intrinsically closures, which is what you'd need them to be to work the way you want. ColdFusion函数不是本质上的闭包,这就是您需要它们以所需方式工作的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM