Cannot Invoke Method On An Object Of Type coldfusion.runtime.VariableScope With Named Arguments

Posted March 12, 2007 at 8:24 AM

Tags: ColdFusion

I am getting a very strange error when I try to scope a private method within a ColdFusion component. I have this very simple ColdFusion component:

 Launch code in new window » Download code as text file »

  • <cfcomponent
  • output="false">
  •  
  • <cffunction
  • name="PrivateMethod"
  • access="private"
  • returntype="string"
  • output="false"
  • hint="Returns an updated string.">
  •  
  • <!--- Define arguments. --->
  • <cfargument name="Value" type="string" required="true" />
  •  
  • <!--- Return formatted string. --->
  • <cfreturn ("<strong>" & ARGUMENTS.Value & "</strong>") />
  • </cffunction>
  •  
  •  
  • <cffunction
  • name="CallMethod"
  • access="public"
  • returntype="void"
  • output="false"
  • hint="Invokes the private method.">
  •  
  • <cfset VARIABLES.PrivateMethod(
  • Value = "Crazy Bananas!"
  • ) />
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>
  •  
  •  
  • <cffunction
  • name="Debug"
  • access="public"
  • returntype="void"
  • output="true"
  • hint="Dumps out private variables.">
  •  
  • <cfdump
  • var="#VARIABLES#"
  • label="VARIABLES Scope Dump"
  • />
  •  
  • <cfabort />
  • </cffunction>
  •  
  • </cfcomponent>

It does absolutely nothing. It has one private method named "PrivateMethod". It has two public methods; one, Debug(), that dumps out the variables scope, and another, CallMethod(), that invokes the private method in the VARIABLES scope using named arguments.

Now, if I call the Debug() method on this ColdFusion component I get:


 
 
 

 
ColdFusion Component Variables Scope CFDump  
 
 
 

As you can clearly see, the method PrivateMethod() is clearly within the VARIABLES scope of this component. However, when I try to call CallMethod():

 Launch code in new window » Download code as text file »

  • <!--- Create CFC instance. --->
  • <cfset objTest = CreateObject( "component", "Test" ) />
  •  
  • <!--- Invoke method (which calls private method). --->
  • <cfset objTest.CallMethod() />

... I get this ColdFusion error:

Cannot invoke method PrivateMethod on an object of type coldfusion.runtime.VariableScope with named arguments. Use ordered arguments instead.

Now, I have two options to fix it here. I can either take out the names arguments to the PrivateMethod() function:

 Launch code in new window » Download code as text file »

  • <cfset VARIABLES.PrivateMethod(
  • "Crazy Bananas!"
  • ) />

... and just use ordered arguments (values are assigned to arguments in the same order in which they were passed). Or, I can simply not use the a method scope when invoking the private method and let ColdFusion search for the appropriate method:

 Launch code in new window » Download code as text file »

  • <cfset PrivateMethod(
  • Value = "Crazy Bananas!"
  • ) />

Both of the "solutions" will allow the code to execute fine. But, of course, this should not be the case. There is no reason that I can see that I should not be able to invoke a private method using its scope.

Any one have any ideas? Is this a bug? Am I just not seeing something?

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Permalink  |  Other Searches  |  Print Page



Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Mar 12, 2007 at 8:48 AM // reply »
76 Comments

Cool. I knew about the variables.methodcall(namedArg="blah") because I tried it a while back. I just settled on taking out the reference to variables though, since I don't think it does anything for the readability of the program in that case (actually degrades it, imo). But I didn't know I could simply have used ordered arguments.

Strange stuff... keep us updated =)


Mar 12, 2007 at 8:59 AM // reply »
6,516 Comments

I head what you are saying on readability. My issues it that I like using the THIS scope when referencing public method within the same CFC. I learned to do this after I once had an ARGUMENTS key and a method name conflicting (it kept trying to invoke the argument "Commit" like it was a method (in the THIS scope)).

So anyway, if I use the THIS scope for public method invocation, which to me ups the readability (very clear what I am referring to), I figure I should use the VARIABLES scope for private methods in order to keep things very consistent.


Mar 12, 2007 at 9:12 AM // reply »
76 Comments

I agree with that - certainly in my mind if you can do this.publicmethod() you should be able to do this.privatemethod(). And adding the fact that you can use it with ordered arguments just strengthens the case.


Nov 29, 2007 at 5:20 PM // reply »
2 Comments

I had the same problem today invoking a function in the request scope. We typically copy our UDFs into the request scope so we can reference them from within CFCs.

The original code was:
<cfset var convRate = request.getConversionRate(foo = bar)>

The error was:

Cannot invoke method getConversionRate on an object of type coldfusion.runtime.RequestScope with named arguments.
Use ordered arguments instead.

The bizarre workaround was to create a copy of the function as a local variable and then invoke that copy instead. E.g.

<cfset var getConversionRate = request.getConversionRate>
<cfset var convRate = getConversionRate(foo = bar)>

This is pretty lame. Using ordered arguments wasn't an option because I have multiple optional arguments in my function.


Nov 29, 2007 at 5:36 PM // reply »
6,516 Comments

@Leon,

Yeah, I am not sure what the problem is with it. It must be some weird wiring issue behind the scenes that makes it very complicated. Cause to me, a scope is a scope is a scope.


Oct 3, 2009 at 12:41 AM // reply »
26 Comments

@ben

The variables scope of a component is part of the class definition, not an object instance definition. You can use it for class methods, class constants, et al.

The this scope of a component is part of an object instance definition. You can use it for instance methods, instance properties, et al.

The problem is that ColdFusion has confusing syntax. Implicit scope = variables, unless it = url, form, or other. Explicit scope this. Don't even get me started on the super variable, and how it's a class variable, not an object instance variable. [Say what?]

What's more, is that createObject doesn't necessarily create an object instance. [Say what?] It just creates a reference to the class. You can double check this by creating Java objects. You need to call object=Class.init() to actually get an object instance.

You can't call a private method as a class method. You can only call a private method from an instance.

You called variables.privateMethod, which basically treats the call as if it originated from outside the class. Hence, like a class method.

COldFusion wants you to always use this.privateMethod, which treats the call instead as if it originated from inside the class. Hence, an instance method.

Examples are psuedocode-ey.

This is what you did:

component
function privateMethod private
function publicMethod public
variables.privateMethod

Which is the same as this:

x = createObject(component, foo).privateMethod()

You need to do this:

component
function privateMethod private
function publicMethod public
this.privateMethod


Oct 31, 2009 at 10:09 PM // reply »
6,516 Comments

@Alex,

I think that some of what you're saying is on the money. However, calling a method on the variables scope is not the same as calling it on the public face of the component instance.

The reason that you cannot use named arguments on calling the variables scope is because ColdFusion simply doesn't allow it. This, however, is something that is changing in CF9.


Post Comment  |  Ask Ben

Recent Blog Comments
Nov 21, 2009 at 6:47 PM
Hal Helms - Real World Object Oriented Development, Sarasota - Day Five
@charlie griefer, Thank you.. ... read »
Nov 21, 2009 at 5:15 PM
Using ColdFusion Structures To Remove Duplicate List Values
@Jose Galdamez, Oh heh yeah I didn't paste the whole code. I should have defined the vars -- my bad. It's fixed thou. Thanks. ... read »
Nov 21, 2009 at 4:49 PM
Styling The ColdFusion 8 WriteToBrowser CFImage Output
Great work yet again Ben! Whilst I didn't use this whole code, I copied some of your regex code for a similar problem with the lack of an alt attribute and unescaped ampersands in CFIMAGE for Railo 3 ... read »
Nov 21, 2009 at 1:13 PM
My First ColdFusion Builder Extension - Encrypting And Decrypting CFM / CFC Files
@Ben, Because I am pedantic, I just want to make sure that everyone knows there is absolutely no encryption going on. There is only encoding and obfuscation. The cfencode tool only obfuscates your C ... read »
Nov 21, 2009 at 12:28 PM
Using ColdFusion Structures To Remove Duplicate List Values
@Jody I can't seem to get your code sample to work. If you are still having problems, try this code out and see if it gets you what you wanted. <!--- Comma delimited list with various duplicates ... read »
Nov 21, 2009 at 11:03 AM
Groovy Operator Overloading Does Not Work In The ColdFusion Context
Hi Ben, Thanks for this informative post. Now I am reading ur old posts too ... read »
Nov 21, 2009 at 10:56 AM
HostMySite.com Has The Best ColdFusion Hosting
@Mehul, Yes very nice people, however several downtimes per day which was not acceptable. Hence we had to move out. I am glad you are having good luck with them so far. ... read »