I am experiencing an unexpected issue with ColdFusion Markup Language. Let's say I have the following components. If both a public and a private function are defined in a "base" component, can the former still invoke the private one when called from an extending "sub" type's instances?
Program.cfc
<cfcomponent>
<cffunction access="public" name="doOperation">
<cfset this.checkValue(-14)>
</cffunction>
<cffunction access="private" name="checkValue">
<cfargument name="notNeg" required="yes" type="numeric">
<cfif arguments.notNeg LT 0 >
<cfthrow message="Negative Numbers not allowed">
</cfif>
</cffunction>
</cfcomponent>
SubProgram.cfc
<cfcomponent extends="Program">
</cfcomponent>
Run.cfm
<cfobject component="SubProgram" name="this.instance">
<cfset this.instance.doOperation()> <<<<----ERROR---->>>>
ColdFusion throws the error
method
checkValuewas not found in componentSubProgram. Ensure that the method is defined...
What is the issue here? No brownie points for encapsulation!
The issue is that you're trying to call the
checkValue()method as a public method.thisdoes not work in CFML the same way as it does in other languages (a very poor design decision on the part of Macromedia):thisis an external reference to the object itself, so if you callthis.someMethod(), that's trying to call apublicmethod calledsomeMethod()(as if you were callingmyObject.someMethod()). In CFML parlance, thevariablesscope is the reference to private data/members.What you want to do is this:
Or simply:
Also, if you're using a recent version of CF (eg: CF10 or CF11) you really want to not write your components in tags. It makes for pretty awful-looking code. Try to limit tag usage to view files. CF10 still doesn't have 100% support for all CFML constructs in script, but CF11 does.