this.function() resolves to variables.function() instead of this.function()

Description

// testFunctions.cfc component { variables.variable = "variables"; variables.func = function (){ return "variables"; } public function init(){ this.variable = "this"; return this; } public function func (){ return "this"; } public function test(){ if (!structKeyExists(server, "lucee")) echo ("<h1>#server.coldfusion.productname# #server.coldfusion.productversion#</h1>"); else echo ("<h1>Lucee #server.lucee.version#</h1>"); echo('test: <b>func()</b> comes from <b>#func()#</b><br>'); echo('test: <b>this.func()</b> comes from <b>#this.func()#</b><br>'); echo('test: <b>variable</b> comes from <b>#variable#</b><br>'); echo('test: <b>this.variable</b> from from <b>#this.variable#</b><br>'); dumpVariableScope(); } function echo(x){ writeoutput(x); } public function dumpVariableScope(){ cfdump(var=variables); } } //index.cfm <cfscript> a = new testFunctions().init(); a.test(); dump(a.func()); // lucee returns variables here too dump(a); </cfscript>

Lucee returns

test: func() comes from variables test: this.func() comes from variables test: variable comes from variables test: this.variable from from this

Adobe returns

test: func() comes from variables test: this.func() comes from this test: variable comes from variables test: this.variable from from this

Lucee gets this wrong?

this.func() resolves to variables.func() instead of this.func()

https://dev.lucee.org/t/cfc-and-this-scope-to-call-a-method/7994/6

Environment

None

Attachments

5
  • 24 Feb 2021, 03:12 am
  • 24 Feb 2021, 02:49 am
  • 24 Feb 2021, 02:49 am
  • 24 Feb 2021, 02:49 am
  • 24 Feb 2021, 02:49 am

Activity

Show:

Michael Offner 17 May 2021 at 14:28

This only happens when the closure is set within the component body. I think the problem is that a closure creates a relation to it’s birthplace nad it seem in that case the relation is bidirectional, what it should not of course.

When you create the closure outside the body, for example inside the init function, all is fine.

Zac Spitzer 14 May 2021 at 13:46

test case checked in with the failing tests skipped

https://github.com/lucee/Lucee/commit/c676e919f44e34dc5e7b438ee5fe6fe012d66541

Adam Cameron 4 May 2021 at 07:34

I’ve extracted this from a DM conversation with , as I think it could be relevant

 

Looking at the line of code you point to, I'm left questioning whether a function expression should have any sense of access modifier, implicit or otherwise? And I can't quite decide on an answer, but at first blush I think Lucee has got it wrong. If anything the access modifier ought to be applied to the variable the function expression is assigned to, and not be something about the function expression, eg:

public f1 = function(){} private f2 = function(){}

think Lucee is getting confused by how tag syntax has to work, in that it needs to roll the access modifier into the <ffunction> tag, because there's nowhere else to put it, but method access is a quality of the component not the function. If you see what I mean. And that confusion has bubbled-out into script as well, by tightly coupling the access modifier to the function definition, not its context.

In the course of writing that I've decided Lucee is def going about things wrong, and CF has got it right here.

Pothys - MitrahSoft 24 February 2021 at 08:15

I've checked this ticket and confirmed the issue happened on lucee latest version 5.3.8.149-SNAPSHOT also. In component, while calling this.function() is resolved by the variables.function()(same function name) instead of this.function(). But calling this.variable is correctly resolved by this.variable. Seems ACF works correctly in this scenario.

Zac Spitzer 24 February 2021 at 04:04
Edited

is it possibly because closures are always created by default with Component.ACCESS_PUBLIC ? https://github.com/lucee/Lucee/blob/6.0/core/src/main/java/lucee/transformer/cfml/expression/AbstrCFMLExprTransformer.java#L1335

Coz, If I add (pseudo code as an inline component)

a = component { variables.func2 = function (){ return "variables2"; } } dump(a.func2()); // return variables2 (but variables aren't public)

I can access it from outside the cfc

if I prefix variables.func2 with public or private, it behaves as expected, throwing

component [testFunctions] has no function with name [func2]

Details

Assignee

Reporter

Priority

New Issue warning screen

Before you create a new Issue, please post to the mailing list first https://dev.lucee.org

Once the issue has been verified, one of the Lucee team will ask you to file an issue

Affects versions

Created 24 February 2021 at 00:52
Updated 8 July 2022 at 14:54

Flag notifications