tracker issue : CF-4187503

select a category, or use search below
(searches all categories and all time range)

String member functions don't cast

| View in Tracker

Status/Resolution/Reason: Closed/Fixed/Fixed

Reporter/Name(from Bugbase): brian king / brian king (brian king)

Created: 09/07/2016

Components: Language

Versions: 11.0

Failure Type: Usability Issue

Found In Build/Fixed In Build: CF11_Final / 2018,0,0,307622

Priority/Frequency: Normal / All users will encounter

Locale/System: English / Win 2008 Server R2 64 bit

Vote Count: 5

Problem Description:
.len() .trim() and other "string"-based member functions should cast values that are 'stringy" but not objects as string just as Len() and Trim() do now, to reduce confusion in code.  When used on values from query that are not varchar the error thrown is "The len method was not found."

Steps to Reproduce:

sampleQuery = QueryNew( "ID", "Integer" , {"id":1} );
WriteOutput( sampleQuery.ID.len() );

Actual Result:
Exception:  The len method was not found.

Expected Result:

Any Workarounds:
Use headless functions (Len(), Trim(), etc) as opposed to member functions ( .len(), .trim() )

----------------------------- Additional Watson Details -----------------------------

Watson Bug ID:	4187503

External Customer Info:
External Company:  
External Customer Name: brian king
External Customer Email:  
External Test Config: My Hardware and Environment details:



Problem occurred in a function where the datatype of the incoming value was not apparent, but passed the "typing" on the argument: (string ID). It would be better to overload the member functions to retain the typelessness of ColdFusion.
Comment by External U.
1864 | September 07, 2016 03:17:51 PM GMT
Probably will get the same treatment as, but still worth suggesting again.
Comment by External U.
1865 | September 07, 2016 03:23:58 PM GMT
This ER doesn't really make sense. Methods act on the object they're called on, where the object is of a specific type or implementation. So the method needs to exist in the object implementation. Which - in the example provided - is not the case as an int doesn't have a len() method. Even if it did, then one would not expect it to work like a string len() method; it'd more like return the size of the int in bytes or something (which is pretty pointless, and more likely to be a static method on the int class). The issue here is the developer just needs to understand how OO works, if I'm to be brutally honest. This is a negative vote for this, it'd be a mistake in language design to take this one fwd.
Comment by External U.
1866 | September 07, 2016 08:06:08 PM GMT
I think this ER does make sense. CFML is typeless (or at best, loosely typed) so it is improper to refer to objects as a specific "type", at least in the sense that the compiler or developer declaratively enforces. What can be done with a variable is a runtime decision based on that code the developer writes and the back-end Java classes used to store the value is an (unimportant) implementation detail. Member functions are IMO syntactic sugar for BIFs, not proper methods on proper objects of any explicit type. If you treat a variable as a date with a date BIF or as a string with a string BIF, that variable for all intents and purposes _is_ a date or a string in each context. I don't see why member functions would be any different. A variable that can be treated as a date should allow you to call date member functions. And a variable that can be treated as a string should allow string member functions. The variable type is what you make it, and not something declared explicitly. The argument of ambiguity in type member functions is also a straw man IMO. Realistically, the only classes of member functions that would ever be interchangeable are string, list and date. All list functions have "list" in their name, and there is no overlap between actual string and date member functions that I can see, so the code should always be clear in what manner the developer wants the variable to be treated.
Comment by External U.
1867 | September 08, 2016 12:06:32 AM GMT
Any chance at looking at this for 2018? This really annoying behavior makes CFML unpredictable and makes me think twice every time I go to use a member function. Will it work? I never know. Behind the scenes Java details should never affect me as a user of CFML, which is a loosely typed language and allows me to do "stringy" things with variables that can be coerced to a string. This has always been the case with BIFs.
Comment by Bradley W.
1868 | March 21, 2018 04:51:43 PM GMT
+1 - This needs fixed. If simple values come in thru a query or URL parameter, we should be able to run .trim()/.len()/etc on them w/o having to worry about if the underlying data type is numeric or bla. Stringy member functions should simply work on all simple values.
Vote by Aaron N.
26399 | March 28, 2018 08:02:51 AM GMT
With ColdFusion preserving datatypes, member functions can be invoked on values that are strings. The following snippet now returns "11", with sampleQuery.ID.len() and Len(sampleQuery.ID) not returning exceptions. {code:java} <cfscript> sampleQuery = QueryNew( "ID", "Integer", {"id":1}); WriteOutput(sampleQuery.ID.len()); WriteOutput(Len(sampleQuery.ID)); </cfscript> {code}
Comment by Immanuel N.
27565 | March 28, 2018 01:10:34 PM GMT
Hi Adobe, What was fixed? Only .len()/.trim() were added to numeric type? Or all stringy member functions were added to all simple types? Thanks!, -Aaron
Comment by Aaron N.
27270 | April 02, 2018 11:46:32 PM GMT
Adobe?? What exactly is the fix for this ticket. We can't see your internal comments. Can you please add a public comment we can see? Thanks!, -Aaron
Comment by Aaron N.
27333 | April 10, 2018 02:47:47 AM GMT
Aaron, The issue has been fixed on an upcoming release of ColdFusion. The fix must be in place when Data type preservation is enabled. Data type preservation will be enabled by default. -Immanuel
Comment by Immanuel N.
27566 | April 10, 2018 09:33:18 AM GMT
Hi Immanuel, Are you saying .trim()/.len() will no longer throw exception when used on any value coming from a query? Ex: a timestamp column, an integer column, etc? I'm confused about the specific cases that this fix applies to. Thanks!, -Aaron
Comment by Aaron N.
27567 | April 12, 2018 09:57:29 PM GMT
Hi Adobe and Brian, This ticket is not fixed in CF2018 Public Beta (build 2018.0.0.308164). The following still throws an exception: <cfscript> foo = now() writeOutput(foo.trim()) </cfscript> Could you please outline exactly what was fixed? I do not understand your last response. The community expects the dynamic language to behave like a dynamic language. Thanks!, -Aaron
Comment by Aaron N.
27568 | April 17, 2018 08:15:46 AM GMT
Somehow I got unsubscribed to this ticket. I still feel the same way about it. CFML as a language does not limit what can be done to a variable by the underlying Java objects that happen to represent it. CFML allows you to do anything with a variable that it can be cast to (automatically behind the scenes). Therefore, any BIFs that can operate on a simple value (stringy) should work as a member function. CFML doesn't even provide a first-class method to test a simple value to see what actual java class is being used behind the scenes (and it shouldn't-- that's an implementation details). It is therefore incorrect to expect the CF developer to know what java classes have been used behind the scenes and to limit functionality based on that. It's just not idiomatic to how CFML works. Some care needs to be taken here to ensure there isn't any ambiguity in member functions and the possible underlying Java classes that might be used to represent simple values in CFML.
Comment by Bradley W.
27569 | April 17, 2018 01:52:51 PM GMT