SlideShare ist ein Scribd-Unternehmen logo
1 von 74
Downloaden Sie, um offline zu lesen
CFML Features for
More Modern Coding
Dan Fredericks
fmdano@gmail.com
@fmdano74
http://www.meetup.com/nvcfug/
What this Presentation will cover:
• CFML History of top features
• CFScript Support
• QueryExecute() Function
• Member Functions
• Elvis Function
• Closures
• Map and Reduce
• First Class Functions and Callbacks
• CF 12 Special
ColdFusion Feature History
• ColdFusion 1: CF1 was an interesting animal, it predates the CFML language, back then it was DBML (Database
Markup Language) and it used a tag named <dbquery> to define a query and then <dbsql> to append SQL to that
query. There was a <dbset> a <dbif> and not much else.
• ColdFusion 2: CF2 introduced CFML, and introduced dynamic SQL built within a <cfquery> tag.
• ColdFusion 3: CF3 was less significant for the language, and more for the introduction of CF Studio.
• ColdFusion 4
• Invoke Java Objects
• ColdFusion 5
• Macromedia
• CFScript-based UDFs
• ColdFusion 6
• Server rewritten in Java (MX)
• CFML Language API with an OOP Interface
• ColdFusion MX 7
• Flash-Based forms
• Report builder
ColdFusion Feature History
• Adobe ColdFusion 8
• CFPDFFORM integrate with Acrobat forms
• .net integration (http://www.Microsoft.com/net)
• Built in AJAX widgets
• Array and structure improvement
• CFPDF
• Some CFScript enhancements
• ColdFusion 9
• More CFScript support
• Explicit local scope
• getters/setters in CFC’s
• Init (implicit constructions via method) in CFC
• ORM
ColdFusion Feature History
• ColdFusion 10
• Security enhancements
• Tomcat Integration
• Restful web services
• Hotfix Updater in Admin
• Language enhancements – Closures, CFScript, etc.
• ColdFusion 11
• Full CFScript Support
• Member Functions
• Elvis Operator
• queryExecute
• built in functions elevated to first-class functions
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
CFScript
• Community has different opinions on using Tag vs Script
• Using MVC Tags on View, Script on Controller and Model
• Script syntax is cleaner
• Closer to other ECMA script languages
• Lots of tag syntax is more characters
• I am more comfortable with Tags
• Documentation is lacking for Script (check cfdocs.org)
• Tags were superior for SQL integration (talk about this later)
• Newer features such as Closures are script based
• Do what is best for you but try to be consistent!!!
CFScript
Syntax – tags without Bodies:
cfTagName( attribute-pairs* );
writeDump(var);
writeOutput(expression);
Location(“mypage.cfm”,”false”);
Syntax – tags with Bodies:
cfTagName( attribute-pairs* )
{ …};
cfDocument(format=“PDF”)
{ //code }
For (i=1; i<=10; i++) {
//code
}
CFScript
• There are some tags that have multiple implementations
• These implementations are due to old syntax or dual syntax (CF9 cfc’s)
<cfscript>
//CF9 syntax
thread action=“run” name=“testName” {
thread.test = “CFML”;
}
//CF11 syntax
cfthread( action=“run” name=“testName”){
thread.test = “CFML”;
}
<cfscript>
CFScript
<cfscript>
//CF9 syntax
param name=“local.summit” type = “string” default = “CFSummit”;
//CF11 syntax
cfparam( name = “local.summit” type = “string” default = “CFSummit”);
</cfscript>
CFScript
<cfscript>
//CF9 syntax
abort “some message”;
//CF11 syntax
cfabort( showError = “some message”);
</cfscript>
CFScript
Tag Example
• Loop
<cfloop from=“1” to=“10”index=“i”>
<cfoutput>#i#</cfoutput>
</cfloop>
Script Example
• For Loop
for (i=1; i <=5; i++) {
// all statements in the block are looped over
result = i * 2;
writeOutput(result);
}
• While Loop
while (condition) {
// statements
}
CFScript
Tag Example
• If/elseif/else example:
<cfset count = 10>
<cfif count GT 20>
<cfoutput>#count#</cfoutput>
<cfelseif count GT 8>
<cfoutput>#count#</cfoutput>
<cfelse>
<cfoutput>#count#</cfoutput>
<cfif>
Script Example
• If/elseif/else example:
<cfscript>
count = 10;
if (count > 20) {
writeOutput(count);
} else if (count == 8) {
writeOutput(count);
} else {
writeOutput(count);
}
</cfscript>
CFScript
Tag Example
• Query Loop
<cfset platform = ["Adobe ColdFusion", "Railo", "Lucee"]>
<cfset myQuery = queryNew(" ")>
<cfset queryAddColumn(myQuery, "platform", "CF_SQL_VARCHAR",
platform)>
<cfloop index="i" from="1" to="#myQuery.recordCount#">
<cfoutput><li>#myQuery["platform"][i]#</li></cfoutput>
</cfloop>
OR
<cfloop query="myQuery" group="platform">
<cfoutput><li>#platform#</li></cfoutput>
</cfloop>
Script Example
• Query Loop
q = queryNew("id,data", "integer,varchar",
[ [11, "aa"], [22, "bb"], [33, "cc"] ] );
for (row in q){
writeOutput("#q.currentRow#:#row.id#:#row.data#;");
//result: 1:11:aa;2:22:bb;3:33:cc;
}
OR
cfloop(query=q, group="fk"){
writeOutput("<strong>#fk#</strong>");
}
CFScript
Tag Example
<cfcomponent displayname="utils" output="false" >
<cfproperty name="version" type="string" default="0.0.1" >
<cffunction name="doReverse" access="public" returntype="string" hint="I reverse the supplied string" >
<cfargument name="stringToReverse" required="true" type="string" >
<cfreturn reverse(arguments.stringToReverse) >
</cffunction>
<cffunction name="reverseArrayOrder" access="public" returntype="array" hint="I reverse an array's order" >
<cfargument name="arrayToReverse" type="array" default='["Adobe ColdFusion", "Lucee", "Railo"]' >
<cfset local.result = '' />
<cfloop array="arguments.arrayToRevers" index=“local.a" >
<cfset arrayAppend(local.result, local.a) >
</cfloop>
<cfreturn local.result />
</cffunction>
</cfcomponent>
CFScript
Script Example
component displayname="Utils" output="false" {
(property name="version" type="string" default="0.0.1";) – not really needed
public string function doReverse(required string stringToReverse)
hint="I reverse the supplied string"
{
return reverse(arguments.stringToReverse);
}
public array function reverseArrayOrder(array arrayToReverse = ["Adobe ColdFusion", "Lucee", "Railo"])
hint="I reverse an array's order"
{
var result = [];
for (var i = arrayLen(arguments.arrayToReverse); i >= 1; i--)
{
result.append(arguments.arrayToReverse[i]);
}
return result;
}
}
CFScript
Resources:
• ColdFusion Online Docs : https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-tags/tags-r-
s/cfscript.html#cfscript-Scriptsupportfortags
• CFDocs: http://cfdocs.org/
• CFChef GitHub: https://github.com/cfchef/cfml-tag-to-script-conversions/blob/master/README.md#general
• Adam Cameron GitHub: https://github.com/adamcameron/cfscript/blob/master/cfscript.md#database
• Pete Freitag Cheat sheet: http://www.petefreitag.com/cheatsheets/coldfusion/cfscript/
QueryExecute
• CFQUERY has been the staple to query a database since day 1
• There have been a few attempts to query the database using script
• Here is the latest alternative for script based syntax
Syntax:
QueryExecute( sql_stmt, queryParams, queryOptions );
QueryExecute
Old Script Syntax
<cfscript>
q = new com.adobe.coldfusion.query();
q.setDatasource("cfartgallery");
q.setSQL("select * from art
where artname like :search or description like :search");
q.addParam(name="search",value="%e%",cfsqltype="cf_sql_varchar");
r = q.execute();
</cfscript>
QueryExecute
New Script Syntax
queryExecute( sql_stmt, queryParam, 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”}
);
QueryExecute
queryExecute( sql_stmt, queryParam, queryOptions);
Tag Syntax
<cfquery name=“qryResult”>
SELECT *
FROM Employees
</cfquery>
Script Syntax
qryResult = queryExecute(
"SELECT * FROM Employees“
);
Note: queryExecute is just a
function so can be used in tags as
well:
<cfset temp = queryExecute(…) >
QueryExecute
queryExecute( sql_stmt, queryParam, queryOptions);
Tag Syntax
<cfset country = “USA” />
<cfset empid = 1 />
<cfquery name=“qryResult”>
SELECT *
FROM Employees
WHERE empid = #empID#
AND country = #country#
</cfquery>
** Should use cfqueryparm
Script Syntax (Parameters using Struct)
qryResult = queryExecute(“
SELECT *
FROM Employees
WHERE empid = :empid
AND country = :country",
{country="USA", empid=1}
);
QueryExecute
queryExecute( sql_stmt, queryParam, queryOptions);
Tag Syntax (Specify a datasource)
<cfquery name=“qryResult”
datasource = “myDatasourceName”>
SELECT *
FROM Employees
</cfquery>
Script Syntax (Specify a datasource)
qryResult = queryExecute(“
SELECT *
FROM Employees",
{},
{datasource=
"myDataSourceName"}
);
QueryExecute
queryExecute( sql_stmt, queryParam, queryOptions);
Tag Syntax (query with a subquery)
<cffunction name=“getEqMfg” returntype=“query” access=“public”>
<cfargument name=“dc” cfsqltype=“string” required=“true”>
<cfquery name=“ml” datasource=“myDSN”>
Select name, mfgCode, country
From mfgdetails_tbl
Where mfgcode in (
Select mfgCode
From mfg2devices_tbl
Where deviceCode =
<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.dc#“ maxlength=“5”> )
Order By country, name
</cfquery>
<cfreturn ml >
</cffunction>
Script Syntax (query with a subquery)
public query function getEqMfg(required string dc){
var ml = queryExecute("Select name, mfgCode, country
From mfgdetails_tbl
Where mfgcode in (
Select mfgCode
From mfg2devices_tbl
Where deviceCode = :dcp
)
Order By country, name",
{dcp={value="dc",cfsqltype="CF_SQL_VARCHAR", maxlength=5 }},
{datasource = “myDSN”}
);
return ml;
}
QueryExecute
queryExecute( sql_stmt, queryParam, queryOptions);
Tag Syntax
(Return a number/count or maxRows)
<cfquery name=“dsc”>
Select count(*) as qty
From generic_view”
</cfquery>
<cfquery name=“sc” maxrows=“#rc#”>
Select specialtyname, qty
From generic_view
Order by qty DESC, specialtyname
</cfquey>
Script Syntax
(Return a number/count or maxRows)
public numeric function getSpecialtyCount(){
var dsc = queryExecute("Select Count(*) as qty
From specialtycategorycount_view");
return dsc.qty;
}
query function getSpecialtyCodeChartData(required numeric rc=99){
var sc = queryExecute("Select specialtyname, qty
From specialtycategorycount_view
Order by qty DESC, specialtyname",
{}, {maxrows = "rc"});
return sc;
}
QueryExecute
queryExecute: https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-
functions/functions-m-r/queryexecute.html
CFDocs.org: http://cfdocs.org/queryexecute
Query options: http://stackoverflow.com/questions/26296467/what-are-the-options-for-
queryoptions-in-the-queryexecute-function
Get rid of cfqueryparam: http://blog.adamcameron.me/2014/03/querycfc-queryexecute-
have-good-feature.html
Check out cfuser examples: http://www.cfuser.com/more-queryexecute-examples/
Cfuser: http://www.cfuser.com/more-queryexecute-examples/
Member 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()
Member Functions
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()
Chaining: stringVar.find(“I like cfml”, “cfml”).uCase()
Member Functions
Regular CF function syntax
dateTimeFormat(
dateAdd( 'd', -5, now() )
, 'yyyy-mm-dd' );
dateTimeFormat( dateAdd( 'd', -5, now() ), 'yyyy-mm-dd' );
Note: dateTimeFormat function was added in
CF10, combo of dateTime and timeFormat.
Member Function syntax
now().add( 'd', -5 )
.dateTimeFormat( 'yyyy-mm-dd' );
now().add( 'd', -5 ).dateTimeFormat( 'yyyy-mm-dd' );
Member Functions
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();
Member Functions
Regular CF function syntax
var myArray = ArrayNew(1);
ArrayAppend(myArray, "objec_new");
ArraySort(myArray, "ASC");
Member Function syntax
myArray.append("objec_new");
myArray.sort("ASC");
Member Functions
• Important Note on a potential Member Function Gotcha:
• Some member functions might fall into underlying Java methods if the strict
ColdFusion syntax is not followed.
• https://bugbase.adobe.com/index.cfm?event=bug&id=3753710
Member Functions
• Resources
Adobe ColdFusion wiki: https://helpx.adobe.com/coldfusion/developing-
applications/building-blocks-of-coldfusion-applications/using-the-member-functions.html
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.
Elvis Operator
• Syntax: ?:
value = ( url.foo ?: "bar" );
• The Elvis operator is primarily used to assign the ‘right default’ for a
variable or an expression
• Or it is a short-hand way to do parameterization. It will allow us to set
a value if the variable is Null
Elvis Operator
Examples which are all the same:
1. If ( isNull(local.testVar)){
value = “test Item”;
} else{
value = local.newTest;
}
2. Value = (local.testVar ?: “test Item”);
3. Value = (isNull(local.testVar) ? “test Item”: local.newTest);
Elvis Operator
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“
Elvis Operator
• Resources:
• Wiki docs https://helpx.adobe.com/coldfusion/developing-applications/the-cfml-programming-
language/elements-of-cfml/elvis-operator.html
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 closure is. It knows about its origin and it
doesn't forget. It will always be tied to that same parent var scope.
Closures
javascript example (works in CF also)
Function outerFunction() {
var a = 3;
return function innerFunction(b){
var c = a + b;
return c;
}
}
(1) var foo = outerFunction()
(2) var result = foo(2);
(3) Console.log(result); //5
• We have an outer function with a
nested function which accepts a
parameter b
• (1)When you invoke the outer you
get the inner returned later.
• (2)Notice the outer function was
called but the a still has its value
and is used in the return function
(innerFunction).
• (3)That is why the result Is 5!
• http://taha-sh.com/blog/understanding-
closures-in-javascript
Closures
function bunchofstuff(…) { // OLD CODE
…bunch of stuff…
}
function restofstuff(…) { …rest of stuff… }
function stuff1(…) { bunchofstuff(…); …more
stuff… restofstuff(…); }
function stuff2(…) { bunchofstuff(…); …other
stuff… restofstuff(…); }
You still have 4 functions and stuff1 and 2
still have common code
function generalstuff(…, differentstuff) { // CLOSURE WAY
…bunch of stuff… differentstuff(…); …general code…
}
function stuff1(…) {
generalstuff(…, function(…){ …more specific stuff…
});
}
function stuff2(…) {
generalstuff(…, function(…){ …more specific stuff… });
}
Using the closure code above all common code is in general
stuff and…
you call stuff1 or stuff 2 for the specific code you need run
(Template Method design pattern)
Closures
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
• 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.
Closures
• Ray Camden example (technically is, but more like a callback/inline function) :
Data = [“Neil Diamond”, “Depeche Mode”, “The Cure”, “Cher”, “Ace of Base”, “Frank
Sinatra”, The Church”];
arraySort(data, function(a,b){
var first = a;
var second = b;
first = replace(first, “The “, “”);
second = replace(second, “The “, “”);
return first gt second;
});
This code above will order the data array by names excluding THE.
Ace of Base, Cher, The Church, The Cure, Depeche Mode, Frank Sinatra, Neil Diamond
Closures
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
Closures
ArrayEach
arrayEach(
array,
function(any currentObj)
{
}
);
arrayEach([1,2,3,4,5,6,7], function(item)
{
writeOutput
(dayOfWeekAsString(item) & “<br>”);
});
Answer:
Sunday
Monday
Tuesday
Wenesday
Thursday
Friday
Saturday
Closures
structEach
structEach(
struct,
function(key, value)
{
}
);
structEach({one:1, two:2}, function(key,
value)
{
writeoutput(key & “:” & value);
});
Answer:
ONE: 1
TWO: 2
Closures
arrayFilter(
array,function(arrayElement,
[,index, array])
{return true|false;}
);
Note: CF 11 - the callback functions
of all the filters have access to the
entire array/list/struct apart from
the current element
• ArrayFilter
Filtered =
arrayFilter([“myNewBike”,
“oldBike”], function(item)
{
return len(item) > 8;
});
Answer
=> [1]
Closures
arrayFindAll
ArrayFindAll(array, object) or
ArrayFindAll(
array,
function(arrayElement) {
return true|false;
}
)
Data=[{age:4}, {age:6}, {age:41}];
Answer =
arrayFindAll(data,
function(item){
return item.age < 10;
});
Answer
[1,2]
Closures
arrayReduce
ArrayReduce(
array,
function(result, item, [,index,
array])
[, initialValue]
)
complexData = [{a:4}, {a:18}, {a:51}];
Function reducer(prev, element){
return prev + element.a;
}
sumOfData =
arrayReduce(complexData, reducer, 0);
Answer
73
Closures
arrayMap
ArrayMap(
array,
function(item [,index, array])
)
complexData = [{a:4}, {a:18}, {a:51}];
newArray =
arrayMap(complexData, function(item){
return item.a;
}, 0);
Answer
[4, 18, 51]
Closures
Testbox: https://www.ortussolutions.com/product/testbox
• TestBox uses Closures
• Since the implementations of the describe()
and it() functions are closures, they can
contain executable code that is necessary to
implement the test. All ColdFusion rules of
scoping apply to closures, so please
remember them. We recommend always
using the variables scope for easy access and
distinction.
• A test suite begins with a call to our TestBox
describe() function with at least two
arguments: a title and a closure within the
life-cycle method called run(). The title is the
name of the suite to register and the function
is the block of code that implements the
suite.
function run() {
describe("A suite is a closure",
function() {
c = new Calculator();
it("and so is a spec", function() {
expect( c ).toBeTypeOf( 'component' );
});
});
}
Closures
• Some Example code online or resources:
• Sesame library inline functions/closures
https://github.com/markmandel/Sesame
• Underscore.cfc ported from underscore.js
https://github.com/russplaysguitar/UnderscoreCF
• TestBox gives the ability to use closures
http://wiki.coldbox.org/wiki/TestBox.cfm
• Adam Tuttle presentation on closures
http://fusiongrokker.com/p/closures/#/
• Adam Cameron blog multiple Closure examples
http://blog.adamcameron.me/search/label/Closure
Map and Reduce (and more)
• 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.
• So it remaps the original collection
• ArrayMap, StructMap, ListMap
• 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.
• ArrayReduce, StructReduce, ListReduce
Map and Reduce (and more)
• 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.
structEach(circles,function(key,value)
{
matchednames =
arrayfilter(value,function(obj)
{
return left(obj,1)=='d';
}
});
Example shows how to look at a struct
and if it begins with a D, return it.
Map and Reduce (and more)
• The each() function iterates over
a given object and calls a
callback for each element. This
can be used instead of a loop.
letters = ["a","b","c","d"];
arrayEach(letters, function()
{
writeDump(arguments);
});
Struct 1 a
struct 1 b
struct 1 c
struct 1 d
Map and Reduce (and more)
• Map() complexData = [ {a: 4}, {a: 18}, {a: 51} ];
newArray =
arrayMap( complexData, function(item)
{
return item.a;
}, 0 );
Answer: [4, 18, 51]
Map and Reduce (and more)
• Reduce() complexData = [ {a: 4}, {a: 18}, {a: 51} ];
sum =
arrayReduce( complexData, function(prev,
element)
{
return prev + element.a;
}, 0 );
Answer: 73
Map and Reduce (and more)
• ArrayMap Example ( next few examples from Adam Cameron):
rainbow = ["Whero","Karaka","Kowhai","Kakariki","Kikorangi","Tawatawa","Mawhero"];
colourInList = arrayMap(
rainbow, function(v,i,a){
return replace(a.toList(), v, ucase(v) );
}
);
writeDump([rainbow,colourInList]);
Will see an array of Rainbow with 7 items each showing the next in the row all caps:
WHERO,Karaka,Kowhai,Kakariki,Kikorangi,Tawatawa,Mawhero
whero,KARAKA,Kowhai,Kakariki,Kikorangi,Tawatawa,Mawhero
whero,karaka,KOWHAI,Kakariki,Kikorangi,Tawatawa,Mawhero
Map and Reduce (and more)
• StructMap()
original = {"one"={1="tahi"},"two"={2="rua"},"three"={3="toru"},"four"={4="wha"}};
fixed = structMap(original, function(k,v)
{
return v[v.keyList().first()];
});
writeDump([ original, fixed]);
This just returns the digit as a key and Maori number as a value
1 tahi
2 rua
3 toru
4 wha
Map and Reduce (and more)
• listMap()
Rainbow = "Whero, Karaka, Kowhai, Kakariki, Kikorangi, Tawatawa, Mawhero";
externalList = "";
reverseRainbow = listMap( rainbow, function(v,i,l)
{
var newValue = "#i#:#v.reverse()#";
externalList = externalList.append(newValue);
return newValue;
});
writeDump([{rainbow=rainbow},{reverseRainbow=reverseRainbow},{externalList=externalList}]);
This should reverse the rainbow list and show it backwards.
Map and Reduce (and more)
• listReduce()
numbers = "1,2,3,4,5,6,7,8,9,10";
sum = listReduce(numbers, function(previousValue, value)
{
return previousValue + value;
}, 0);
writeOutput("The sum of the digits #numbers# is #sum#<br>");
The sum of the digits 1,2,3,4,5,6,7,8,9,10 is 55
Map and Reduce (and more)
• arrayReduce()
rainbow =
["Whero","Karaka","Kowhai","Kakariki","Kikorangi","Tawatawa","Mawhero"]
;
ul = arrayReduce(rainbow, function(previousValue, value)
{
return previousValue & "<li>#value#</li>";
}, "<ul>"
) & "</ul>";
writeOutput(ul);
Result is just the Array turned into a list
Map and Reduce (and more)
• structReduce()
• StructReduce(struct, function(result, key, value [,struct]), initialVal)
rainbow = { "Red"="Whero", "Orange"="Karaka", "Yellow"="Kowhai", "Green"="Kakariki” };
ui = structReduce( rainbow, function(previousValue, key, value)
{
return previousValue & "<dt>#key#</dt><dd>#value#</dd>";
},
"<dl>"
) & "</dl>";
writeOutput(dl);
Result is a two column list of the key and the value: Blue Kikorangi
Map and Reduce (and more)
• Resources
• map and reduce & more with adam: http://blog.adamcameron.me/2014/02/coldfusion-11-map-and-reduce.html
• map reduce: https://hacks.mozilla.org/2015/01/from-mapreduce-to-javascript-functional-programming/
• js working example of each: http://elijahmanor.com/reducing-filter-and-map-down-to-reduce/
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
First Class Functions
• What is a Callback function?
• This is a function that is passed
into another function.
• You build a main generic function
to do work, then you can pass in a
more detailed function to do a lot
of the work.
• Sorting, you might want to sort
money data, or state data, or city
data
• Build a sort function then pass in
the callback function you need to do
your sort
Sort(dataToSort, callBackFunction)
{ //do stuff }
callbackFunction()
{ //build sort }
Calls the Sort function:
sortedData = sort(unsortedData,
callbackFunction);
First Class Functions
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
First Class Functions
This is where lcase and ucase are being returned from a function:
Function convertArray(array array, string caseTo){
caseConvertFunction = getConvertFunction(caseTo);
for (var i=1, I <= arrayLen(array); i++){
array[i] = caseConverterFunction{array[i]);
}}
Function getConvertFunction (String caseType){
if (caseType == ‘lower’) return lcase; else return ucase;
}
resultArray_lower = convertArray([‘One’, ‘Two’, ‘Three’], ‘lower’);
resultArray_upper = convertArray([‘One’, ‘Two’, ‘Three’], ‘upper’);
_lower array: one, two, three
_upper array: ONE, TWO, THREE
First Class Functions
• Resources
• http://blogs.coldfusion.com/post.cfm/language-enhancements-in-coldfusion-
splendor-promoing-built-in-cf-function-to-first-class
• http://blog.adamcameron.me/2013/09/wow-coldfusions-built-in-functions-
will.html
• http://blog.adamcameron.me/2012/09/callbacks-function-expressions.html
• Sesame project: https://github.com/markmandel/Sesame
• Adobe Online Docs: https://helpx.adobe.com/coldfusion/developing-
applications/the-cfml-programming-language/built-in-functions-as-first-class-
citizen.html
ColdFusion 12 feature
• NDA – What I will show here may not be talked about until Adobe
allows the discussion to be public.
• ColdFusion 12 has the code name of RAIJIN
ColdFusion 12 Feature
• 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
ColdFusion 12 Feature
Old way:
if(isDefined("foo"))
writeOutput(foo.bar());
else
writeOutput("not defined");
New way:
writeOutput(foo?.bar());
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
ColdFusion 12 Feature
• There are a few other new Language enhancements not discussed
today
• There are new enhancements to current features of ColdFusion
• There is also a few new features that will be announced soon
Resources:
Adam Cameron Blog: http://blog.adamcameron.me/2015/10/coldfusion-12-it-
goes-to-show-you.html
Final Thoughts/Resources
• These topics were only some more modern concepts for CFML.
• Where to get more information from CFML Community
• Adobe Wiki
• CFDocs.org
• Cfblogger (put in aggregator like feedly)
• Slack Channel – 700+ cfml users https://cfml.slack.com/
• Twitter, Facebook, youTube, Vimeo and other social sites
Dan Fredericks
@fmdano74
fmdano@gmail.com
I am on most social networks, twitter, facebook, G+, LinkedIn
Special Thanks to Adam Cameron, Adam Tuttle, Ray Camden, Sean Corfield, and Brad Wood for examples

Weitere ähnliche Inhalte

Was ist angesagt?

My Database Skills Killed the Server
My Database Skills Killed the ServerMy Database Skills Killed the Server
My Database Skills Killed the ServerColdFusionConference
 
How do I Write Testable Javascript so I can Test my CF API on Server and Client
How do I Write Testable Javascript so I can Test my CF API on Server and ClientHow do I Write Testable Javascript so I can Test my CF API on Server and Client
How do I Write Testable Javascript so I can Test my CF API on Server and ClientColdFusionConference
 
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....Take home your very own free Vagrant CFML Dev Environment - Presented at dev....
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....Gavin Pickin
 
Developing High Performance and Scalable ColdFusion Application Using Terraco...
Developing High Performance and Scalable ColdFusion Application Using Terraco...Developing High Performance and Scalable ColdFusion Application Using Terraco...
Developing High Performance and Scalable ColdFusion Application Using Terraco...ColdFusionConference
 
Become a Security Rockstar with ColdFusion 2016
Become a Security Rockstar with ColdFusion 2016Become a Security Rockstar with ColdFusion 2016
Become a Security Rockstar with ColdFusion 2016ColdFusionConference
 
Intro to JavaScript Tooling in Visual Studio Code
Intro to JavaScript Tooling in Visual Studio CodeIntro to JavaScript Tooling in Visual Studio Code
Intro to JavaScript Tooling in Visual Studio CodeColdFusionConference
 
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016Gavin Pickin
 
Herding cats managing ColdFusion servers with commandbox
Herding cats managing ColdFusion servers with commandboxHerding cats managing ColdFusion servers with commandbox
Herding cats managing ColdFusion servers with commandboxColdFusionConference
 
Hey My Web App is Slow Where is the Problem
Hey My Web App is Slow Where is the ProblemHey My Web App is Slow Where is the Problem
Hey My Web App is Slow Where is the ProblemColdFusionConference
 
OroCRM Technology Webinar May 28, 2014
OroCRM Technology Webinar May 28, 2014OroCRM Technology Webinar May 28, 2014
OroCRM Technology Webinar May 28, 2014Jary Carter
 
CommandBox REPL, CLI, and Package Manager
CommandBox REPL, CLI, and Package ManagerCommandBox REPL, CLI, and Package Manager
CommandBox REPL, CLI, and Package Managerbdw429s
 
Performance tips for Symfony2 & PHP
Performance tips for Symfony2 & PHPPerformance tips for Symfony2 & PHP
Performance tips for Symfony2 & PHPMax Romanovsky
 

Was ist angesagt? (19)

My Database Skills Killed the Server
My Database Skills Killed the ServerMy Database Skills Killed the Server
My Database Skills Killed the Server
 
How do I Write Testable Javascript so I can Test my CF API on Server and Client
How do I Write Testable Javascript so I can Test my CF API on Server and ClientHow do I Write Testable Javascript so I can Test my CF API on Server and Client
How do I Write Testable Javascript so I can Test my CF API on Server and Client
 
Instant ColdFusion with Vagrant
Instant ColdFusion with VagrantInstant ColdFusion with Vagrant
Instant ColdFusion with Vagrant
 
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....Take home your very own free Vagrant CFML Dev Environment - Presented at dev....
Take home your very own free Vagrant CFML Dev Environment - Presented at dev....
 
Developing High Performance and Scalable ColdFusion Application Using Terraco...
Developing High Performance and Scalable ColdFusion Application Using Terraco...Developing High Performance and Scalable ColdFusion Application Using Terraco...
Developing High Performance and Scalable ColdFusion Application Using Terraco...
 
Realtime with websockets
Realtime with websocketsRealtime with websockets
Realtime with websockets
 
Become a Security Rockstar with ColdFusion 2016
Become a Security Rockstar with ColdFusion 2016Become a Security Rockstar with ColdFusion 2016
Become a Security Rockstar with ColdFusion 2016
 
Intro to JavaScript Tooling in Visual Studio Code
Intro to JavaScript Tooling in Visual Studio CodeIntro to JavaScript Tooling in Visual Studio Code
Intro to JavaScript Tooling in Visual Studio Code
 
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
 
Realtime with-websockets-2015
Realtime with-websockets-2015Realtime with-websockets-2015
Realtime with-websockets-2015
 
Herding cats managing ColdFusion servers with commandbox
Herding cats managing ColdFusion servers with commandboxHerding cats managing ColdFusion servers with commandbox
Herding cats managing ColdFusion servers with commandbox
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Testing Automaton - CFSummit 2016
Testing Automaton - CFSummit 2016Testing Automaton - CFSummit 2016
Testing Automaton - CFSummit 2016
 
10 common cf server challenges
10 common cf server challenges10 common cf server challenges
10 common cf server challenges
 
Hey My Web App is Slow Where is the Problem
Hey My Web App is Slow Where is the ProblemHey My Web App is Slow Where is the Problem
Hey My Web App is Slow Where is the Problem
 
OroCRM Technology Webinar May 28, 2014
OroCRM Technology Webinar May 28, 2014OroCRM Technology Webinar May 28, 2014
OroCRM Technology Webinar May 28, 2014
 
CommandBox REPL, CLI, and Package Manager
CommandBox REPL, CLI, and Package ManagerCommandBox REPL, CLI, and Package Manager
CommandBox REPL, CLI, and Package Manager
 
Automate Thyself
Automate ThyselfAutomate Thyself
Automate Thyself
 
Performance tips for Symfony2 & PHP
Performance tips for Symfony2 & PHPPerformance tips for Symfony2 & PHP
Performance tips for Symfony2 & PHP
 

Andere mochten auch

Gianni Lettieri - quelli che fanno
Gianni Lettieri - quelli che fannoGianni Lettieri - quelli che fanno
Gianni Lettieri - quelli che fannoGianni Lettieri
 
Aspan vuosi 2015 (id 35372)
Aspan vuosi 2015 (id 35372)Aspan vuosi 2015 (id 35372)
Aspan vuosi 2015 (id 35372)Aspa Foundation
 
Uu 22-2001
Uu 22-2001Uu 22-2001
Uu 22-2001abdus138
 
Realidad nacional educativa
Realidad nacional educativaRealidad nacional educativa
Realidad nacional educativaisamar2525
 
Delingskultur for Sparebanken Møre Arena Ålesund 10.januar 2017
Delingskultur for Sparebanken Møre Arena Ålesund 10.januar 2017Delingskultur for Sparebanken Møre Arena Ålesund 10.januar 2017
Delingskultur for Sparebanken Møre Arena Ålesund 10.januar 2017Jørn Kippersund
 
Building Better AngularJS 1.X Apps With TypeScript
Building Better AngularJS 1.X Apps With TypeScriptBuilding Better AngularJS 1.X Apps With TypeScript
Building Better AngularJS 1.X Apps With TypeScriptColdFusionConference
 
Consejo de profesores 22 02
Consejo de profesores 22 02Consejo de profesores 22 02
Consejo de profesores 22 02parvuloseltrigal
 
Derechos y obligaciones de los docentes
Derechos y obligaciones de los docentesDerechos y obligaciones de los docentes
Derechos y obligaciones de los docentesStefanie Prado
 
Crafting ColdFusion Applications like an Architect
Crafting ColdFusion Applications like an ArchitectCrafting ColdFusion Applications like an Architect
Crafting ColdFusion Applications like an ArchitectColdFusionConference
 
Floorplan (http://www.vlsisystemdesign.com/PD-Flow.php)
Floorplan (http://www.vlsisystemdesign.com/PD-Flow.php)Floorplan (http://www.vlsisystemdesign.com/PD-Flow.php)
Floorplan (http://www.vlsisystemdesign.com/PD-Flow.php)VLSI SYSTEM Design
 
Digital trends and challenges in B2B Commerce
Digital trends and challenges in B2B CommerceDigital trends and challenges in B2B Commerce
Digital trends and challenges in B2B CommerceEpiserver
 
Visbreaking and Delayed coking
Visbreaking and Delayed cokingVisbreaking and Delayed coking
Visbreaking and Delayed cokingSanyam Jain
 
Omnichannel Marketing leicht gemacht: Lernen von den Besten
Omnichannel Marketing leicht gemacht: Lernen von den BestenOmnichannel Marketing leicht gemacht: Lernen von den Besten
Omnichannel Marketing leicht gemacht: Lernen von den BestenMayoris AG
 

Andere mochten auch (19)

Gianni Lettieri - quelli che fanno
Gianni Lettieri - quelli che fannoGianni Lettieri - quelli che fanno
Gianni Lettieri - quelli che fanno
 
Flipbook project
Flipbook projectFlipbook project
Flipbook project
 
Project Report
Project ReportProject Report
Project Report
 
Aspan vuosi 2015 (id 35372)
Aspan vuosi 2015 (id 35372)Aspan vuosi 2015 (id 35372)
Aspan vuosi 2015 (id 35372)
 
F-35 Piece
F-35 PieceF-35 Piece
F-35 Piece
 
Uu 22-2001
Uu 22-2001Uu 22-2001
Uu 22-2001
 
Realidad nacional educativa
Realidad nacional educativaRealidad nacional educativa
Realidad nacional educativa
 
340B Piece Final
340B Piece Final340B Piece Final
340B Piece Final
 
Delingskultur for Sparebanken Møre Arena Ålesund 10.januar 2017
Delingskultur for Sparebanken Møre Arena Ålesund 10.januar 2017Delingskultur for Sparebanken Møre Arena Ålesund 10.januar 2017
Delingskultur for Sparebanken Møre Arena Ålesund 10.januar 2017
 
Building Better AngularJS 1.X Apps With TypeScript
Building Better AngularJS 1.X Apps With TypeScriptBuilding Better AngularJS 1.X Apps With TypeScript
Building Better AngularJS 1.X Apps With TypeScript
 
Consejo de profesores 22 02
Consejo de profesores 22 02Consejo de profesores 22 02
Consejo de profesores 22 02
 
Derechos y obligaciones de los docentes
Derechos y obligaciones de los docentesDerechos y obligaciones de los docentes
Derechos y obligaciones de los docentes
 
Crafting ColdFusion Applications like an Architect
Crafting ColdFusion Applications like an ArchitectCrafting ColdFusion Applications like an Architect
Crafting ColdFusion Applications like an Architect
 
Floorplan (http://www.vlsisystemdesign.com/PD-Flow.php)
Floorplan (http://www.vlsisystemdesign.com/PD-Flow.php)Floorplan (http://www.vlsisystemdesign.com/PD-Flow.php)
Floorplan (http://www.vlsisystemdesign.com/PD-Flow.php)
 
Digital trends and challenges in B2B Commerce
Digital trends and challenges in B2B CommerceDigital trends and challenges in B2B Commerce
Digital trends and challenges in B2B Commerce
 
Visbreaking and Delayed coking
Visbreaking and Delayed cokingVisbreaking and Delayed coking
Visbreaking and Delayed coking
 
Omnichannel Marketing leicht gemacht: Lernen von den Besten
Omnichannel Marketing leicht gemacht: Lernen von den BestenOmnichannel Marketing leicht gemacht: Lernen von den Besten
Omnichannel Marketing leicht gemacht: Lernen von den Besten
 
Cracking
CrackingCracking
Cracking
 
Minor Project (Rohit Sharma)
Minor Project (Rohit Sharma)Minor Project (Rohit Sharma)
Minor Project (Rohit Sharma)
 

Ähnlich wie Cfml features modern_coding

CFWheels - Pragmatic, Beautiful Code
CFWheels - Pragmatic, Beautiful CodeCFWheels - Pragmatic, Beautiful Code
CFWheels - Pragmatic, Beautiful Codeindiver
 
CFML Enhancements in ColdFusion 10
CFML Enhancements in ColdFusion 10 CFML Enhancements in ColdFusion 10
CFML Enhancements in ColdFusion 10 Mindfire Solutions
 
Cfml features modern coding into the box 2018
Cfml features modern coding into the box 2018Cfml features modern coding into the box 2018
Cfml features modern coding into the box 2018Ortus Solutions, Corp
 
How to use the new Domino Query Language
How to use the new Domino Query LanguageHow to use the new Domino Query Language
How to use the new Domino Query LanguageTim Davis
 
Language Enhancement in ColdFusion 8 - CFUnited 2007
Language Enhancement in ColdFusion 8 - CFUnited 2007Language Enhancement in ColdFusion 8 - CFUnited 2007
Language Enhancement in ColdFusion 8 - CFUnited 2007Rupesh Kumar
 
Language enhancement in ColdFusion 8
Language enhancement in ColdFusion 8Language enhancement in ColdFusion 8
Language enhancement in ColdFusion 8Rupesh Kumar
 
Setting up your Multi Engine Environment - Apache Railo and ColdFusion
Setting up your Multi Engine Environment - Apache Railo and ColdFusionSetting up your Multi Engine Environment - Apache Railo and ColdFusion
Setting up your Multi Engine Environment - Apache Railo and ColdFusionGavin Pickin
 
Language Basics | Coldfusion primer | Chap-1
Language Basics | Coldfusion primer | Chap-1Language Basics | Coldfusion primer | Chap-1
Language Basics | Coldfusion primer | Chap-1Nafis Ahmed
 
#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble App#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble AppPebble Technology
 
The Hitchhiker's Guide to Faster Builds. Viktor Kirilov. CoreHard Spring 2019
The Hitchhiker's Guide to Faster Builds. Viktor Kirilov. CoreHard Spring 2019The Hitchhiker's Guide to Faster Builds. Viktor Kirilov. CoreHard Spring 2019
The Hitchhiker's Guide to Faster Builds. Viktor Kirilov. CoreHard Spring 2019corehard_by
 
ColdFusion Fw1 (FrameWork1) introduction
ColdFusion Fw1 (FrameWork1) introductionColdFusion Fw1 (FrameWork1) introduction
ColdFusion Fw1 (FrameWork1) introductionSaravanaMuthu Jayaraj
 
Coldfusion basics training by Live instructor
Coldfusion basics training by Live instructorColdfusion basics training by Live instructor
Coldfusion basics training by Live instructorLearnFunGo
 
Flink Forward Berlin 2018: Edward Alexander Rojas Clavijo - "Deploying a secu...
Flink Forward Berlin 2018: Edward Alexander Rojas Clavijo - "Deploying a secu...Flink Forward Berlin 2018: Edward Alexander Rojas Clavijo - "Deploying a secu...
Flink Forward Berlin 2018: Edward Alexander Rojas Clavijo - "Deploying a secu...Flink Forward
 
LiveCycle Data Services for ColdFusion Developers
LiveCycle Data Services for ColdFusion DevelopersLiveCycle Data Services for ColdFusion Developers
LiveCycle Data Services for ColdFusion DevelopersSteven Erat
 
Introduction to Laravel Framework (5.2)
Introduction to Laravel Framework (5.2)Introduction to Laravel Framework (5.2)
Introduction to Laravel Framework (5.2)Viral Solani
 

Ähnlich wie Cfml features modern_coding (20)

CFWheels - Pragmatic, Beautiful Code
CFWheels - Pragmatic, Beautiful CodeCFWheels - Pragmatic, Beautiful Code
CFWheels - Pragmatic, Beautiful Code
 
CFML Enhancements in ColdFusion 10
CFML Enhancements in ColdFusion 10 CFML Enhancements in ColdFusion 10
CFML Enhancements in ColdFusion 10
 
Cfml features modern coding into the box 2018
Cfml features modern coding into the box 2018Cfml features modern coding into the box 2018
Cfml features modern coding into the box 2018
 
How to use the new Domino Query Language
How to use the new Domino Query LanguageHow to use the new Domino Query Language
How to use the new Domino Query Language
 
Language Enhancement in ColdFusion 8 - CFUnited 2007
Language Enhancement in ColdFusion 8 - CFUnited 2007Language Enhancement in ColdFusion 8 - CFUnited 2007
Language Enhancement in ColdFusion 8 - CFUnited 2007
 
Language enhancement in ColdFusion 8
Language enhancement in ColdFusion 8Language enhancement in ColdFusion 8
Language enhancement in ColdFusion 8
 
Setting up your Multi Engine Environment - Apache Railo and ColdFusion
Setting up your Multi Engine Environment - Apache Railo and ColdFusionSetting up your Multi Engine Environment - Apache Railo and ColdFusion
Setting up your Multi Engine Environment - Apache Railo and ColdFusion
 
ColdFusion 10
ColdFusion 10ColdFusion 10
ColdFusion 10
 
ITB2017 - Keynote
ITB2017 - KeynoteITB2017 - Keynote
ITB2017 - Keynote
 
Language Basics | Coldfusion primer | Chap-1
Language Basics | Coldfusion primer | Chap-1Language Basics | Coldfusion primer | Chap-1
Language Basics | Coldfusion primer | Chap-1
 
#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble App#PDR15 - waf, wscript and Your Pebble App
#PDR15 - waf, wscript and Your Pebble App
 
The Hitchhiker's Guide to Faster Builds. Viktor Kirilov. CoreHard Spring 2019
The Hitchhiker's Guide to Faster Builds. Viktor Kirilov. CoreHard Spring 2019The Hitchhiker's Guide to Faster Builds. Viktor Kirilov. CoreHard Spring 2019
The Hitchhiker's Guide to Faster Builds. Viktor Kirilov. CoreHard Spring 2019
 
ColdFusion Fw1 (FrameWork1) introduction
ColdFusion Fw1 (FrameWork1) introductionColdFusion Fw1 (FrameWork1) introduction
ColdFusion Fw1 (FrameWork1) introduction
 
CBDW2014 - This is ColdBox 4
CBDW2014 - This is ColdBox 4CBDW2014 - This is ColdBox 4
CBDW2014 - This is ColdBox 4
 
Coldfusion basics training by Live instructor
Coldfusion basics training by Live instructorColdfusion basics training by Live instructor
Coldfusion basics training by Live instructor
 
PowerShell-1
PowerShell-1PowerShell-1
PowerShell-1
 
Top5 scalabilityissues
Top5 scalabilityissuesTop5 scalabilityissues
Top5 scalabilityissues
 
Flink Forward Berlin 2018: Edward Alexander Rojas Clavijo - "Deploying a secu...
Flink Forward Berlin 2018: Edward Alexander Rojas Clavijo - "Deploying a secu...Flink Forward Berlin 2018: Edward Alexander Rojas Clavijo - "Deploying a secu...
Flink Forward Berlin 2018: Edward Alexander Rojas Clavijo - "Deploying a secu...
 
LiveCycle Data Services for ColdFusion Developers
LiveCycle Data Services for ColdFusion DevelopersLiveCycle Data Services for ColdFusion Developers
LiveCycle Data Services for ColdFusion Developers
 
Introduction to Laravel Framework (5.2)
Introduction to Laravel Framework (5.2)Introduction to Laravel Framework (5.2)
Introduction to Laravel Framework (5.2)
 

Mehr von ColdFusionConference

Building better SQL Server Databases
Building better SQL Server DatabasesBuilding better SQL Server Databases
Building better SQL Server DatabasesColdFusionConference
 
API Economy, Realizing the Business Value of APIs
API Economy, Realizing the Business Value of APIsAPI Economy, Realizing the Business Value of APIs
API Economy, Realizing the Business Value of APIsColdFusionConference
 
Security And Access Control For APIS using CF API Manager
Security And Access Control For APIS using CF API ManagerSecurity And Access Control For APIS using CF API Manager
Security And Access Control For APIS using CF API ManagerColdFusionConference
 
Monetizing Business Models: ColdFusion and APIS
Monetizing Business Models: ColdFusion and APISMonetizing Business Models: ColdFusion and APIS
Monetizing Business Models: ColdFusion and APISColdFusionConference
 
Developer Insights for Application Upgrade to ColdFusion 2016
Developer Insights for Application Upgrade to ColdFusion 2016Developer Insights for Application Upgrade to ColdFusion 2016
Developer Insights for Application Upgrade to ColdFusion 2016ColdFusionConference
 
ColdFusion Keynote: Building the Agile Web Since 1995
ColdFusion Keynote: Building the Agile Web Since 1995ColdFusion Keynote: Building the Agile Web Since 1995
ColdFusion Keynote: Building the Agile Web Since 1995ColdFusionConference
 
Build your own secure and real-time dashboard for mobile and web
Build your own secure and real-time dashboard for mobile and webBuild your own secure and real-time dashboard for mobile and web
Build your own secure and real-time dashboard for mobile and webColdFusionConference
 
Everyones invited! Meet accesibility requirements with ColdFusion
Everyones invited! Meet accesibility requirements with ColdFusionEveryones invited! Meet accesibility requirements with ColdFusion
Everyones invited! Meet accesibility requirements with ColdFusionColdFusionConference
 

Mehr von ColdFusionConference (20)

Api manager preconference
Api manager preconferenceApi manager preconference
Api manager preconference
 
Cf ppt vsr
Cf ppt vsrCf ppt vsr
Cf ppt vsr
 
Building better SQL Server Databases
Building better SQL Server DatabasesBuilding better SQL Server Databases
Building better SQL Server Databases
 
API Economy, Realizing the Business Value of APIs
API Economy, Realizing the Business Value of APIsAPI Economy, Realizing the Business Value of APIs
API Economy, Realizing the Business Value of APIs
 
Don't just pdf, Smart PDF
Don't just pdf, Smart PDFDon't just pdf, Smart PDF
Don't just pdf, Smart PDF
 
Security And Access Control For APIS using CF API Manager
Security And Access Control For APIS using CF API ManagerSecurity And Access Control For APIS using CF API Manager
Security And Access Control For APIS using CF API Manager
 
Monetizing Business Models: ColdFusion and APIS
Monetizing Business Models: ColdFusion and APISMonetizing Business Models: ColdFusion and APIS
Monetizing Business Models: ColdFusion and APIS
 
ColdFusion in Transit action
ColdFusion in Transit actionColdFusion in Transit action
ColdFusion in Transit action
 
Developer Insights for Application Upgrade to ColdFusion 2016
Developer Insights for Application Upgrade to ColdFusion 2016Developer Insights for Application Upgrade to ColdFusion 2016
Developer Insights for Application Upgrade to ColdFusion 2016
 
Where is cold fusion headed
Where is cold fusion headedWhere is cold fusion headed
Where is cold fusion headed
 
ColdFusion Keynote: Building the Agile Web Since 1995
ColdFusion Keynote: Building the Agile Web Since 1995ColdFusion Keynote: Building the Agile Web Since 1995
ColdFusion Keynote: Building the Agile Web Since 1995
 
Instant ColdFusion with Vagrant
Instant ColdFusion with VagrantInstant ColdFusion with Vagrant
Instant ColdFusion with Vagrant
 
Restful services with ColdFusion
Restful services with ColdFusionRestful services with ColdFusion
Restful services with ColdFusion
 
Build your own secure and real-time dashboard for mobile and web
Build your own secure and real-time dashboard for mobile and webBuild your own secure and real-time dashboard for mobile and web
Build your own secure and real-time dashboard for mobile and web
 
Why Everyone else writes bad code
Why Everyone else writes bad codeWhy Everyone else writes bad code
Why Everyone else writes bad code
 
Securing applications
Securing applicationsSecuring applications
Securing applications
 
Testing automaton
Testing automatonTesting automaton
Testing automaton
 
Rest ful tools for lazy experts
Rest ful tools for lazy expertsRest ful tools for lazy experts
Rest ful tools for lazy experts
 
Hidden gems in cf2016
Hidden gems in cf2016Hidden gems in cf2016
Hidden gems in cf2016
 
Everyones invited! Meet accesibility requirements with ColdFusion
Everyones invited! Meet accesibility requirements with ColdFusionEveryones invited! Meet accesibility requirements with ColdFusion
Everyones invited! Meet accesibility requirements with ColdFusion
 

Cfml features modern_coding

  • 1. CFML Features for More Modern Coding Dan Fredericks fmdano@gmail.com @fmdano74 http://www.meetup.com/nvcfug/
  • 2. What this Presentation will cover: • CFML History of top features • CFScript Support • QueryExecute() Function • Member Functions • Elvis Function • Closures • Map and Reduce • First Class Functions and Callbacks • CF 12 Special
  • 3. ColdFusion Feature History • ColdFusion 1: CF1 was an interesting animal, it predates the CFML language, back then it was DBML (Database Markup Language) and it used a tag named <dbquery> to define a query and then <dbsql> to append SQL to that query. There was a <dbset> a <dbif> and not much else. • ColdFusion 2: CF2 introduced CFML, and introduced dynamic SQL built within a <cfquery> tag. • ColdFusion 3: CF3 was less significant for the language, and more for the introduction of CF Studio. • ColdFusion 4 • Invoke Java Objects • ColdFusion 5 • Macromedia • CFScript-based UDFs • ColdFusion 6 • Server rewritten in Java (MX) • CFML Language API with an OOP Interface • ColdFusion MX 7 • Flash-Based forms • Report builder
  • 4. ColdFusion Feature History • Adobe ColdFusion 8 • CFPDFFORM integrate with Acrobat forms • .net integration (http://www.Microsoft.com/net) • Built in AJAX widgets • Array and structure improvement • CFPDF • Some CFScript enhancements • ColdFusion 9 • More CFScript support • Explicit local scope • getters/setters in CFC’s • Init (implicit constructions via method) in CFC • ORM
  • 5. ColdFusion Feature History • ColdFusion 10 • Security enhancements • Tomcat Integration • Restful web services • Hotfix Updater in Admin • Language enhancements – Closures, CFScript, etc. • ColdFusion 11 • Full CFScript Support • Member Functions • Elvis Operator • queryExecute • built in functions elevated to first-class functions
  • 6. 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
  • 7. CFScript • Community has different opinions on using Tag vs Script • Using MVC Tags on View, Script on Controller and Model • Script syntax is cleaner • Closer to other ECMA script languages • Lots of tag syntax is more characters • I am more comfortable with Tags • Documentation is lacking for Script (check cfdocs.org) • Tags were superior for SQL integration (talk about this later) • Newer features such as Closures are script based • Do what is best for you but try to be consistent!!!
  • 8. CFScript Syntax – tags without Bodies: cfTagName( attribute-pairs* ); writeDump(var); writeOutput(expression); Location(“mypage.cfm”,”false”); Syntax – tags with Bodies: cfTagName( attribute-pairs* ) { …}; cfDocument(format=“PDF”) { //code } For (i=1; i<=10; i++) { //code }
  • 9. CFScript • There are some tags that have multiple implementations • These implementations are due to old syntax or dual syntax (CF9 cfc’s) <cfscript> //CF9 syntax thread action=“run” name=“testName” { thread.test = “CFML”; } //CF11 syntax cfthread( action=“run” name=“testName”){ thread.test = “CFML”; } <cfscript>
  • 10. CFScript <cfscript> //CF9 syntax param name=“local.summit” type = “string” default = “CFSummit”; //CF11 syntax cfparam( name = “local.summit” type = “string” default = “CFSummit”); </cfscript>
  • 11. CFScript <cfscript> //CF9 syntax abort “some message”; //CF11 syntax cfabort( showError = “some message”); </cfscript>
  • 12. CFScript Tag Example • Loop <cfloop from=“1” to=“10”index=“i”> <cfoutput>#i#</cfoutput> </cfloop> Script Example • For Loop for (i=1; i <=5; i++) { // all statements in the block are looped over result = i * 2; writeOutput(result); } • While Loop while (condition) { // statements }
  • 13. CFScript Tag Example • If/elseif/else example: <cfset count = 10> <cfif count GT 20> <cfoutput>#count#</cfoutput> <cfelseif count GT 8> <cfoutput>#count#</cfoutput> <cfelse> <cfoutput>#count#</cfoutput> <cfif> Script Example • If/elseif/else example: <cfscript> count = 10; if (count > 20) { writeOutput(count); } else if (count == 8) { writeOutput(count); } else { writeOutput(count); } </cfscript>
  • 14. CFScript Tag Example • Query Loop <cfset platform = ["Adobe ColdFusion", "Railo", "Lucee"]> <cfset myQuery = queryNew(" ")> <cfset queryAddColumn(myQuery, "platform", "CF_SQL_VARCHAR", platform)> <cfloop index="i" from="1" to="#myQuery.recordCount#"> <cfoutput><li>#myQuery["platform"][i]#</li></cfoutput> </cfloop> OR <cfloop query="myQuery" group="platform"> <cfoutput><li>#platform#</li></cfoutput> </cfloop> Script Example • Query Loop q = queryNew("id,data", "integer,varchar", [ [11, "aa"], [22, "bb"], [33, "cc"] ] ); for (row in q){ writeOutput("#q.currentRow#:#row.id#:#row.data#;"); //result: 1:11:aa;2:22:bb;3:33:cc; } OR cfloop(query=q, group="fk"){ writeOutput("<strong>#fk#</strong>"); }
  • 15. CFScript Tag Example <cfcomponent displayname="utils" output="false" > <cfproperty name="version" type="string" default="0.0.1" > <cffunction name="doReverse" access="public" returntype="string" hint="I reverse the supplied string" > <cfargument name="stringToReverse" required="true" type="string" > <cfreturn reverse(arguments.stringToReverse) > </cffunction> <cffunction name="reverseArrayOrder" access="public" returntype="array" hint="I reverse an array's order" > <cfargument name="arrayToReverse" type="array" default='["Adobe ColdFusion", "Lucee", "Railo"]' > <cfset local.result = '' /> <cfloop array="arguments.arrayToRevers" index=“local.a" > <cfset arrayAppend(local.result, local.a) > </cfloop> <cfreturn local.result /> </cffunction> </cfcomponent>
  • 16. CFScript Script Example component displayname="Utils" output="false" { (property name="version" type="string" default="0.0.1";) – not really needed public string function doReverse(required string stringToReverse) hint="I reverse the supplied string" { return reverse(arguments.stringToReverse); } public array function reverseArrayOrder(array arrayToReverse = ["Adobe ColdFusion", "Lucee", "Railo"]) hint="I reverse an array's order" { var result = []; for (var i = arrayLen(arguments.arrayToReverse); i >= 1; i--) { result.append(arguments.arrayToReverse[i]); } return result; } }
  • 17. CFScript Resources: • ColdFusion Online Docs : https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-tags/tags-r- s/cfscript.html#cfscript-Scriptsupportfortags • CFDocs: http://cfdocs.org/ • CFChef GitHub: https://github.com/cfchef/cfml-tag-to-script-conversions/blob/master/README.md#general • Adam Cameron GitHub: https://github.com/adamcameron/cfscript/blob/master/cfscript.md#database • Pete Freitag Cheat sheet: http://www.petefreitag.com/cheatsheets/coldfusion/cfscript/
  • 18. QueryExecute • CFQUERY has been the staple to query a database since day 1 • There have been a few attempts to query the database using script • Here is the latest alternative for script based syntax Syntax: QueryExecute( sql_stmt, queryParams, queryOptions );
  • 19. QueryExecute Old Script Syntax <cfscript> q = new com.adobe.coldfusion.query(); q.setDatasource("cfartgallery"); q.setSQL("select * from art where artname like :search or description like :search"); q.addParam(name="search",value="%e%",cfsqltype="cf_sql_varchar"); r = q.execute(); </cfscript>
  • 20. QueryExecute New Script Syntax queryExecute( sql_stmt, queryParam, 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”} );
  • 21. QueryExecute queryExecute( sql_stmt, queryParam, queryOptions); Tag Syntax <cfquery name=“qryResult”> SELECT * FROM Employees </cfquery> Script Syntax qryResult = queryExecute( "SELECT * FROM Employees“ ); Note: queryExecute is just a function so can be used in tags as well: <cfset temp = queryExecute(…) >
  • 22. QueryExecute queryExecute( sql_stmt, queryParam, queryOptions); Tag Syntax <cfset country = “USA” /> <cfset empid = 1 /> <cfquery name=“qryResult”> SELECT * FROM Employees WHERE empid = #empID# AND country = #country# </cfquery> ** Should use cfqueryparm Script Syntax (Parameters using Struct) qryResult = queryExecute(“ SELECT * FROM Employees WHERE empid = :empid AND country = :country", {country="USA", empid=1} );
  • 23. QueryExecute queryExecute( sql_stmt, queryParam, queryOptions); Tag Syntax (Specify a datasource) <cfquery name=“qryResult” datasource = “myDatasourceName”> SELECT * FROM Employees </cfquery> Script Syntax (Specify a datasource) qryResult = queryExecute(“ SELECT * FROM Employees", {}, {datasource= "myDataSourceName"} );
  • 24. QueryExecute queryExecute( sql_stmt, queryParam, queryOptions); Tag Syntax (query with a subquery) <cffunction name=“getEqMfg” returntype=“query” access=“public”> <cfargument name=“dc” cfsqltype=“string” required=“true”> <cfquery name=“ml” datasource=“myDSN”> Select name, mfgCode, country From mfgdetails_tbl Where mfgcode in ( Select mfgCode From mfg2devices_tbl Where deviceCode = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.dc#“ maxlength=“5”> ) Order By country, name </cfquery> <cfreturn ml > </cffunction> Script Syntax (query with a subquery) public query function getEqMfg(required string dc){ var ml = queryExecute("Select name, mfgCode, country From mfgdetails_tbl Where mfgcode in ( Select mfgCode From mfg2devices_tbl Where deviceCode = :dcp ) Order By country, name", {dcp={value="dc",cfsqltype="CF_SQL_VARCHAR", maxlength=5 }}, {datasource = “myDSN”} ); return ml; }
  • 25. QueryExecute queryExecute( sql_stmt, queryParam, queryOptions); Tag Syntax (Return a number/count or maxRows) <cfquery name=“dsc”> Select count(*) as qty From generic_view” </cfquery> <cfquery name=“sc” maxrows=“#rc#”> Select specialtyname, qty From generic_view Order by qty DESC, specialtyname </cfquey> Script Syntax (Return a number/count or maxRows) public numeric function getSpecialtyCount(){ var dsc = queryExecute("Select Count(*) as qty From specialtycategorycount_view"); return dsc.qty; } query function getSpecialtyCodeChartData(required numeric rc=99){ var sc = queryExecute("Select specialtyname, qty From specialtycategorycount_view Order by qty DESC, specialtyname", {}, {maxrows = "rc"}); return sc; }
  • 26. QueryExecute queryExecute: https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion- functions/functions-m-r/queryexecute.html CFDocs.org: http://cfdocs.org/queryexecute Query options: http://stackoverflow.com/questions/26296467/what-are-the-options-for- queryoptions-in-the-queryexecute-function Get rid of cfqueryparam: http://blog.adamcameron.me/2014/03/querycfc-queryexecute- have-good-feature.html Check out cfuser examples: http://www.cfuser.com/more-queryexecute-examples/ Cfuser: http://www.cfuser.com/more-queryexecute-examples/
  • 27. Member 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()
  • 28. Member Functions 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() Chaining: stringVar.find(“I like cfml”, “cfml”).uCase()
  • 29. Member Functions Regular CF function syntax dateTimeFormat( dateAdd( 'd', -5, now() ) , 'yyyy-mm-dd' ); dateTimeFormat( dateAdd( 'd', -5, now() ), 'yyyy-mm-dd' ); Note: dateTimeFormat function was added in CF10, combo of dateTime and timeFormat. Member Function syntax now().add( 'd', -5 ) .dateTimeFormat( 'yyyy-mm-dd' ); now().add( 'd', -5 ).dateTimeFormat( 'yyyy-mm-dd' );
  • 30. Member Functions 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();
  • 31. Member Functions Regular CF function syntax var myArray = ArrayNew(1); ArrayAppend(myArray, "objec_new"); ArraySort(myArray, "ASC"); Member Function syntax myArray.append("objec_new"); myArray.sort("ASC");
  • 32. Member Functions • Important Note on a potential Member Function Gotcha: • Some member functions might fall into underlying Java methods if the strict ColdFusion syntax is not followed. • https://bugbase.adobe.com/index.cfm?event=bug&id=3753710
  • 33. Member Functions • Resources Adobe ColdFusion wiki: https://helpx.adobe.com/coldfusion/developing- applications/building-blocks-of-coldfusion-applications/using-the-member-functions.html
  • 34. 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.
  • 35. Elvis Operator • Syntax: ?: value = ( url.foo ?: "bar" ); • The Elvis operator is primarily used to assign the ‘right default’ for a variable or an expression • Or it is a short-hand way to do parameterization. It will allow us to set a value if the variable is Null
  • 36. Elvis Operator Examples which are all the same: 1. If ( isNull(local.testVar)){ value = “test Item”; } else{ value = local.newTest; } 2. Value = (local.testVar ?: “test Item”); 3. Value = (isNull(local.testVar) ? “test Item”: local.newTest);
  • 37. Elvis Operator 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“
  • 38. Elvis Operator • Resources: • Wiki docs https://helpx.adobe.com/coldfusion/developing-applications/the-cfml-programming- language/elements-of-cfml/elvis-operator.html
  • 39. 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 closure is. It knows about its origin and it doesn't forget. It will always be tied to that same parent var scope.
  • 40. Closures javascript example (works in CF also) Function outerFunction() { var a = 3; return function innerFunction(b){ var c = a + b; return c; } } (1) var foo = outerFunction() (2) var result = foo(2); (3) Console.log(result); //5 • We have an outer function with a nested function which accepts a parameter b • (1)When you invoke the outer you get the inner returned later. • (2)Notice the outer function was called but the a still has its value and is used in the return function (innerFunction). • (3)That is why the result Is 5! • http://taha-sh.com/blog/understanding- closures-in-javascript
  • 41. Closures function bunchofstuff(…) { // OLD CODE …bunch of stuff… } function restofstuff(…) { …rest of stuff… } function stuff1(…) { bunchofstuff(…); …more stuff… restofstuff(…); } function stuff2(…) { bunchofstuff(…); …other stuff… restofstuff(…); } You still have 4 functions and stuff1 and 2 still have common code function generalstuff(…, differentstuff) { // CLOSURE WAY …bunch of stuff… differentstuff(…); …general code… } function stuff1(…) { generalstuff(…, function(…){ …more specific stuff… }); } function stuff2(…) { generalstuff(…, function(…){ …more specific stuff… }); } Using the closure code above all common code is in general stuff and… you call stuff1 or stuff 2 for the specific code you need run (Template Method design pattern)
  • 42. Closures 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 • 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.
  • 43. Closures • Ray Camden example (technically is, but more like a callback/inline function) : Data = [“Neil Diamond”, “Depeche Mode”, “The Cure”, “Cher”, “Ace of Base”, “Frank Sinatra”, The Church”]; arraySort(data, function(a,b){ var first = a; var second = b; first = replace(first, “The “, “”); second = replace(second, “The “, “”); return first gt second; }); This code above will order the data array by names excluding THE. Ace of Base, Cher, The Church, The Cure, Depeche Mode, Frank Sinatra, Neil Diamond
  • 44. Closures 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
  • 46. Closures structEach structEach( struct, function(key, value) { } ); structEach({one:1, two:2}, function(key, value) { writeoutput(key & “:” & value); }); Answer: ONE: 1 TWO: 2
  • 47. Closures arrayFilter( array,function(arrayElement, [,index, array]) {return true|false;} ); Note: CF 11 - the callback functions of all the filters have access to the entire array/list/struct apart from the current element • ArrayFilter Filtered = arrayFilter([“myNewBike”, “oldBike”], function(item) { return len(item) > 8; }); Answer => [1]
  • 48. Closures arrayFindAll ArrayFindAll(array, object) or ArrayFindAll( array, function(arrayElement) { return true|false; } ) Data=[{age:4}, {age:6}, {age:41}]; Answer = arrayFindAll(data, function(item){ return item.age < 10; }); Answer [1,2]
  • 49. Closures arrayReduce ArrayReduce( array, function(result, item, [,index, array]) [, initialValue] ) complexData = [{a:4}, {a:18}, {a:51}]; Function reducer(prev, element){ return prev + element.a; } sumOfData = arrayReduce(complexData, reducer, 0); Answer 73
  • 50. Closures arrayMap ArrayMap( array, function(item [,index, array]) ) complexData = [{a:4}, {a:18}, {a:51}]; newArray = arrayMap(complexData, function(item){ return item.a; }, 0); Answer [4, 18, 51]
  • 51. Closures Testbox: https://www.ortussolutions.com/product/testbox • TestBox uses Closures • Since the implementations of the describe() and it() functions are closures, they can contain executable code that is necessary to implement the test. All ColdFusion rules of scoping apply to closures, so please remember them. We recommend always using the variables scope for easy access and distinction. • A test suite begins with a call to our TestBox describe() function with at least two arguments: a title and a closure within the life-cycle method called run(). The title is the name of the suite to register and the function is the block of code that implements the suite. function run() { describe("A suite is a closure", function() { c = new Calculator(); it("and so is a spec", function() { expect( c ).toBeTypeOf( 'component' ); }); }); }
  • 52. Closures • Some Example code online or resources: • Sesame library inline functions/closures https://github.com/markmandel/Sesame • Underscore.cfc ported from underscore.js https://github.com/russplaysguitar/UnderscoreCF • TestBox gives the ability to use closures http://wiki.coldbox.org/wiki/TestBox.cfm • Adam Tuttle presentation on closures http://fusiongrokker.com/p/closures/#/ • Adam Cameron blog multiple Closure examples http://blog.adamcameron.me/search/label/Closure
  • 53. Map and Reduce (and more) • 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. • So it remaps the original collection • ArrayMap, StructMap, ListMap • 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. • ArrayReduce, StructReduce, ListReduce
  • 54. Map and Reduce (and more) • 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. structEach(circles,function(key,value) { matchednames = arrayfilter(value,function(obj) { return left(obj,1)=='d'; } }); Example shows how to look at a struct and if it begins with a D, return it.
  • 55. Map and Reduce (and more) • The each() function iterates over a given object and calls a callback for each element. This can be used instead of a loop. letters = ["a","b","c","d"]; arrayEach(letters, function() { writeDump(arguments); }); Struct 1 a struct 1 b struct 1 c struct 1 d
  • 56. Map and Reduce (and more) • Map() complexData = [ {a: 4}, {a: 18}, {a: 51} ]; newArray = arrayMap( complexData, function(item) { return item.a; }, 0 ); Answer: [4, 18, 51]
  • 57. Map and Reduce (and more) • Reduce() complexData = [ {a: 4}, {a: 18}, {a: 51} ]; sum = arrayReduce( complexData, function(prev, element) { return prev + element.a; }, 0 ); Answer: 73
  • 58. Map and Reduce (and more) • ArrayMap Example ( next few examples from Adam Cameron): rainbow = ["Whero","Karaka","Kowhai","Kakariki","Kikorangi","Tawatawa","Mawhero"]; colourInList = arrayMap( rainbow, function(v,i,a){ return replace(a.toList(), v, ucase(v) ); } ); writeDump([rainbow,colourInList]); Will see an array of Rainbow with 7 items each showing the next in the row all caps: WHERO,Karaka,Kowhai,Kakariki,Kikorangi,Tawatawa,Mawhero whero,KARAKA,Kowhai,Kakariki,Kikorangi,Tawatawa,Mawhero whero,karaka,KOWHAI,Kakariki,Kikorangi,Tawatawa,Mawhero
  • 59. Map and Reduce (and more) • StructMap() original = {"one"={1="tahi"},"two"={2="rua"},"three"={3="toru"},"four"={4="wha"}}; fixed = structMap(original, function(k,v) { return v[v.keyList().first()]; }); writeDump([ original, fixed]); This just returns the digit as a key and Maori number as a value 1 tahi 2 rua 3 toru 4 wha
  • 60. Map and Reduce (and more) • listMap() Rainbow = "Whero, Karaka, Kowhai, Kakariki, Kikorangi, Tawatawa, Mawhero"; externalList = ""; reverseRainbow = listMap( rainbow, function(v,i,l) { var newValue = "#i#:#v.reverse()#"; externalList = externalList.append(newValue); return newValue; }); writeDump([{rainbow=rainbow},{reverseRainbow=reverseRainbow},{externalList=externalList}]); This should reverse the rainbow list and show it backwards.
  • 61. Map and Reduce (and more) • listReduce() numbers = "1,2,3,4,5,6,7,8,9,10"; sum = listReduce(numbers, function(previousValue, value) { return previousValue + value; }, 0); writeOutput("The sum of the digits #numbers# is #sum#<br>"); The sum of the digits 1,2,3,4,5,6,7,8,9,10 is 55
  • 62. Map and Reduce (and more) • arrayReduce() rainbow = ["Whero","Karaka","Kowhai","Kakariki","Kikorangi","Tawatawa","Mawhero"] ; ul = arrayReduce(rainbow, function(previousValue, value) { return previousValue & "<li>#value#</li>"; }, "<ul>" ) & "</ul>"; writeOutput(ul); Result is just the Array turned into a list
  • 63. Map and Reduce (and more) • structReduce() • StructReduce(struct, function(result, key, value [,struct]), initialVal) rainbow = { "Red"="Whero", "Orange"="Karaka", "Yellow"="Kowhai", "Green"="Kakariki” }; ui = structReduce( rainbow, function(previousValue, key, value) { return previousValue & "<dt>#key#</dt><dd>#value#</dd>"; }, "<dl>" ) & "</dl>"; writeOutput(dl); Result is a two column list of the key and the value: Blue Kikorangi
  • 64. Map and Reduce (and more) • Resources • map and reduce & more with adam: http://blog.adamcameron.me/2014/02/coldfusion-11-map-and-reduce.html • map reduce: https://hacks.mozilla.org/2015/01/from-mapreduce-to-javascript-functional-programming/ • js working example of each: http://elijahmanor.com/reducing-filter-and-map-down-to-reduce/
  • 65. 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
  • 66. First Class Functions • What is a Callback function? • This is a function that is passed into another function. • You build a main generic function to do work, then you can pass in a more detailed function to do a lot of the work. • Sorting, you might want to sort money data, or state data, or city data • Build a sort function then pass in the callback function you need to do your sort Sort(dataToSort, callBackFunction) { //do stuff } callbackFunction() { //build sort } Calls the Sort function: sortedData = sort(unsortedData, callbackFunction);
  • 67. First Class Functions 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
  • 68. First Class Functions This is where lcase and ucase are being returned from a function: Function convertArray(array array, string caseTo){ caseConvertFunction = getConvertFunction(caseTo); for (var i=1, I <= arrayLen(array); i++){ array[i] = caseConverterFunction{array[i]); }} Function getConvertFunction (String caseType){ if (caseType == ‘lower’) return lcase; else return ucase; } resultArray_lower = convertArray([‘One’, ‘Two’, ‘Three’], ‘lower’); resultArray_upper = convertArray([‘One’, ‘Two’, ‘Three’], ‘upper’); _lower array: one, two, three _upper array: ONE, TWO, THREE
  • 69. First Class Functions • Resources • http://blogs.coldfusion.com/post.cfm/language-enhancements-in-coldfusion- splendor-promoing-built-in-cf-function-to-first-class • http://blog.adamcameron.me/2013/09/wow-coldfusions-built-in-functions- will.html • http://blog.adamcameron.me/2012/09/callbacks-function-expressions.html • Sesame project: https://github.com/markmandel/Sesame • Adobe Online Docs: https://helpx.adobe.com/coldfusion/developing- applications/the-cfml-programming-language/built-in-functions-as-first-class- citizen.html
  • 70. ColdFusion 12 feature • NDA – What I will show here may not be talked about until Adobe allows the discussion to be public. • ColdFusion 12 has the code name of RAIJIN
  • 71. ColdFusion 12 Feature • 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
  • 72. ColdFusion 12 Feature Old way: if(isDefined("foo")) writeOutput(foo.bar()); else writeOutput("not defined"); New way: writeOutput(foo?.bar()); 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
  • 73. ColdFusion 12 Feature • There are a few other new Language enhancements not discussed today • There are new enhancements to current features of ColdFusion • There is also a few new features that will be announced soon Resources: Adam Cameron Blog: http://blog.adamcameron.me/2015/10/coldfusion-12-it- goes-to-show-you.html
  • 74. Final Thoughts/Resources • These topics were only some more modern concepts for CFML. • Where to get more information from CFML Community • Adobe Wiki • CFDocs.org • Cfblogger (put in aggregator like feedly) • Slack Channel – 700+ cfml users https://cfml.slack.com/ • Twitter, Facebook, youTube, Vimeo and other social sites Dan Fredericks @fmdano74 fmdano@gmail.com I am on most social networks, twitter, facebook, G+, LinkedIn Special Thanks to Adam Cameron, Adam Tuttle, Ray Camden, Sean Corfield, and Brad Wood for examples