More Modern CFML features

More Modern features in ColdFuison, what are these features?

Here are some and examples for each:

  • CFScript
  • QueryExecute
  • Member Functions
  • Elvis Operator
  • Colusures
  • Map Reduce Filter Each
  • First Class Functions
  • Safe Navigator

CFScript:

  • Seems like first CFScript was implemented in CF 4.0
  • Tags seemed ok back then because pre CFC’s (CF Components)
  • Used UDF’s and Custom Tags to reuse and separate code
  • CF MX (6.0) brought about CFC’s so separation of code
  • CFCs – you create methods, which are ColdFusion user-defined functions, in the component page. You pass data to a method by using parameters. The method then performs the function and, if specified in the cfreturn tag, returns data.
  • CF 9 added script based cfc support
  • You could write a full CFC with cfscript and not need to include code in cfscript block
  • CF11 adds full Script Support
  • most of the cfscript example will be CF 11 unless otherwise noted

cfTagName( attribute-pairs* );

writeDump(var);
writeOutput(expression);
Location(“mypage.cfm”,”false”);

cfTagName( attribute-pairs* ) 

{ …};

cfDocument(format=“PDF”)
{ //code  }

For (i=1; i<=10; i++) {
   //code
}

Differences in the old cfscript syntax and new syntax

<cfscript>
//CF9 syntax
thread action=“run” name=“testName” {
  thread.test = “CFML”;
}

//CF11 syntax
cfthread( action=“run” name=“testName”){
  thread.test = “CFML”;
}
<cfscript>

Resources:

Query Execute

Syntax:

QueryExecute( sql_stmt, queryParams, queryOptions );

Numbers =
(1) queryExecute(“
  SELECT      *
  FROM        art
  WHERE      artname like ‘%this%’
  ORDER BY  id“,
     (2)  {type={value=“number”, cfsqltype=“cf_sql_varchar”}},
             or    {value=“color”},
      (3) {datasource = “scratch_mssql”}

);
qryResult = queryExecute(“
     SELECT *
     FROM Employees",
   {}, 
   {datasource= "myDataSourceName"}
);

Resources:

Members functions

  • Member Functions are operators and functions that are declared as a member of a class.
  • These are more in line with true object oriented style of coding
  • Member functions can also be chained together

Formats:

Old:

  ArrayAppend(empArr, emp)

  structIsEmpty(empStruct)

New:

  empArr.append(emp)

  empStruct.isEmpty()

List of data types supported:

  • String: stringVar.find()
  • List: listVar.listFind()
  • Array: arrayVar.find()
  • Struct: structVar.find()
  • Date: dateVar.dateFormat()
  • Image: someImage.crop()
  • Query: queryVar.addColumn()
  • Spreadsheet: spreadsheetVar.writ()
  • XML: xmlVar.search()

A chaining example:

s =    "The";
s =    s.append("quick brown fox", " ")
    .append("jumps over the lazy dog", " ")
        .ucase()
             .reverse();
writeOutput(s);

Result: GOD YZAL EHT REVO SPMUJ XOF NWORB KCIUQ EHT

s.append("quick brown fox", " ").append("jumps over the lazy dog", " ").ucase().reverse();

Resources

Elvis Operator

  • The Elvis Operator added in ColdFusion 11
  • It works like a Ternary Operator; it’s a decision making operator that requires three operands: condition, true statement, and false statement that are combined using a question mark (?) and a colon (:
  • ((condition) ? trueStatement : falseStatement)
  • The way it works is that the condition is evaluated. If it is true, then the true statement executed; if it is false, then the false statement executes
  • Before Elvis we had isDefined(), structKeyExists() and IF statements to do these kind of evaluations.
result = firstOperand ?: secondOperand;       // binary
result= (local.myVar ?: “default value”);

OR

result = firstOperand ?: secondOperand;       // binary
result = isInteger(17) ? "it's an integer" : "no it isn't";       // "it's an integer"

OR

result = firstOperand ? secondOperand : thirdOperand;     // ternary
result = isInteger("nineteen") ? "it's an integer" : "no it isn't";      // "no it isn't“

Resources:

Closures

  • A Closure is a function which binds variable references at declaration time not at use-time
  • Callbacks are not Closures (inline callbacks are)
  • That inner function has access to the var scope of the function it was defined from. This is what a closureis. It knows about its origin and it doesn’t forget. It will always be tied to that same parent var scope.
Function outerFunction() {
  var a = 3;
  return function innerFunction({
  var c = a + b;
  return c;
  }
}

(1) var foo = outerFunction()
(2) var result = foo(2);
(3) Console.log(result); //5

Example:

ColdFusion Docs Example:

   function helloTranslator(String helloWord) {
        return function(String name) {
             return "#helloWord#, #name#";
        };
    }

    helloInHindi=helloTranslator("Namaste");
    helloInFrench=helloTranslator("Bonjour");
    writeoutput(helloInHindi("Anna"));   

 à Namaste, Anna

    writeoutput(helloInFrench("John"));  

à Bonjour, John

Description of the above code:

  • In this case, using closure, two new functions are created. One adds Namaste to the name. And the second one adds Bonjour to the name.
  • helloInHindi and helloInFrench are closures. They have the same function body; however, store different environments.
  • The inner function is available for execution after the outer function is returned. The outer function returns the closure
  • A closure is formed when the inner function is available for execution. Meaning, it is formed when it is defined, not when it is used.

ColdFusion built in Functions that use Closures:

  • CF10 Closure Functions:
  • ArrayEach, StructEach
  • ArrayFilter, StructFilter,ListFilter
  • ArrayFindAt, ArrayFindAllNoCase
  • CF11 Closure Functions:
  • isClosure
  • ArrayReduce, StructReduce, ListReduce
  • ArrayMap, StructMap, ListMap

Resources:

   http://fusiongrokker.com/p/closures/#/

Map, Filter, Reduce, Each

These features all work on Arrays, Lists, Structs and Queries

  • The map() functions iterate over the collection (be it a list, array or struct), and returns a new object with an element for each of the ones in the original collection. The callback returns the new element for the new collection, which is derived from the original collection. It is important to note that only the collections values are changed, it will still have the same key/indexes.
  • The reduce() operation is slightly more complex. Basically it iterates over the collection and from each element of the collection, derives one single value as a result.
  • The Filter() function is similar to map and reduce. It will iterate over a given object and return a new object but the original list is unaffected. The callback returns a Boolean to determine if the element is returned in a new object.
  • The each() function iterates over a given object and calls a callback for each element. This can be used instead of a loop.

MAP:

  • ArrayMap Example ( next few examples from Adam Cameron):
dcSports    = ["Redskins", "Capitals", "Nationals", "Wizards", "United"];
colourInList = arrayMap(
        dcSports, function(v,i,a){
                  return replace(a.toList(), v, ucase(v) );
         }
);
writeDump([dcSports,colourInList]); 

Will see an array of dcSports with 7 items each showing the next in the row all caps:

      REDSKINS,Capitals,Nationals,Wizards,United

      Redskins,CAPITALS,Nationals,Wizards,United

      Redskins,Capitals,NATIONALS,Wizards,United

REDUCE

  • arrayReduce()

dcSports = [“Redskins”, “Capitals”, “Nationals”, “Wizards”, “United”];

ul = arrayReduce(dcSports, function(previousValue, value)
   {
        return previousValue & "<li>#value#</li>";
    },    "<ul>"
) & "</ul>";
writeOutput(ul);

Result is just the Array turned into a list

FILTER

  • ArrayFilter
Filtered =
     arrayFilter([“myNewBike”,
           “oldBike”], function(item)
{
      return len(item) > 8;
});

Answer

=> [1]

EACH

arrayEach([1,2,3,4,5,6,7], function(item)
{
     writeOutput
       (dayOfWeekAsString(item) & “<br>”);
});

Answer:

Sunday

Monday

Tuesday

Wenesday

Thursday

Friday

Saturday

Also check out how these features will work with queries:

week = queryNew("id,en,mi", "integer,varchar,varchar", [
    [1,"Monday", "lunes"],
    [2,"Tuesday", "martes"],
    [3,"Wednesday", "miercoles"],
    [4,"Thursday", "jueves"],
    [5,"Friday", "vernes"],
    [6,"Saturday", "sabado"],
    [7,"Sunday", "domingo"]
]);
shortestMaoriDayName = week.reduce(function(shortest,number){
    if (shortest.len() == 0) return number.mi;
    return number.mi.len() < shortest.len() ? number.mi : shortest;
}, "");
writeOutput(shortestMaoriDayName);

Resources:

First Class Functions

  • A first class object is the one which could be passed as an argument
  • Now you can treat ColdFusion functions such as arrayLen, lCase, uCase, etc. as objects and you can do the following:
  • Pass them as arguments to a function call
  • Assign them to variables
  • Return them as a result of a function invocation
  • This first introduced in ColdFusion 11

Here is how to pass in a built-in function as an argument:

Function convertCaseArray(Array, array, function converter){
  for (var i=1, I <= arrayLen(array); i++){
    array[i] = converter(array[i]);
  }
  return array;
}

resultArray = convertCaseArray([‘One’,’Two’,’Three’], lcase);
Writedump(resultArray);

Array converted to all lower case

Resources

Safe Navigator

  • Save Navigation — ?.
  • Save navigation operator can be used to access members of a struct or values of an object.
  • Normally we use a .
  • <cfset t = myObject.getUserObj />
  • Now we can use the ?. To ensure that an exception is not thrown when the variable is not defined
  • <cfset t = myObject?.getUserObj />
  • If myObject is not defined then t will be assigned as undefined

Chaining:

writeOutput(employee?.name?.firstname?.trim());

The above code does not output any value if any of the following is undefined/null:

employee OR

employee.name OR

employee.name.firstname.

Note: the code will throw an exception if the employee is defined but employee.name is not

 

Final Thoughts:

These are just some examples of modern features, if you have more examples, please put those into the comments below. The is a perfect post to add a lot of examples for all these modern features. To see more information about modern features you can always check out the recorded presentation from NCDEVCON on these features:

https://www.youtube.com/watch?v=m_HdTuOdTy8&index=5&list=PLz6r7YssJoKQyfkq1cdNRy0-FqRpcxEZr

To get more information on all of these features, check out the Adobe Docs and also check cfdocs.org and look in the other section to see more details on many of these.

 

Leave a reply

Your email address will not be published. Required fields are marked *

By submitting this form, you accept the Mollom privacy policy.

Related