Automatic Type Conversion in ColdFusion 11

你说的曾经没有我的故事 提交于 2019-12-12 11:30:43

问题


I am migrating an application from ColdFusion 9 to ColdFusion 11.

In the existing code there is an assignment of a variable to false:

<cfset VARIABLES.roleTypeId = false >

And then, farther down, a function that expects this variable to be numeric:

<cffunction name="rolesForStudy" >
    <cfargument name="id" hint="Study Id">
    <cfargument name="roleTypeId" default="#VARIABLES.roleTypeId#" type="numeric"/>
</cffunction>

I inherited the code, and I cannot defend the original programmer's decision to set it up this way -- but, in short, it worked in ColdFusion 9, and it doesn't work in ColdFusion 11 (returning a data type error). I assume that ColdFusion 9 was automatically converting false to 0.

My question: Is there a configuration setting that I can change in ColdFusion 11 to make it do the conversion like ColdFusion 9 did? Or will I have to fix this code, along with probably lots of other similar examples throughout the application? Neither I nor our ColdFusion administrator has been able to find any information about this in the ColdFusion Administrator interface, the ColdFusion documentation, or online.

Edit in Response to Adam Cameron in comments

I have created a file that consists of the following 10 lines (and nothing else):

<cfset VARIABLES.roleTypeId = false >
<cfoutput>
<p>#rolesForStudy( 1, VARIABLES.roleTypeId )#</p>
</cfoutput>

<cffunction name="rolesForStudy" >
    <cfargument name="id" hint="Study Id">
    <cfargument name="roleTypeId" default="#VARIABLES.roleTypeId#" type="numeric"/>
    <cfreturn "It worked" >
</cffunction>

When I execute it in ColdFusion 9, it displays the words "It worked".

when I execute it in ColdFusion 11, it returns the following error message:
If the component name is specified as a type of this argument, it is possible that either a definition file for the component cannot be found or is not accessible.


回答1:


I believe you will have to fix the code. There are no settings (that I know of at any rate) that alter the way CF handles boolean types. You should be able to change the assignement above from "false" to 0 and your function code will work. However I suspect elsewhere you might have something like <cfif variables.roletypeID IS "False"> which will then be broken as it is in truth looking for a string - which also works (ha). CF's handling of a myriad of values as boolean (0 or not 0, true, false, yes and no) is a legacy of it's origin. It's convenient at times but definitely leads to things like this.

Meanwhile I wonder if this change of behavior is a new bug or the fixing of an old bug. In my view passing "false" as an argument and having it read as numeric seems inconsistent so the new way of doing it seems right to me. However, many many languages treat 0 or not 0 as default values for true and false.

EDIT:

According to Adam's comments below, my example of code where someone would say:

<cfif somevar IS "false">

...would work even if somevar was indeed numeric. His example (useful) is that:

#0 is "False"#

...will output "yes" - so CF is recasting the string "false" to a zero under the hood for comparison. That makes my example incorrect.

My answer is still correct I believe. The issue he's running into is that the argument passed to his function - being of the type "boolean" is throwing an error because the function expects a numeric value. But Adam's point and example makes me think perhaps this behavior is a bug - since it appears CF is not casting to a number before checkign the type (something it did do in CF 9 according to the Joe).




回答2:


NumberFormat is your saviour, credit going to this comment on one of Ben Nadel's articles.

<cfset VARIABLES.roleTypeId = false>
#NumberFormat(VARIABLES.roleTypeId)# <!-- = 0 -->
<cfset VARIABLES.roleTypeId = true>
#NumberFormat(VARIABLES.roleTypeId)# <!-- = 1 -->

So you should be able to either convert it to the expected numeric type before calling the function, or just doing

<cfargument name="roleTypeId" default="#NumberFormat(VARIABLES.roleTypeId)#" type="numeric">



回答3:


I've raised this as a bug in ColdFusion 11: "Type coercion failure when passing boolean to a numeric arg".

I recommend you work around this by taking the type check off the argument. This is probably the lowest-impact fix.

This is also a rare case in which I'd add a comment to code, explaining why you've taken the type checking off.

Apologies to Joe, Mark & Duncan for emphatically contradicting what they were finding. That said, I don't agree that their answers are the best approach here ;-)



来源:https://stackoverflow.com/questions/27447751/automatic-type-conversion-in-coldfusion-11

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!