# Table of Contents - [Introduction | Learn Modern ColdFusion in 100 Minutes](#introduction-learn-modern-coldfusion-cfml-in-100-minutes) - [Welcome | Learn Modern ColdFusion in 100 Minutes](#welcome-learn-modern-coldfusion-cfml-in-100-minutes) - [Author | Learn Modern ColdFusion in 100 Minutes](#author-learn-modern-coldfusion-cfml-in-100-minutes) - [What is ColdFusion (CFML) | Learn Modern ColdFusion in 100 Minutes](#what-is-coldfusion-cfml-learn-modern-coldfusion-cfml-in-100-minutes) - [CommandBox CLI | Learn Modern ColdFusion in 100 Minutes](#commandbox-cli-learn-modern-coldfusion-cfml-in-100-minutes) - [Instructions & Interpreters | Learn Modern ColdFusion in 100 Minutes](#instructions-interpreters-learn-modern-coldfusion-cfml-in-100-minutes) - [Comments | Learn Modern ColdFusion in 100 Minutes](#comments-learn-modern-coldfusion-cfml-in-100-minutes) - [About This Book | Learn Modern ColdFusion in 100 Minutes](#about-this-book-learn-modern-coldfusion-cfml-in-100-minutes) - [Strings | Learn Modern ColdFusion in 100 Minutes](#strings-learn-modern-coldfusion-cfml-in-100-minutes) - [Syntax | Learn Modern ColdFusion in 100 Minutes](#syntax-learn-modern-coldfusion-cfml-in-100-minutes) - [Variable Scopes | Learn Modern ColdFusion in 100 Minutes](#variable-scopes-learn-modern-coldfusion-cfml-in-100-minutes) - [Operators | Learn Modern ColdFusion in 100 Minutes](#operators-learn-modern-coldfusion-cfml-in-100-minutes) - [JSON | Learn Modern ColdFusion in 100 Minutes](#json-learn-modern-coldfusion-cfml-in-100-minutes) - [Functions | Learn Modern ColdFusion in 100 Minutes](#functions-learn-modern-coldfusion-cfml-in-100-minutes) - [Null & Nothingness | Learn Modern ColdFusion in 100 Minutes](#null-nothingness-learn-modern-coldfusion-cfml-in-100-minutes) - [Static Constructs | Learn Modern ColdFusion in 100 Minutes](#static-constructs-learn-modern-coldfusion-cfml-in-100-minutes) - [Final Constructs | Learn Modern ColdFusion in 100 Minutes](#final-constructs-learn-modern-coldfusion-cfml-in-100-minutes) - [Abstract Constructs | Learn Modern ColdFusion in 100 Minutes](#abstract-constructs-learn-modern-coldfusion-cfml-in-100-minutes) - [Structures | Learn Modern ColdFusion in 100 Minutes](#structures-learn-modern-coldfusion-cfml-in-100-minutes) - [Numbers | Learn Modern ColdFusion in 100 Minutes](#numbers-learn-modern-coldfusion-cfml-in-100-minutes) - [Interfaces | Learn Modern ColdFusion in 100 Minutes](#interfaces-learn-modern-coldfusion-cfml-in-100-minutes) - [Conditionals | Learn Modern ColdFusion in 100 Minutes](#conditionals-learn-modern-coldfusion-cfml-in-100-minutes) - [Exception Management | Learn Modern ColdFusion in 100 Minutes](#exception-management-learn-modern-coldfusion-cfml-in-100-minutes) - [Properties | Learn Modern ColdFusion in 100 Minutes](#properties-learn-modern-coldfusion-cfml-in-100-minutes) - [Components | Learn Modern ColdFusion in 100 Minutes](#components-learn-modern-coldfusion-cfml-in-100-minutes) - [Variables | Learn Modern ColdFusion in 100 Minutes](#variables-learn-modern-coldfusion-cfml-in-100-minutes) - [Application.cfc | Learn Modern ColdFusion in 100 Minutes](#application-cfc-learn-modern-coldfusion-cfml-in-100-minutes) - [Arrays | Learn Modern ColdFusion in 100 Minutes](#arrays-learn-modern-coldfusion-cfml-in-100-minutes) - [Database Queries | Learn Modern ColdFusion in 100 Minutes](#database-queries-learn-modern-coldfusion-cfml-in-100-minutes) - [Includes | Learn Modern ColdFusion in 100 Minutes](#includes-learn-modern-coldfusion-cfml-in-100-minutes) - [Threading | Learn Modern ColdFusion in 100 Minutes](#threading-learn-modern-coldfusion-cfml-in-100-minutes) - [Closures | Learn Modern ColdFusion in 100 Minutes](#closures-learn-modern-coldfusion-cfml-in-100-minutes) - [File Handling | Learn Modern ColdFusion in 100 Minutes](#file-handling-learn-modern-coldfusion-cfml-in-100-minutes) - [Java Integration | Learn Modern ColdFusion in 100 Minutes](#java-integration-learn-modern-coldfusion-cfml-in-100-minutes) - [Code Locking | Learn Modern ColdFusion in 100 Minutes](#code-locking-learn-modern-coldfusion-cfml-in-100-minutes) - [Beyond The 100 | Learn Modern ColdFusion in 100 Minutes](#beyond-the-100-learn-modern-coldfusion-cfml-in-100-minutes) - [Image Manipulation | Learn Modern ColdFusion in 100 Minutes](#image-manipulation-learn-modern-coldfusion-cfml-in-100-minutes) - [Security Guide | Learn Modern ColdFusion in 100 Minutes](#security-guide-learn-modern-coldfusion-cfml-in-100-minutes) - [Sending Emails | Learn Modern ColdFusion in 100 Minutes](#sending-emails-learn-modern-coldfusion-cfml-in-100-minutes) - [Asynchronous Programming | Learn Modern ColdFusion in 100 Minutes](#asynchronous-programming-learn-modern-coldfusion-cfml-in-100-minutes) - [MVC | Learn Modern ColdFusion in 100 Minutes](#mvc-learn-modern-coldfusion-cfml-in-100-minutes) - [HTTP/S Calls | Learn Modern ColdFusion in 100 Minutes](#http-s-calls-learn-modern-coldfusion-cfml-in-100-minutes) - [Dependency Injection | Learn Modern ColdFusion in 100 Minutes](#dependency-injection-learn-modern-coldfusion-cfml-in-100-minutes) - [Welcome | Learn Modern ColdFusion in 100 Minutes](#welcome-learn-modern-coldfusion-cfml-in-100-minutes) - [Syntax | Learn Modern ColdFusion in 100 Minutes](#syntax-learn-modern-coldfusion-cfml-in-100-minutes) - [Beyond The 100 | Learn Modern ColdFusion in 100 Minutes](#beyond-the-100-learn-modern-coldfusion-cfml-in-100-minutes) - [MVC | Learn Modern ColdFusion in 100 Minutes](#mvc-learn-modern-coldfusion-cfml-in-100-minutes) - [Email Protection | Cloudflare](#email-protection-cloudflare) --- # Introduction | Learn Modern ColdFusion in 100 Minutes ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-LA-UVvdhvPQ4iTxu_CD%252Fuploads%252FhYstvPurtoN588M7uUZ8%252FCFML-logo-L.png%3Falt%3Dmedia%26token%3D4f93da73-2d31-4b41-b1fa-ad86e5b9f516&width=768&dpr=3&quality=100&sign=35c7d407&sv=2) cfml.rocks Welcome to the wonderful world of dynamic programming with ColdFusion . The purpose of this book is to jump-start developers into the ColdFusion programming language from a **MODERN** perspective and a focus on best practices, object orientation, and tooling. ColdFusion is not the same as it was 20 years ago; yes it's more than 20 years old! It's dynamic, vibrant, modern, fluent, and functional! Let's begin our adventure into the world of **MODERN** ColdFusion . [hashtag](https://modern-cfml.ortusbooks.com/#support-open-source) Support Open Source ------------------------------------------------------------------------------------------- This book is available free of charge [onlinearrow-up-right](https://modern-cfml.ortusbooks.com/) and commercially as a [downloadable or printed bookarrow-up-right](https://www.ortussolutions.com/learn/coldfusion) . Your support goes a long way to help the development of this book, future book endeavors, and all the open-source projects we work on. To support us, please consider becoming our patron at [patreon.com/ortussolutionsarrow-up-right](https://patreon.com/ortussolutions) for as little as $10/month. [hashtag](https://modern-cfml.ortusbooks.com/#ortus-solutions-corp) Ortus Solutions, Corp ---------------------------------------------------------------------------------------------- ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LA-UbMqUYOVVZvx_rxu%252F-LA-Uonn6zwzUcHtVri8%252Fortus-medium.jpg%3Fgeneration%3D1523647993812836%26alt%3Dmedia&width=768&dpr=3&quality=100&sign=1d5613bb&sv=2) This book was written and maintained by [Luis Majanoarrow-up-right](https://www.luismajano.com/) and the [Ortus Solutionsarrow-up-right](https://www.ortussolutions.com/) Development Team. > Ortus Solutions is a company that focuses on building professional open source tools, custom applications and great websites! We're the team behind ColdBox, the de-facto enterprise CFML HMVC Platform, TestBox, the CFML Testing and Behavior Driven Development (BDD) Framework, ContentBox, a highly modular and scalable Content Management System, CommandBox, the ColdFusion CLI, package manager, etc, and many more - [https://www.ortussolutions.com/arrow-up-right](https://www.ortussolutions.com/) [NextWelcomechevron-right](https://modern-cfml.ortusbooks.com/intro/intro) Last updated 2 years ago Was this helpful? --- # Welcome | Learn Modern ColdFusion in 100 Minutes Welcome to the wonderful world of dynamic programming with ColdFusion (CFML). This book aims to jump-start developers into the ColdFusion (CFML) programming language from a modern perspective and focus on best practices, object orientation, and tooling. ColdFusion is not the same as it was 20 years ago; yes, it's more than 20 years old! It's dynamic, vibrant, modern, fluent, and functional! Let's begin our adventure into the world of MODERN ColdFusion (CFML). circle-info This book is inspired by the original [Ruby in 100 minutesarrow-up-right](http://tutorials.jumpstartlab.com/projects/ruby_in_100_minutes.html) , [Mike Henke's work on CFML in 100 minutesarrow-up-right](https://github.com/mhenke/CFML-in-100-minutes/wiki) , and [Learn CF in a week seriesarrow-up-right](http://www.learncfinaweek.com/) . [hashtag](https://modern-cfml.ortusbooks.com/intro/intro#coldfusion-vs.-cfml) ColdFusion vs. CFML ------------------------------------------------------------------------------------------------------ Let's get this ambiguity out of the way. **ColdFusion** is the server product, and **CFML** is the language, short for **C**old**F**usion **M**arkup **L**anguage. In turn, ColdFusion is actually the platform or framework in which CFML scripts are executed. It is similar to the relationship between HTML and a web browser like IE, Firefox, or Safari. More information at: [http://www.differencebetween.net/technology/communication-technology/difference-between-cfml-and-coldfusion/arrow-up-right](http://www.differencebetween.net/technology/communication-technology/difference-between-cfml-and-coldfusion/) CFML will execute in a ColdFusion engine. [PreviousIntroductionchevron-left](https://modern-cfml.ortusbooks.com/) [NextAuthorchevron-right](https://modern-cfml.ortusbooks.com/intro/intro/author) Last updated 1 year ago Was this helpful? --- # Author | Learn Modern ColdFusion in 100 Minutes [hashtag](https://modern-cfml.ortusbooks.com/intro/intro/author#luis-fernando-majano-lainez) Luis Fernando Majano Lainez ----------------------------------------------------------------------------------------------------------------------------- ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-LA-UVvdhvPQ4iTxu_CD%252Fuploads%252FrQfbp6YSbF0LOQC2QpzO%252Flm_IMG_0402_1024.jpeg%3Falt%3Dmedia%26token%3D2921696a-874a-40bb-b92a-fd3f4a962a78&width=768&dpr=3&quality=100&sign=bf0c5509&sv=2) Luis Majano is a Computer Engineer who has been developing and designing software systems since 2000. He was born in [San Salvador, El Salvadorarrow-up-right](http://en.wikipedia.org/wiki/El_Salvador) , in the late 70s, during a period of economic instability and civil war. He lived in El Salvador until 1995 and then moved to Miami, Florida, where he completed his Bachelor of Science in Computer Engineering at [Florida International Universityarrow-up-right](http://fiu.edu/) . He is the CEO of [Ortus Solutionsarrow-up-right](http://www.ortussolutions.com/) , a consulting firm specializing in web development, ColdFusion (CFML), Java development, and open-source professional services. He is the creator of ColdBox, ContentBox, CommandBox, WireBox, TestBox, LogBox, and anything "Box," and he contributes to over 250 open-source projects. He has a passion for learning and mentoring developers so they can succeed with sustainable software practices and the usage and development of open-source software. You can read his blog at [www.luismajano.comarrow-up-right](http://www.luismajano.com/) Luis is passionate about Jesus, tennis, golf, volleyball, and anything electronic. Random Author Facts: * He played volleyball in the Salvadorean National Team at the tender age of 17 * His favorite books are the Lord of the Rings and The Hobbit (Geek!) * His first ever computer was a Texas Instruments TI-86 that his parents gave him in 1986. After some time digesting his very first BASIC book, he had written his own tic-tac-toe game at the age of 9. (Extra geek!) * He has a geek love for circuits, microcontrollers, and overall embedded systems. * He has, of late (during old age), become a fan of organic gardening. > Keep Jesus number one in your life and in your heart. I did and it changed my life from desolation, defeat and failure to an abundant life full of love, thankfulness, joy and overwhelming peace. As this world breathes failure and fear upon any life, Jesus brings power, love and a sound mind to everybody! > > "Trust in the LORD with all your heart, and do not lean on your own understanding." Proverbs 3:5 [PreviousWelcomechevron-left](https://modern-cfml.ortusbooks.com/intro/intro) [NextAbout This Bookchevron-right](https://modern-cfml.ortusbooks.com/intro/intro/about-this-book) Last updated 2 years ago Was this helpful? --- # What is ColdFusion (CFML) | Learn Modern ColdFusion in 100 Minutes ColdFusion Markup Language is a dynamic web programming language, which is especially suited for new developers as it was written to make a programmer's job easy and not care if the computer's job is hard. CFMLs primary goal is to be a rapid application development scripting language and middleware. It integrates with many technologies to provide an out-of-the-box language that makes things **easy**. This brief introduction will look at key language features you need to get started. [hashtag](https://modern-cfml.ortusbooks.com/intro/history#going-deep) Going Deep -------------------------------------------------------------------------------------- ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LA-UbMqUYOVVZvx_rxu%252F-LA-UpTKym2XHaKe_L6x%252Flucee.png%3Fgeneration%3D1523647995236227%26alt%3Dmedia&width=768&dpr=3&quality=100&sign=18392ab0&sv=2) Lucee Server ColdFusion (CFML) is an interpreted and [dynamic ECMA Script like languagearrow-up-right](https://en.wikipedia.org/wiki/Dynamic_programming_language) that compiles to [Java Bytecodearrow-up-right](https://en.wikipedia.org/wiki/Java_bytecode) directly, thus running in the Java Virtual Machine (JVM) and in almost every operating system. Implementations of the language are mostly done by two parties: [Adobe ColdFusionarrow-up-right](http://www.adobe.com/products/coldfusion-family.html) (Commercial) and [Lucee Serverarrow-up-right](http://lucee.org/) (Free & Open Source), and they saw their beginnings in 1995. It is a mature and modern language and development platform. You can discover all the versions here: [https://cfdocs.org/coldfusion-versionsarrow-up-right](https://cfdocs.org/coldfusion-versions) ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LA-UbMqUYOVVZvx_rxu%252F-LA-UpTUVJSCwTP4h35D%252Facf.png%3Fgeneration%3D1523647996019452%26alt%3Dmedia&width=768&dpr=3&quality=100&sign=65ab6f95&sv=2) Adobe ColdFusion [hashtag](https://modern-cfml.ortusbooks.com/intro/history#developing-with-cfml) Developing with CFML ---------------------------------------------------------------------------------------------------------- All examples in this book will leverage CommandBox as the de-facto standard for ColdFusion (CFML) development. [CommandBoxarrow-up-right](https://www.ortussolutions.com/products/commandbox) is a standalone, native tool for Windows, Mac, and Linux that will provide you with a Command Line Interface (CLI) for developer productivity, tool interaction, package management, REPL, embedded ColdFusion/Java server, application scaffolding, and some sweet ASCII art. [hashtag](https://modern-cfml.ortusbooks.com/intro/history#docs-reference) Docs Reference ---------------------------------------------------------------------------------------------- The best way to discover the CFML language's methods, tags, and functionality is to leverage [cfdocs.orgarrow-up-right](https://cfdocs.org/) . Make sure you open it and bookmark it. [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fcfdocs.org%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=12889214&sv=2)CFML DocumentationCF Docschevron-right](https://cfdocs.org/) [hashtag](https://modern-cfml.ortusbooks.com/intro/history#ide-editors) IDE - Editors ------------------------------------------------------------------------------------------ There are many flavors of IDE's but here are our recommendations, which all support CFML * [Visual Studio Codearrow-up-right](https://code.visualstudio.com/) _(Our Preference for both CFML and Java)_ * Open-source packages * Adobe Package * [Sublimearrow-up-right](https://www.sublimetext.com/3) * [Adobe ColdFusion Builderarrow-up-right](http://www.adobe.com/products/coldfusion-builder.html) * Deprecated in favor of VSCode by Adobe * [IntelliJarrow-up-right](https://www.jetbrains.com/idea/) ### [hashtag](https://modern-cfml.ortusbooks.com/intro/history#sublime-packages) **Sublime Packages** Use [package controlarrow-up-right](https://packagecontrol.io/) in sublime to install the following packages which we use in our developer setups: * ColdBox Sublime * CommandBox Sublime * Alignment * CFML * CFMLDocPlugin * ColdFusion Docs Launcher * DockBlockr * Emmet * Enhanced HTML and CFML * SideBarEnhancements * Terminal circle-check You can find the sublime package manager link here: [https://packagecontrol.io/arrow-up-right](https://packagecontrol.io/) ### [hashtag](https://modern-cfml.ortusbooks.com/intro/history#vscode-packages) **VSCode Packages** * Kamasamk CFML - [https://marketplace.visualstudio.com/items?itemName=KamasamaK.vscode-cfmlarrow-up-right](https://marketplace.visualstudio.com/items?itemName=KamasamaK.vscode-cfml) * ColdBox Support - [https://marketplace.visualstudio.com/items?itemName=ortus-solutions.vscode-coldboxarrow-up-right](https://marketplace.visualstudio.com/items?itemName=ortus-solutions.vscode-coldbox) * CommandBox Support - [https://marketplace.visualstudio.com/items?itemName=ortus-solutions.vscode-commandboxarrow-up-right](https://marketplace.visualstudio.com/items?itemName=ortus-solutions.vscode-commandbox) * TestBox Support - [https://marketplace.visualstudio.com/items?itemName=ortus-solutions.vscode-testboxarrow-up-right](https://marketplace.visualstudio.com/items?itemName=ortus-solutions.vscode-testbox) * Adobe ColdFusion Builder - [https://marketplace.visualstudio.com/items?itemName=com-adobe-coldfusion.adobe-cfml-lsparrow-up-right](https://marketplace.visualstudio.com/items?itemName=com-adobe-coldfusion.adobe-cfml-lsp) * CFLSP - ColdFusion syntax error checker : [https://marketplace.visualstudio.com/items?itemName=DavidRogers.cflsparrow-up-right](https://marketplace.visualstudio.com/items?itemName=DavidRogers.cflsp) * CFLint - Linting Support - [https://marketplace.visualstudio.com/items?itemName=KamasamaK.vscode-cflintarrow-up-right](https://marketplace.visualstudio.com/items?itemName=KamasamaK.vscode-cflint) * LuceeDebug - A barebones debugger - [https://marketplace.visualstudio.com/items?itemName=DavidRogers.luceedebugarrow-up-right](https://marketplace.visualstudio.com/items?itemName=DavidRogers.luceedebug) * Align * Auto Alignment * Auto CLose Tag * Auto Rename Tag * AutoFileName * Better Comments * CFGoto * Code Outline * Document This * DotENV * EditorConfig * ESLint * File Utils * Git Graph * Hibernate Log Analyser circle-info You can find the VSCode marketplace link here: [https://marketplace.visualstudio.com/VSCodearrow-up-right](https://marketplace.visualstudio.com/VSCode) [PreviousAbout This Bookchevron-left](https://modern-cfml.ortusbooks.com/intro/intro/about-this-book) [NextCommandBox CLIchevron-right](https://modern-cfml.ortusbooks.com/intro/intro-to-commandbox) Last updated 3 years ago Was this helpful? --- # CommandBox CLI | Learn Modern ColdFusion in 100 Minutes ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-LA-UVvdhvPQ4iTxu_CD%252Fuploads%252Fgit-blob-aad0e9ffea7b4ac9fc446b4fe95f78275997263b%252Fcommandboxlogo.png%3Falt%3Dmedia&width=768&dpr=3&quality=100&sign=24fdc3e2&sv=2) CommandBox CLI CommandBox is an amalgamation of many different tools and borrows concepts from NPM, Grunt/Gulp, Maven, ANT, Node, and much more. Features include: * True Command Line for ColdFusion (CFML) * Operation System integration for executing commands * Ability to create and execute commands built using ColdFusion (CFML) * ForgeBox integration for cloud package management and installations * ColdBox Platform, TestBox, and ContentBox CMS Integrations * Integrated servlet server with rewrite capabilities * Ability to create command recipes and execution * REPL (Read-Evaluate-Print-Loop) console for immediate ColdFusion (CFML) interaction * Ability to interact with users via CLI and create workflows and installers * Ability to execute workflows and tasks * Built-in Help system [hashtag](https://modern-cfml.ortusbooks.com/intro/intro-to-commandbox#installation) Installation ------------------------------------------------------------------------------------------------------ CommandBox is a Java-based executable that will run on the most recent desktop operating systems (Linux, Mac OS X, Windows). Since it is a command line tool that uses a shell interface, it does not require an operating system using a GUI. Below is a simple guideline to get you up and running, but an [in-depth guidearrow-up-right](https://commandbox.ortusbooks.com/getting-started-guide) can be found here: [https://commandbox.ortusbooks.com/setuparrow-up-right](https://commandbox.ortusbooks.com/setup) ### [hashtag](https://modern-cfml.ortusbooks.com/intro/intro-to-commandbox#requirements) Requirements * 256MB+ RAM * 250MB+ free hard drive space * Multi-core CPU recommended * JRE/JDK 8+ ### [hashtag](https://modern-cfml.ortusbooks.com/intro/intro-to-commandbox#download) Download If you already have a Java JRE installed level 8 or higher (and set in your environment variables), you can [downloadarrow-up-right](http://www.ortussolutions.com/products/commandbox#download) the non-JRE version for your Operating System. If you don't have a JRE installed or aren't sure, we recommend downloading the version with a JRE included. Regardless of where you place the **box** binary, the first time you execute it, a `.CommandBox` folder will be created in your user's home directory, and CommandBox will be extracted into that location. If you delete this directory, it will be replaced the next time the CommandBox executable is run. ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-LA-UVvdhvPQ4iTxu_CD%252Fuploads%252FEZ1jaF5IkrQfPSjNCr6s%252Fimage.png%3Falt%3Dmedia%26token%3Db50ff7f3-cd7c-40df-bcde-802084649cb2&width=768&dpr=3&quality=100&sign=2432ba24&sv=2) Box Shell #### [hashtag](https://modern-cfml.ortusbooks.com/intro/intro-to-commandbox#windows) Windows Unzip the executable **box.exe** and double-click on it to open the shell. When you are finished running commands, you can close the window or type `exit`. circle-info **Hint:** You can make the `box.exe` available in any Windows terminal by adding its location to the `PATH` system environment variable. See [http://www.computerhope.com/issues/ch000549.htmarrow-up-right](http://www.computerhope.com/issues/ch000549.htm) #### [hashtag](https://modern-cfml.ortusbooks.com/intro/intro-to-commandbox#homebrew-mac) Homebrew (Mac) [Homebrewarrow-up-right](http://brew.sh/) is a great Mac package manager; it can easily install and keep your CommandBox installation up to date (even binary releases); just run the following for stable releases: Copy brew install commandbox To stay with current bleeding edge releases, use the following: Copy brew tap ortus-solutions/boxtap brew tap-pin ortus-solutions/boxtap brew install --devel commandbox Then run the `box` binary to begin the one-time unpacking process. Versions will be installed in `/usr/local/Cellar/commandbox`. To switch between versions, use `brew switch commandbox [version number]` #### [hashtag](https://modern-cfml.ortusbooks.com/intro/intro-to-commandbox#manual-linux-mac) Manual Linux/Mac Unzip the binary **box** and double-click on it to open the shell terminal. When you are finished running commands, you can close the window or type `exit`. circle-info **Hint** You can place the binary in your `/usr/bin` or `/usr/local/bin` directory so it can be available system-wide via the box command in any terminal window. #### [hashtag](https://modern-cfml.ortusbooks.com/intro/intro-to-commandbox#linux-apt-get) Linux apt-get Run the following commands to add the Ortus signing key, register our Debian repo, and install CommandBox. Copy curl -fsSl https://downloads.ortussolutions.com/debs/gpg | sudo apt-key add - echo "deb https://downloads.ortussolutions.com/debs/noarch /" | sudo tee -a /etc/apt/sources.list.d/commandbox.list sudo apt-get update && sudo apt-get install commandbox #### [hashtag](https://modern-cfml.ortusbooks.com/intro/intro-to-commandbox#linux-yum) Linux yum Add the following to: `/etc/yum.repos.d/commandbox.repo` Copy [CommandBox] name=CommandBox $releasever - $basearch failovermethod=priority baseurl=http://downloads.ortussolutions.com/RPMS/noarch enabled=1 metadata_expire=7d gpgcheck=0 Then run a `sudo yum install commandbox` and be up and running [hashtag](https://modern-cfml.ortusbooks.com/intro/intro-to-commandbox#getting-started) Getting Started ------------------------------------------------------------------------------------------------------------ We have created a small [getting started guidearrow-up-right](https://commandbox.ortusbooks.com/getting-started-guide) that will give you enough skills to move forward with any CommandBox development. You can find it here: [https://commandbox.ortusbooks.com/content/getting\_started\_guide.htmlarrow-up-right](https://commandbox.ortusbooks.com/getting-started-guide) [PreviousWhat is ColdFusion (CFML)chevron-left](https://modern-cfml.ortusbooks.com/intro/history) [NextInstructions & Interpreterschevron-right](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters) Last updated 3 years ago Was this helpful? --- # Instructions & Interpreters | Learn Modern ColdFusion in 100 Minutes [hashtag](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters#dynamic-language) Dynamic Language ------------------------------------------------------------------------------------------------------------------------ CFML is a **compiled** programming language that can’t run on your processor directly; it has to be fed into a middleman called the Java Virtual Machine in the form of [Java Bytecodearrow-up-right](https://en.wikipedia.org/wiki/Java_bytecode) . It is also a **dynamic language (**[**https://en.wikipedia.org/wiki/Dynamic\_programming\_language**arrow-up-right](https://en.wikipedia.org/wiki/Dynamic_programming_language) **)**, meaning you do not have the **typed** restrictions a compile-time language like Java has. This means you have greater flexibility as the engine **infers** your types. It allows you to do runtime manipulations like method injections, removals, metadata programming, etc., that a typical typed language would not allow. It also allows us to not be in the dreaded compile, build, deploy cycle since the CFML scripts will be evaluated, compiled, and executed all at runtime. No need for re-deploying or annoying restarts. ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-LA-UVvdhvPQ4iTxu_CD%252Fuploads%252F2f65y9pNCcbsunFe5tG5%252FCFML-JavaBytecode.png%3Falt%3Dmedia%26token%3D08daa837-8d5e-4a41-be45-5ec2ea0af865&width=768&dpr=3&quality=100&sign=bb75d71&sv=2) ### [hashtag](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters#runtime-exceptions) Runtime Exceptions However, with much power comes greater responsibility. There is a lot more potential for runtime exceptions because these exceptions cannot be caught by a compiler at compilation time, as compilation occurs simultaneously with execution. Thus, unit and integration testing become a real asset when building applications under a dynamic language. Wouldn't you know it? We also have a great tool for test-driven and behavior-driven development for ColdFusion: [**TestBox**arrow-up-right](https://testbox.ortusbooks.com/) ([https://testbox.ortusbooks.com/arrow-up-right](https://testbox.ortusbooks.com/) ) ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LKm6qaYURu6DNLO8LAI%252F-LKm9JkHwOlWWkqJlPfd%252Ftestbox-logo.png%3Falt%3Dmedia%26token%3D12c7973d-f932-4c15-9cbf-da07f148458b&width=768&dpr=3&quality=100&sign=c020fa8a&sv=2) TestBox Testing Framework circle-info **TestBox** is a next-generation testing framework for ColdFusion (CFML) that is based on BDD (Behavior Driven Development) for providing a clean, obvious syntax for writing tests. It contains a testing framework, runner, assertions, and expectations library and ships with a mocking and stubbing library. ### [hashtag](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters#code-portability) Code Portability The ColdFusion engine will convert your CFML markup into byte code and feed it into the Virtual Machine (VM) to execute it. The benefit of this approach is that you can write ColdFusion code once and, typically, execute it on many different operating systems and hardware platforms. You can run any CFML script in any Adobe or Lucee server or in the command line with CommandBox. circle-info Running via CommandBox in the command line will leverage the Lucee 5x CFML engine by default. Still, it can be configured easily to run Adobe Coldfusion (ACF), or different versions of either Lucee or ACF. [hashtag](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters#java-integration) Java Integration ------------------------------------------------------------------------------------------------------------------------ CFML is a dynamic language for the JVM. Thus it runs in a full JDK/JRE context. It also provides you with hooks into the Java virtual machine. Meaning you can create and use Java objects natively in CFML. You can even create dynamic proxies and implement Java interfaces natively. Almost **Any** Java library or program can be class loaded and executed in CFML. For further reading, check out the [Java Integration Guidearrow-up-right](https://cfdocs.org/java) : [https://cfdocs.org/javaarrow-up-right](https://cfdocs.org/java) Copy currentFile = createObject( "java", "java.io.File" ).init( getCurrentTemplatePath() ); writeOutput( currentFile.lastModified() ); createDynamicProxy( new cbproxies.models.Consumer( arguments.consumer ), [ "java.util.function.Consumer" ] ) circle-info Adobe and Lucee have the added benefit of being written modularly using [OSGIarrow-up-right](https://www.osgi.org/developer/architecture/) . This will allow you to build your own Java OSGI bundles and deploy them as well. [hashtag](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters#running-cfml-from-the-command-line) Running CFML from the Command Line ------------------------------------------------------------------------------------------------------------------------------------------------------------ This is a durable way to write CFML code because you save your instructions into a file. That file can then be backed up, transferred, added to source control, etc. ### [hashtag](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters#an-example-cfml-file) An Example CFML File We might create a file named `hello.cfm` like this: Copy Hello from CFML Land! Then we could run the program like this `box hello.cfm` and get the following result: Copy Hello from CFML Land! circle-exclamation When you run `box hello.cfm` you’re actually loading the CFML instruction set engine (Lucee) and executing the code. Please note there is **NO** web server here. It is a pure command-line execution. [hashtag](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters#commandbox-repl) CommandBox REPL ---------------------------------------------------------------------------------------------------------------------- CommandBox sports a CFML **R**ead **E**val **P**rint **L**oop interface or most commonly known as **REPL**. The REPL is like a programming calculator, input in, output out. It will execute CFML instructions and give you feedback on syntax and results. To start a REPL, we must go into the CommandBox shell by typing just `box` or opening the `box` binary. Once in the CommandBox prompt, type `repl` and you will be placed in REPL mode: ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LA-UbMqUYOVVZvx_rxu%252F-LA-Uqgy8av2UqgIfYcn%252Frepl.png%3Fgeneration%3D1523648000326176%26alt%3Dmedia&width=768&dpr=3&quality=100&sign=3826b5a3&sv=2) CommandBox Please note that the REPL in CommandBox opens in **script** mode, not **tag** mode. This means that we must type in instructions that adhere to the ColdFusion scripting or ECMA script-like syntax instead of the tag-based syntax. We will discover more about syntax in the next chapter. For now, let's type the equivalent in Script syntax: Copy writeOutput( "Hello from CFML Land!" ) ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LA-UbMqUYOVVZvx_rxu%252F-LA-UqhLCOAt5OhVRzJ4%252Frepl-hello.png%3Fgeneration%3D1523648000309815%26alt%3Dmedia&width=768&dpr=3&quality=100&sign=1d8b66fd&sv=2) CommandBox Boom! We get a magical hello from the CommandBox REPL. circle-check **Tip**: Our REPL supports not only one-line commands but also multi-line commands. Go ahead, try it! Copy if( true ){ writeoutput( "hello" ) } echo( "hello" ) ### [hashtag](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters#producing-output) Producing Output In this book, we will primarily be using the REPL or CommandBox for execution. We will use several functions to produce output during our exercises and code examples. Here is a list of what we will use to produce output to either the console, the output stream, or a log file. Function Lucee Adobe Description `echo()` check While [writeOutputarrow-up-right](https://cfdocs.org/writeoutput) writes to the page-output stream, this function writes to the main response buffer. [https://cfdocs.org/echoarrow-up-right](https://cfdocs.org/echo) `systemOutput()` check Writes the given object to the output stream [https://cfdocs.org/systemoutputarrow-up-right](https://cfdocs.org/systemoutput) `writeOutput()` check check Appends text to the page-output stream. [https://cfdocs.org/writeoutputarrow-up-right](https://cfdocs.org/writeoutput) `writeDump()` check check Outputs the elements, variables, and values of most CFML objects. Useful for debugging. You can display the contents of simple and complex variables, objects, components, user-defined functions, and other elements. [https://cfdocs.org/writedumparrow-up-right](https://cfdocs.org/writedump) `writeLog()` check check Writes a message to a [logarrow-up-right](https://cfdocs.org/log) file. [https://cfdocs.org/writelogarrow-up-right](https://cfdocs.org/writelog) circle-check `writeDump()` is helpful in the console to visualize complex objects `writedump( var=variable, output="console" ) You can also pass complex objects to` systemOuput() `as well.` [PreviousCommandBox CLIchevron-left](https://modern-cfml.ortusbooks.com/intro/intro-to-commandbox) [NextSyntaxchevron-right](https://modern-cfml.ortusbooks.com/cfml-language/syntax) Last updated 3 years ago Was this helpful? --- # Comments | Learn Modern ColdFusion in 100 Minutes Comments are necessary and essential for any programming language. CFML is no different with helping you add code comments in both script and tag syntax. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/comments#tag-comments) Tag Comments --------------------------------------------------------------------------------------------------- You can use the `` Syntax to comment within a CFML template (`.cfm`). This is very similar to HTML comments but adding an extra `-` to demarcate it as a CFML comment. Copy HTML Comment ColdFusion Comment [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/comments#script-comments) Script Comments --------------------------------------------------------------------------------------------------------- If you are within a CFC or in a `` block you can use an alternate style for comments. You can leverage `//` for single line comments and the following for multi-line comments: Copy /** * Multi-line Javadoc style comment * * @COLDBOX_CONFIG_FILE The override location of the config file * @COLDBOX_APP_ROOT_PATH The location of the app on disk * @COLDBOX_APP_KEY The key used in application scope for this application * @COLDBOX_APP_MAPPING The application mapping override, only used for Flex/SOAP apps, this is auto-calculated * @COLDBOX_FAIL_FAST By default if an app is reiniting and a request hits it, we will fail fast with a message. This can be a boolean indicator or a closure. */ /* Multi Line Comments are great! */ // Single line comment [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/comments#script-javadoc-style-comments) Script "Javadoc" style comments --------------------------------------------------------------------------------------------------------------------------------------- A multi-line block can affect the metadata of a `component` or `function` if the opening line contains 2 asterisks. Also, for readability, some people will start each line of the comment with an asterisk. The CF engines will parse out those starting asterisks and they will not appear in the component or the function metadata. Copy /** * This is the hint for the function * * @param1 This is the hint for the param */ function myFunc( string param1 ){ } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/comments#cfcdoc-style-comments) CFCDoc Style Comments --------------------------------------------------------------------------------------------------------------------- In the CFML world, you can write [JavaDocarrow-up-right](http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html) comments in what we call **CFCDoc** comments. We leverage the [DocBoxarrow-up-right](https://github.com/Ortus-Solutions/DocBox) library to generate documentation according to object metadata and comments. Please check out the [annotating your code arrow-up-right](https://docbox.ortusbooks.com/getting-started/annotating-your-code) section in the DocBox documentation to get a feel for how to document your code: [https://docbox.ortusbooks.com/getting-started/annotating-your-codearrow-up-right](https://docbox.ortusbooks.com/getting-started/annotating-your-code) MyAwesome.cfc Copy /** * This is my component * * @author Luis Majano */ component extends="Base" implements="IHello" singleton{ /** * The Settings */ property name="settings"; /** * Constructor * * @wirebox The Injector * @wirebox.inject wirebox * @vars The vars I need * @vars.generic Array * * @return MyComponent * @throws SomethingException */ function init( required wirebox, required vars ){ variables.wirebox = arguments.wirebox; return this; } } [![Logo](https://docbox.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1073404360-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fspaces%252F-MO7676VkvjpkgbE8J5a%252Favatar-1607527844506.png%3Fgeneration%3D1607527844740047%26alt%3Dmedia&width=48&height=48&sign=9da0d890&sv=2)Introduction | DocBoxdocbox.ortusbooks.comchevron-right](https://docbox.ortusbooks.com/) Read about DocBox You can see some examples of advanced CFC documentation here: [https://apidocs.ortussolutions.com/coldbox/current/arrow-up-right](https://apidocs.ortussolutions.com/coldbox/current/) circle-check **Tip**: VSCode has some great plugins for generating this type of documentation on your CFCs. We recommend the following extensions: * **Align** - Helps align everything * **AutoCloseTag** - Helps close comment and well all tags * **DocumentThis** - Automatically generates detailed JSDoc, CFCDoc comments in TypeScript and JavaScript files. [PreviousSyntaxchevron-left](https://modern-cfml.ortusbooks.com/cfml-language/syntax) [NextVariableschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/variables) Last updated 3 years ago Was this helpful? --- # About This Book | Learn Modern ColdFusion in 100 Minutes The source code for this book is hosted on GitHub: [https://github.com/ortus-docs/Modern-ColdFusion-CFML-In-100-Minutesarrow-up-right](https://github.com/ortus-docs/Modern-ColdFusion-CFML-In-100-Minutes) . You can freely contribute to it and submit pull requests. The contents of this book are copyrighted by [Ortus Solutions, Corparrow-up-right](http://www.ortussolutions.com/) and cannot be altered or reproduced without the author's consent. All content is provided _"As-Is"_ and can be freely distributed.‌ * The majority of code examples in this book are done in `cfscript`. * The majority of code generation and running of examples are done via **CommandBox**: The ColdFusion (CFML) CLI, Package Manager, REPL - [https://www.ortussolutions.com/products/commandboxarrow-up-right](https://www.ortussolutions.com/products/commandbox) ​ [hashtag](https://modern-cfml.ortusbooks.com/intro/intro/about-this-book#external-trademarks-and-copyrights) ‌External Trademarks & Copyrights‌ ---------------------------------------------------------------------------------------------------------------------------------------------------- Flash, Flex, ColdFusion, and Adobe are registered trademarks and copyrights of Adobe Systems [hashtag](https://modern-cfml.ortusbooks.com/intro/intro/about-this-book#notice-of-liability) Notice of Liability ---------------------------------------------------------------------------------------------------------------------- ‌The information in this book is distributed **as is**, without warranty. The author and Ortus Solutions, Corp shall not have any liability to any person or entity concerning loss or damage caused or alleged to be caused directly or indirectly by the content of this training book, software, and resources described in it. [hashtag](https://modern-cfml.ortusbooks.com/intro/intro/about-this-book#charitable-proceeds) Charitable Proceeds‌ ----------------------------------------------------------------------------------------------------------------------- 10% of the proceeds of this book will go to charity to support orphaned kids in El Salvador - [https://www.harvesting.org/arrow-up-right](https://www.harvesting.org/) . So please donate and purchase the printed version of this book; every book sold can help a child for almost two months.‌ [hashtag](https://modern-cfml.ortusbooks.com/intro/intro/about-this-book#shalom-childrens-home) Shalom Children's Home --------------------------------------------------------------------------------------------------------------------------- ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F-LA-UVvdhvPQ4iTxu_CD%252Fuploads%252FKlyKfniPe2HdVECTxyhJ%252Fimage.png%3Falt%3Dmedia%26token%3Df50c7854-a58f-4cf7-b3bf-3cb4db363d65&width=768&dpr=3&quality=100&sign=2884d790&sv=2) Shalom Children's Party! The Shalom Children's Home ([https://www.harvesting.org/arrow-up-right](https://www.harvesting.org/) ) is one of the ministries that are dear to our hearts located in El Salvador. During the 12-year civil war that ended in 1990, many children were left orphaned or abandoned by parents who fled El Salvador. The Benners saw the need to help these children and received 13 children in 1982. Little by little, more children came on their own, churches and the government brought children to them for care, and the Shalom Children’s Home was founded. Shalom now cares for over 80 children in El Salvador, from newborns to 18 years old. They receive shelter, clothing, food, medical care, education, and life skills training in a Christian environment. The home is supported by a child sponsorship program.‌ We have supported Shalom since 2010; it is a place of blessings for many children in El Salvador who either have no families or have been abandoned. This is a good earth to seed and plant. ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fraw.githubusercontent.com%2Fortus-docs%2Flogbox-docs%2Fmaster%2Fimages%2Fshalom.jpg&width=768&dpr=3&quality=100&sign=16bd38fe&sv=2) Shalom Orphanage [PreviousAuthorchevron-left](https://modern-cfml.ortusbooks.com/intro/intro/author) [NextWhat is ColdFusion (CFML)chevron-right](https://modern-cfml.ortusbooks.com/intro/history) Last updated 2 years ago Was this helpful? --- # Strings | Learn Modern ColdFusion in 100 Minutes In CFML, strings are a type of variable that is used to store collections of letters and numbers. Usually defined within single or double quotes ( `'` or `"` ). Some simple strings would be `"hello"` or `"This sentence is a string!"`. Strings can be anything from `""`, the empty string, to long sets of text. The underlying type for a string in CFML is the Java [Stringarrow-up-right](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html) , which is immutable, meaning it can never change. Thus, a new string object is always created when concatenating strings together. This is a warning that if you do many string concatenations, you will have to use a Java data type to accelerate the concatenations ([String Buildersarrow-up-right](https://www.baeldung.com/java-string-builder-string-buffer) ). circle-info More on String Builders: [https://www.baeldung.com/java-string-builder-string-bufferarrow-up-right](https://www.baeldung.com/java-string-builder-string-buffer) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#character-extractions) Character Extractions -------------------------------------------------------------------------------------------------------------------- In Adobe 2021+ and Lucee server, you can reference characters in a string stream via their position in the string using array syntax: `varname[ position ]`. Please note that string and array positions in CFML start at 1 and not 0. Copy name = "luis"; writeoutput( name[ 1 ] ) => will produce l Adobe has taken this further, and you can use negative indices to get characters from the end backward: Copy name = "luis"; writeoutput( name[ -1 ] ) => will produce s [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#character-extractions-by-range) Character Extractions by Range -------------------------------------------------------------------------------------------------------------------------------------- Adobe 2018+ also supports extraction as ranges using the following array syntax: Copy array[ start:stop:step ] Which is extremely useful for doing character extractions in ranges Copy data = "Hello CFML. You Rock!"; writeOutput( data[ 1 ] ) // Returns H writeOutput( data[ -3 ] ) // Returns c writeOutput( data[ 4:10:2 ] ) // Returns l FL writeOutput( data[ 4:12 ] ) // Returns lo CFML writeOutput( data[ -10:-4:2]) // Returns o o [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#common-string-functions) Common String Functions ------------------------------------------------------------------------------------------------------------------------ You can find all the available string functions here: [https://cfdocs.org/string-functionsarrow-up-right](https://cfdocs.org/string-functions) . Below are some common ones that are handy to memorize: ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#len) Len Call `len()` on a string to get back the number of characters in the string. For instance `Len( "Hello ")` would give you back **6** (notice the trailing space is counted). You can also use member functions: `a.len()`. [https://cfdocs.org/lenarrow-up-right](https://cfdocs.org/len) Copy message = "Hola Luis" writeOutput( message.len() ) if( len( message ) ){ } ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#trim-ltrim-rtrim) Trim, LTrim, RTrim The`Trim` function removes leading and trailing spaces and controls characters from a string. You can also use the `ltrim()` to do left trimming and `rtrim()` to do right trimming. [https://cfdocs.org/trimarrow-up-right](https://cfdocs.org/trim) For instance, `Trim("Hello ")` would give you back `Hello` (notice the trailing space is removed). Combine this with `Len` for example `Len( Trim( "Hello ") )` and you would get back `5`. You can also use member functions: Copy a.trim().len() ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#replace-replacenocase-rereplace-rereplacenocase) Replace, ReplaceNoCase, REReplace, REReplaceNoCase The `Replace` instruction replaces occurrences of **substring1** in a string with **substring2**, in a specified scope. The search is case-sensitive and the scoped default is one. If you would like the searches to be case-insensitive just use the `noCase()` suffix. [https://cfdocs.org/replacearrow-up-right](https://cfdocs.org/replace) For instance, `Replace("Hello", "l", "")` would give you back **Helo** after replacing the _first occurrence of l_, or `Replace("Good Morning!", "o", "e", "All")` would give you **Geed Merning!** `REReplace(), REReplaceNoCase()` are the same functions but using regular expressions: Copy reReplace( "test 123!", "[^a-z0-9]", "", "ALL" ) reReplace( "123abc456", "[0-9]+([a-z]+)[0-9]+", "\1" ) ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#removechars) RemoveChars `RemoveChars` will remove characters from a string. For instance, `RemoveChars("hello bob", 2, 5)` would give you back **hbob**. [https://cfdocs.org/removecharsarrow-up-right](https://cfdocs.org/removechars) ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#mid) Mid The `mid` function extracts a substring from a string. For instance, I could call `Mid("Welcome to CFML Jumpstart", 4, 12)` and it would give you back: **come to CFML**. [https://cfdocs.org/midarrow-up-right](https://cfdocs.org/mid) Copy s = "20001122" writedump( mid( s, 5, 2 ) ) // You can also use character extraction writedump( s[ 5:6 ] ) ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#listtoarray) ListToArray Another great function is `listToArray()` which can take any string and convert it to an array according to a delimiter, empty fields, and even multi-character delimiters. The default delimiter is a comma `,`, but you can use any one or a combination of characters. [https://cfdocs.org/listtoarrayarrow-up-right](https://cfdocs.org/listtoarray) Copy a = "luis,majano,lucas,alexia,veronica"; myArray = a.listToArray(); // Multi-character delimiter list = "coldfusion,php,|test,java,|sql"; getArray = listToArray(list,",|",false,true); someJSON = serializeJSON(getArray); writeOutput(someJSON); [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#combining-strings) Combining Strings ------------------------------------------------------------------------------------------------------------ Combining and interpolating strings is part of any programming language and an integral part. We can do both by building upon some language [operators](https://modern-cfml.ortusbooks.com/cfml-language/operators) . If you have two or more strings, you can concatenate them by using the `&` operator: Copy name = "Luis"; a = "Hello " & name & " how are you today?"; You can also concatenate and assign using the `&=` operator. Please [check out the operators](https://modern-cfml.ortusbooks.com/cfml-language/operators#assignment-operators) section for more on string assignment operators. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#interpolating-strings) Interpolating Strings -------------------------------------------------------------------------------------------------------------------- Interpolating is where we stick a string within another string. In CFML, we use the `#` hashes to output a variable to the stream in context. This means we can interpolate into any string: Copy name = "luis"; welcome = "Good morning #name#, how are you today?"; writeoutput( welcome ); That's it! If you surround any **simple** variable with hashes, CFML will interpret the variable. Now try this with a complex variable and see what happens: Copy complex = [1,2,3]; welcome = "Good morning #complex#, how are you today (#now()#)?"; writeoutput( welcome ); circle-check Please note that anything between hashes is interpreted as an expression in CFML. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/strings#casting) Casting ---------------------------------------------------------------------------------------- CFML also will try to automatically infer and auto-cast strings for you. However, there is a built-in function called `toString()` which can be used to try to convert any value to a string. Copy s = { "a": "1", "b":"2" }; writeOutput( toString(s) ) writeOutput( s.toString() ) number = 42222.222 writedump( number.toString() ) [PreviousNull & Nothingnesschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/null-and-nothingness) [NextJSONchevron-right](https://modern-cfml.ortusbooks.com/cfml-language/json) Last updated 3 years ago Was this helpful? --- # Syntax | Learn Modern ColdFusion in 100 Minutes There are two ways to write CFML code: in **tags** or in **script** syntax. Modern CFML will dictate that your view or presentation layers will utilize the **tag** syntax in `cfm` files, and the model or business layers will all be done in **script** syntax in `cfc` files. (MVC comes later). There are no differences in functionality between them; it's pure syntax. * CFScript Syntax Guide - [https://cfdocs.org/scriptarrow-up-right](https://cfdocs.org/script) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#syntax-files) Syntax Files ------------------------------------------------------------------------------------------------- CFML includes a set of instructions you use on pages (`.cfm`) or components (classes -`cfc`). You will write one or more instructions in a file (`.cfm,.cfc`) then run the file through a CFML engine or Command Line Interpreter like CommandBox. * `cfm` - ColdFusion markup file, tag syntax is the default and used for views * `cfc` - The default is the ColdFusion Component file (Class or Object), script syntax. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#implicit-behavior) Implicit Behavior ----------------------------------------------------------------------------------------------------------- CFML also gives you a pre-set of defined [tagsarrow-up-right](https://cfdocs.org/tags) and [functionsarrow-up-right](https://cfdocs.org/functions) available to you in any file you write your code in. These tags and functions allow you to extend the typical language constructs with many modern capabilities, from database interaction to PDF generation. They are basically automatic imports. circle-check **Tip:** Please note that the CFML built-in functions are also **first-class functions** so that they can be passed around as arguments to other functions or closures or saved as variables. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#exploring-behavior) Exploring Behavior ------------------------------------------------------------------------------------------------------------- Three CFML instructions we will use in this section are `cfset`, `cfoutput`, and `cfdump`. * `cfset` is used to create a variable and assign it a value. * `cfoutput` displays a variable's value to the output stream. * `cfdump` is used to display the contents of simple and complex variables, objects, components, user-defined functions, and other elements to the output stream. We might have a file named _myprogram.cfm_ and _Sample.cfc_ like this: ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#tag-syntax) Tag Syntax myprogram.cfm Copy #s.hello()# ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#script-syntax) Script Syntax myprogram.cfm Copy s = new Sample(); writeOutput( s.hello() ); circle-check **Tip:** Please note that if you want to write in script in a tag-based file, you must use an opening and closing `` tag. Sample.cfc Copy component{ function hello(){ return "Hello, World!"; } } Please note that no types and not even any visibility scopes you might be used to are present. CFML can also infer variable types on more distinct variables like dates, booleans, or numbers. However, please note that you can fully leverage types if you like: Sample.cfc Copy component{ public string function hello(){ return "Hello, World!"; } } circle-check By default, the return type of every function and/or argument is **any**. Thus, it can be determined at runtime as a dynamic variable. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#semi-colons) Semi-Colons Please note that semi-colons are used to demarcate line endings in CFML `;`. However, the Lucee Server engine and Adobe ColdFusion 2018+ treat semi-colons as optional, while Adobe ColdFusion 2016 or below does not. Also, note the CommandBox REPL does NOT require semi-colons. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#tags-in-script) Tags In Script Lucee and Adobe ColdFusion 11+ will allow you to write your CFML tags in script syntax. You basically eliminate the starting `<` and ending `>` enclosures and create a block by using the `{` and `}` mustaches. Copy cfhttp(method="GET", charset="utf-8", url="https://www.google.com/", result="result") { cfhttpparam(name="q", type="formfield", value="cfml"); } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#polyglot-references) Polyglot References --------------------------------------------------------------------------------------------------------------- As we now live in a world of polyglot developers, we have added references below to other languages to see the differences and similarities between CFML and other major languages in usage today. Please note that this section is merely academic and to help developers from other language backgrounds to understand the intricacies of the ColdFusion (CFML) syntax. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#php-syntax) PHP Syntax myprogram.php Copy hello(); ?> Sample.php Copy ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#ruby-syntax) Ruby Syntax myprogram.rb Copy class Sample def hello "Hello, World!" end end s = Sample.new puts s.hello ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#java-syntax) Java Syntax MyProgram.java Copy public class MyProgram { public String hello(){ return "Hello, world!"; } public static void main(String[] args) { System.out.println( new MyProgram().hello() ); } } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/syntax#coding-standards) Coding Standards --------------------------------------------------------------------------------------------------------- At [Ortus Solutionsarrow-up-right](https://www.ortussolutions.com/) , we have developed a set of development standards for many languages. You can find our standards here: [https://github.com/Ortus-Solutions/coding-standardsarrow-up-right](https://github.com/Ortus-Solutions/coding-standards) . [PreviousInstructions & Interpreterschevron-left](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters) [NextCommentschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/comments) Last updated 2 years ago Was this helpful? --- # Variable Scopes | Learn Modern ColdFusion in 100 Minutes In the CFML language, there are many persistence and visibility scopes that exist for variables to be placed in. These are differentiated by context: in a CFC, in a function, tag, thread or in a template. All CFML scopes are implemented as structures or hash maps of key-value name pairs. The default scope for variable storage is called `variables`. Thus you can refer variables like this in either CFC or Template context: Copy a = "hello"; writeOutput( a ); or writeOutput( variables.a ); [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variable-scopes#persistence-scopes) Persistence Scopes ---------------------------------------------------------------------------------------------------------------------- Can be used in any context, used for persisting variables for a period of time. * `session` - stored in server RAM or external storages tracked by unique web visitor * `client` - stored in cookies, databases, or external storages (simple values only) * `application` - stored in server RAM or external storage tracked by the running ColdFusion application * `cookie` - stored in a visitor's browser * `server` - stored in server RAM for ANY application for that CFML instance * `request` - stored in RAM for a specific user request ONLY * `cgi` - read only scope provided by the servlet container and CFML * `form` - Variables submitted via HTTP posts * `URL` - Variables incoming via HTTP GET operations or the incoming URL [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variable-scopes#template-scopes-cfm) Template Scopes (CFM) -------------------------------------------------------------------------------------------------------------------------- * `variables` - The default or implicit scope to which all variables are assigned. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variable-scopes#component-scopes-cfc) Component Scopes (CFC) ---------------------------------------------------------------------------------------------------------------------------- * `variables` - Private scope, visible internally to the CFC only * `this` - Public scope, visible from the outside world * `static` - No need for a CFC instance; available as a CFC representation (Lucee only) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variable-scopes#function-scopes) Function Scopes ---------------------------------------------------------------------------------------------------------------- * `variables` - Has access to private variables within a Component or Page * `this` - Has access to public variables within a Component or Page * `local` - Function-scoped variables **only** exist within the function execution. Referred to as `var` scoping * `arguments` - Incoming variables to a function [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variable-scopes#tag-scopes) Tag Scopes ------------------------------------------------------------------------------------------------------ * `attributes` - Incoming tag attributes * `variables` - The default scope for variable assignments * `caller` - Used within a custom tag to set or read variables within the template that called it. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variable-scopes#thread-scopes) Thread Scopes ------------------------------------------------------------------------------------------------------------ * `attributes` - Passed variables via a thread * `thread` - A thread-specific scope that can be used for storage and retrieval * `local` - Variables local to the thread context [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variable-scopes#evaluating-unscoped-variables) **Evaluating Unscoped Variables** ------------------------------------------------------------------------------------------------------------------------------------------------ If you use a variable name **without** a scope prefix, ColdFusion checks the scopes in the following order to find the variable: 1. Local (function-local, UDFs, and CFCs only) 2. Arguments 3. Thread local (inside threads only) 4. Query (not a true scope; variables in query loops) 5. Thread 6. Variables 7. CGI 8. CFFILE 9. URL 10. Form 11. Cookie 12. Client triangle-exclamation **IMPORTANT**: Because ColdFusion must search for variables when you do not specify the scope, you can improve performance by specifying the scope for all variables. It can also help you avoid nasty lookups or unexpected results. [PreviousVariableschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/variables) [NextOperatorschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/operators) Last updated 2 years ago Was this helpful? --- # Operators | Learn Modern ColdFusion in 100 Minutes **Operators** are the foundation of **any** programming language. Operators are symbols that help a programmer to perform specific mathematical, structuring, destructuring, and logical computations on operands (variables or expressions). We can categorize the CFML operators into the following categories: 1. Arithmetic/Mathematical 2. Assignment 3. Logical 4. Comparison 5. Ternary 6. Elvis (Null Coalescing) 7. Function 8. Collections circle-info You will see that CFML does not have native [bitwisearrow-up-right](https://en.wikipedia.org/wiki/Bitwise_operation) operators, but it does implement bitwise operations via functions since functions can also be operators in CFML: `bitAnd, bitMaskClear, bitMaskRead, bitMaskSet, bitNot, bitOr, bitSHLN, bitSHRN, bitXOR` . You can find much more information here: [https://cfdocs.org/math%2Dfunctionsarrow-up-right](https://cfdocs.org/math-functions) circle-check For more information about bitwise operations, you can read more here: [https://en.wikipedia.org/wiki/Bitwise\_operationarrow-up-right](https://en.wikipedia.org/wiki/Bitwise_operation) triangle-exclamation CFML does not offer the capability to overload operators like other languages. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#operator-precedence) Operator Precedence ------------------------------------------------------------------------------------------------------------------ The order of precedence exists in CFML, just like in mathematics. You can also control the order of precedence by using the grouping operator `()` like in mathematics, the magical ordering parenthesis. Copy ^ *, / \ MOD +, - & EQ, NEQ, LT, LTE, GT, GTE, CONTAINS, DOES NOT CONTAIN, ==, !=, >, >=, <, <= NOT, ! AND, && OR, || XOR EQV IMP circle-check Remember that using parenthesis `(Grouping Operator)` is very important to denote precedence. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#arithmetic-operators) Arithmetic Operators -------------------------------------------------------------------------------------------------------------------- These operators are used to perform arithmetic/mathematical operations on operands. Operator Name Description `+` Add `a = 1 + 4` `-` Subtract `a = 4 - 2` `*` Multiply `a = 4 * b` `/` Divide `a = 4 / myVariable` `^` Exponentiate `a = 2^2 // 4` `%, MOD` Modulus / Remainder `5 % 2 = 1` or `5 mod 2` `\` Integer Divide `a = 7 \ 3` is 2. Please note it does not round off the integer. `++` Increment `a = b++` assign b to a and THEN increment b `a = ++b` increment b and THEN assign to a `--` Decrement `a = b--` assign b to a and THEN decrement b `a = --b` decrement b and THEN assign to a `-` Negate `a = -b` Negate the value of b `+` Positive `a = +b` Make the value of b a positive number `()` Grouping The grouping operator is used just like in mathematics, to give precedence to operations. `result = 3 * (2+3)` which is not the same as `result = 3 * 2 + 3` [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#assignment-operators) Assignment Operators -------------------------------------------------------------------------------------------------------------------- These operators are usually used for compound evaluations and assignments. Operator Name Description `=` Assignment `a = 5` The way to assign a value to a variable. You can also assign them to multiple variables by chaining them: `a=b=c=5` which is the same as saying: `a=5;b=5;c=5` `+=` Compound Add `a += b` is equivalent to `a = a + b` `-=` Compound Subtract `a -= b` is equivalent to `a = a - b` `*=` Compound Multiply `a *= b` is equivalent to `a = a * b` `/=` Compound Divide `a /= b` is equivalent to `a = a / b` `%=` Compound Modulus `a %= b` is equivalent to `a = a % b` `&=` Compound Concatenation A way to concatenate strings together `a = "hello "` `a &= "luis"` The result will be `hello luis` `&` Concatenation Concatenates two strings: `"Hola" & space & "Luis"` ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#undefined) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#logical-operators) Logical Operators -------------------------------------------------------------------------------------------------------------- Logical operators perform logic between values or values, usually denoting a `boolean` result. Operator Name Description `!,NOT` Negation `!true = false` or `a = not true` `&&,AND` And Returns true if both operands are true. `a = b && c` `||, OR` Or Returns true if either operand is true. `a = b` `XOR` Exclusive Or Returns true when either of the operands is true (one is true, and the other is false), but both are not true, and both are not false. `true XOR true = false` `true XOR false = true` `false XOR false = false` `EQV` Equivalence The exact opposite of an exclusive or. Meaning that it will return true when both operands are either true or false. `true EQV true = true` `true EQV false = false` `false EQV false = true` `IMP` Implication A implies B is equivalent to `if a then b`. A imp b is false ONLY if a is true and b is false; else, it returns true always. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#undefined-1) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#comparison-operators) Comparison Operators -------------------------------------------------------------------------------------------------------------------- Comparison operators are used when comparing two values, expressions, or variables. The return of a comparison is either `true` or `false`. Operator Name Description `eq,==` Equality True if `a eq b` or `a == b` `neq,` `!=,` `<>` Not Equal The opposite of equality: `a neq b, a != b, a <> b` `===` Identity Returns true if the operands are equal in value and in type. `2 === "2" // false` `2 === 2 // true` `!==` Negated Identity Same as the identity operator but negating the result. `gt,>` Greater than If the left operand is greater in value than the right operand `gte, >=` Greater than o equal If the left operand is greater than or equal in value than the right operand `lt, <` Less than If the left operand is less than in value than the right operand `lte, <=` Less than or equal If the left operand is less than or equal in value than the right operand `contains,ct` Contains Returns true if the left operand contains the right one. `'hello' contains 'lo'` `does not contain, nct` Negated contains Returns true if the left operand does NOT contain the right one. `'hello' does not contain 'pio'` [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#ternary-operator) Ternary Operator ------------------------------------------------------------------------------------------------------------ The ternary operator is a conditional operator that works just like an `if-then-else` statement but in shorthand syntax. It has three operands: Copy condition ? value1 if true : value2 if false The `condition` must evaluate to a `Boolean` value. If `true` then the `value1` will be used, or else `value2` will be used. You can combine this operator with parenthesis, Elvis operators, etc., to build rich expressions. Copy result = ( 10 > 0 ) ? true : false result = animal eq 'dog' ? 'bark' : 'not a dog' // More complex approach result = creditScore > 800 ? "Excellent" : ( creditScore > 700 ) ? "Good" : ( creditScore > 600 ) ? "Average" : "Bad" [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#elvis-operator-null-coalescing) Elvis Operator (Null Coalescing) ------------------------------------------------------------------------------------------------------------------------------------------ The Elvis operator is usually referred to as the [null coalescing operatorarrow-up-right](https://en.wikipedia.org/wiki/Null_coalescing_operator) . Its name comes from the symbol it represents, which looks like Elivs hair turned sideways: `?:`. If the expression to the operator's left is `null` , then the expression on the right will be evaluated as the result of the expression. Copy expression ?: defaultValueOrExpression Here is a simple example: Copy function process( result ){ writeOutput( result ?: "nothing passed" ) } process() // produces 'nothing passed' process( "hello" ) // produces 'hello' displayName = rc.name ?: 'Anonymous' event .getResponse() .setError( true ) .setData( rc.id ?: "" ) triangle-exclamation Please note that we have seen inconsistencies in both Adobe and Lucee engines regarding the implementation of this operator. I would avoid using it in Adobe 2018 as it is broken in several cases. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#function-operators) Function Operators ---------------------------------------------------------------------------------------------------------------- In CFML, functions can act as operators as well, as you can use the results of the function call as the operands. **Function arguments can also act as expressions, and you can even pass more functions into functions as arguments or even return functions from functions. Now that's a fun tongue twister.** Copy results = ucase( "this is text " ) & toString( 12 + 50 ) // I can also pass lambdas or anonymous functions as arguments results = listener( 2 * 3, (result) => result + 1 ) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#collections-operators) Collections Operators ---------------------------------------------------------------------------------------------------------------------- Many operators can work on collection objects like arrays, structs, and queries. So let's start investigating them. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#safe-navigation-operator) Safe Navigation Operator The [Safe Navigation operatorarrow-up-right](https://en.wikipedia.org/wiki/Safe_navigation_operator) avoids accessing a key in a structure or a value in an object that does `null` or doesn't exist. Typically when you have a reference to an object, you might need to verify that it exists before accessing the methods or properties of the object. To avoid this, the safe navigation operator will return `null` instead of throwing an exception, like so: Copy var user = userService.findById( id ) // If user is not found, then this will still work but no exception is thrown. echo( user?.getSalary() ) s = { name : "luis" } echo( s.name ) echo( s?.name ) ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#spread-operator) Spread Operator The spread operator allows an iterable object to expand and merge in certain declarations in code. These objects in CFML are mostly arrays and structures. This operator can quickly merge all or parts of an existing array or object into another array or object. This operator is used by leveraging three dots `...` in specific expressions. Copy // Spread var variableName = [ ...myArray ] // Traditional var variableName = [].append( myArray ) // Spread var mergedObject = { ...obj1, ...obj2 } // Traditional mergedObject.append( obj1 ).append( obj2 ) You can accomplish the result of the spread operator with the `append()` member function or traditional function in a very elegant and user-friendly syntax. It also allows you NOT to do chaining but inline expressions. The Spread syntax also allows an iterable such as an array expression or string, to be expanded in places where zero or more arguments (for function calls) are expected. Here are some examples to help you understand this operator: #### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#function-calls) Function Calls Copy numbers = [ 1, 2, 3 ] function sum( x, y, z ){ return x + y + z; } // Call the function using the spread operator results = sum( ...numbers ) // 6 // Ignore the others numbers = [ 1, 2, 3, 4, 5 ] results = sum( ...numbers ) // 6 #### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#array-definitions) Array Definitions Copy numbers = [ 1, 2, 3 ] myArray = [ 3, 4, ...numbers ] myArray2 = [ ...numbers ] myArray2 = [ ...numbers, 4, 66 ] #### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#struct-definitions) Struct Definitions Copy var mergedObject = { ...obj1, ...obj2 } user1 = { name : "luis", age: 15 } user2 = { name : "joe", location : "miami" } mergedUsers = { ...user1, ...user2 } // What will the output be? writeDump( mergedUsers ) // { name : "joe" , age : 15, location : "miami" } ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/operators#rest-operator) Rest Operator triangle-exclamation Only available in ACF 2021+ and for function arguments The Rest function operator is similar to Spread Operator but behaves oppositely. The spread syntax expands the iterable constructs into individual elements, and the Rest syntax collects and condenses them into a single construct, usually an array. Please note that this operator only works on function arguments as of now. Imagine I need to create a function that takes in an unlimited number of Identifiers, so I can return all items that have that ID: Copy function findById( ...ids ){ } findById( 1 ) // ids is a single value of 1 findById( 1, 23, 34, 456 ) // ids is an array of values You can also combine them in functions with other arguments: Copy function findById( entityName, ...ids ){ } findById( "User", 1 ) // ids is a single value of 1 findById( "Car", 1, 23, 34, 456 ) // ids is an array of values [PreviousVariable Scopeschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/variable-scopes) [NextNull & Nothingnesschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/null-and-nothingness) Last updated 5 months ago Was this helpful? --- # JSON | Learn Modern ColdFusion in 100 Minutes CFML supports native JSON support via several key functions and some member functions. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/json#serialize) Serialize ----------------------------------------------------------------------------------------- CFML gives us the `serializeJSON()` function to convert any piece of data to its JSON representation ([https://cfdocs.org/serializejsonarrow-up-right](https://cfdocs.org/serializejson) ) Copy serializeJson( var [, serializeQueryByColumns = false ] [, useSecureJSONPrefix = false ] [, useCustomSerializer = false ] ) Pass in any complex or simple variable to the `var` argument and JSON will be produced: Copy person = { name = "Luis Majano", company = "Ortus Solutions", year = 2006}; writeOutput( serializeJSON( person ) ); If you are in Lucee, you can even use the `toJSON()` member function: Copy person = { name = "Luis Majano", company = "Ortus Solutions", year = 2006}; writeOutput( person.toJSON() ); ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/json#key-casing) Key Casing By default CFML will convert the keys in a struct to uppercase in the result JSON document: Copy person = { name = "Luis Majano", company = "Ortus Solutions", year = 2006}; writeOutput( serializeJSON( person ) ); // Will become { "NAME" : "Luis Majano", "COMPANY" : "Ortus Solutions", "YEAR" : 2006 } If you want to preserve the key casing then wrap them in double/single quotes and define the case: Copy person = { 'Name' = "Luis Majano", 'company' = "Ortus Solutions", 'year' = 2006 }; // Will become { "Name" : "Luis Majano", "company" : "Ortus Solutions", "year" : 2006 } ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/json#possible-casting-issues) Possible Casting Issues Adobe ColdFusion may incorrectly serialize some strings if they can be automatically converted into other types, like numbers or booleans. One workaround is to use a CFC with [cfpropertyarrow-up-right](https://cfdocs.org/cfproperty) to specify types. Another workaround is to prepend `Chr(2)` to the value and it will be forced to a string, however, that is an unofficial/undocumented workaround. A more formal workaround is to call `setMetadata()` as a member function on a `struct` to force a type: Copy myStruct = { "zip"="00123" }; myStruct.setMetadata( { "zip": "string" } ); writeOutput( serializeJSON(myStruct) ); [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/json#deserialize) Deserialize --------------------------------------------------------------------------------------------- The inverse of serialization is deserialization ([https://cfdocs.org/deserializejsonarrow-up-right](https://cfdocs.org/deserializejson) ). CFML gives you the `deserializeJSON()` function that will take a JSON document and produce native CFML data structures for you. Copy deserializeJSON( json [, strictMapping = true ] [, useCustomSerializer = false ] ) Just pass a JSON document, and off we go with native structs/arrays/dates/strings and booleans. Copy if( isJson( mydata ) ){ return deserializeJSON( data ); } person = deserializeJSON( '{"company":"Ortus","name":"Mr OrtusMan"}' ); writeOutput( person.company ); This function can also be used as a member function in any string literal: Copy var deserializedData = myjsonString.deserializeJson(); var data = '[]'.deserializeJson(); [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/json#is-this-json) Is this JSON? ------------------------------------------------------------------------------------------------ CFML has a function to test if the incoming string is valid JSON ([https://cfdocs.org/isjsonarrow-up-right](https://cfdocs.org/isjson) ) or not: `isJSON()` Copy isJSON( "[ 1, 2, 3 ]" ) [PreviousStringschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/strings) [NextNumberschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/numbers) Last updated 3 years ago Was this helpful? --- # Functions | Learn Modern ColdFusion in 100 Minutes Functions are the way to interact with objects, with no functions we have no object-oriented behaviors, no [abstractionsarrow-up-right](https://en.wikipedia.org/wiki/Abstraction) and no [encapsulationarrow-up-right](https://en.wikipedia.org/wiki/Encapsulation_%28computer_programming%29) . Functions have an automatic return type of `any` which means it can return any type of variable back to a user and an automatic visibility scope of `public`. They also can take in _ANY_ amount of arguments, which don't even have to be defined in the function signature. WOWZA! Functions in CFML are also first-class object citizens. Meaning that each function can be addressed like an object. They can be even deleted, renamed or even injected at runtime. This is one of the most powerful qualities of the CFML dynamic language. You can at runtime manipulate objects and their functions. circle-info You can find all the different features of functions in the docs: [https://cfdocs.org/cffunctionarrow-up-right](https://cfdocs.org/cffunction) ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/functions#declaration) **Declaration** Copy /** * Hints */ {access} {modifier:static|final|abstract} {returnType} function {name}({attributes}){} ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/functions#examples) **Examples** Copy function hello(){ return "Hola"; } abstract function getFile(); public static function testStatic(){} public final function hello(){} private function saveData(){ } /** * Check for existence * * @name The key to check */ function boolean valueExists( required name ){ return variables.exists( arguments.name ); } circle-info Please note that you can use valid JavaDoc syntax and [DocBoxarrow-up-right](https://github.com/Ortus-Solutions/DocBox) will document your functions and arguments as well. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/functions#function-access-types-and-scopes) Function Access Types and Scopes ------------------------------------------------------------------------------------------------------------------------------------------------------- Functions can have different visibility contexts: * `public` - Available to the component and externally * `private` - Available only to the component that declares the method and any components that extend the component in which it is defined * `package` - Available only to the component that declares the method, components that extend the component, or any other components in the package * `remote` - Available to a locally or remotely executing page or component method, or a remote client through a URL, Flash, or a web service. To publish the function as a web service, this option is required. Another interesting tidbit in CFML is that the visibility determines where the function will exist within the scope of the CFC. Remember that functions in CFML are objects themselves. They can be added, removed, renamed even at runtime thanks to CFML being a dynamic language. * `public,remote` - The function reference is placed in both the `this` and `variables` scope * `private,package` - The function reference is placed in the `variables` scope Does this mean, that I can programmatically change an object at runtime by injecting (mixing) in new methods, or removing methods, or even renaming them? HECK YES SIREE BOB! This is the beauty of the dynamic language, you can manipulate object instances at runtime. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/functions#function-modifiers) Function Modifiers --------------------------------------------------------------------------------------------------------------------------- Function modifiers allows you to declare special behaviors to functions, from `static` availability to `final` and `abstract` declarations. The supported modifiers for CFML functions by CFML engine are the following: Modifier Lucee 5+ Adobe 2016 Adobe 2018 Adobe 2021 `static` Yes No No Yes `final` Yes No Yes Yes `abstract` Yes No Yes Yes We have created a section for each of these types, so you can read more about the modifiers: * [Static Constructs](https://modern-cfml.ortusbooks.com/cfml-language/components/static-constructs) * [Final Constructs](https://modern-cfml.ortusbooks.com/cfml-language/components/final-constructs) * [Abstract Constructs](https://modern-cfml.ortusbooks.com/cfml-language/components/abstract-constructs) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/functions#function-attributes-and-metadata) Function Attributes & Metadata ----------------------------------------------------------------------------------------------------------------------------------------------------- The `function` construct can also have many attributes or name-value pairs that will give it some extra functionality according to CFML engine (metadata). You can find all of them here: [https://cfdocs.org/cffunctionarrow-up-right](https://cfdocs.org/cffunction) . Below are the most common ones: * `output` - Will this function send content to the output stream. Try avoiding this to `true` unless you are building libraries of some type, else you are breaking encapsulation * `description` - A short text description of the function a part from the hint * `returnFormat` - Format to return for remote callers Copy function hello() description="" returnFormat=""{ } Please note that in CFML you can also declare these attributes via annotations in the comments section: Copy /** * Say Hello * * @description A nice function * @output false */ function sayHello(){ } Apart from the name-value pairs of attributes the CFML language gives you, you can also add your own. These are called function annotations or custom function metadata. They can be anything you like and they don't even have to have a value. The CFML engines then gives you the ability to read the metadata out of the functions via the `getMetadata()` or `getComponentMetadata()` functions. * [https://cfdocs.org/getmetadataarrow-up-right](https://cfdocs.org/getmetadata) * [https://cfdocs.org/getcomponentmetadataarrow-up-right](https://cfdocs.org/getcomponentmetadata) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/functions#function-arguments) Function Arguments --------------------------------------------------------------------------------------------------------------------------- Arguments tell the function how to do their operation. A function can receive zero or more arguments separated by commas in its declaration. **declaration** Copy function( required type name=default attribute=value, required type name=default attribute=value ){ } All CFML functions are dynamic, meaning it can take any number of arguments without you even adding the signatures. You can call functions by passing arguments by position or via name-value pairs or even with a structure/array of values, which will be called an `argumentCollection`. **example** Copy function sayHello( target ){ return "Hi #target#! I'm #name#"; } function add( required a, required b ){ return a + b; } // Let's call add calculator.add( 1, 2 ); calculator.add( a=1, b=2 ); // struct collection values = { a = 1, b = 2 }; calculator.add( argumentCollection=values ); // array collection values = [ 1, 2 ]; calculator.add( argumentCollection=values ); circle-check **Tip:** Please also note that you can add a-la-carte metadata or name-value pairs to each argument inline or via annotations like we have seen above. **example with annotations** Copy /** * Constructor * * @wirebox The wirebox reference * @wirebox.inject wirebox */ function init( required wirebox ){ variables.wirebox = arguments.wirebox; return this; } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/functions#function-returns) Function Returns ----------------------------------------------------------------------------------------------------------------------- CFML functions will use the `return` keyword to return a value from the function. A function can be marked `void` in its return type to denote that it does **not** return any value. However, if a function has no return type or `any` and you do not return explicitly a value, then the function will automatically return `null`. Copy void function nada(){ // I do stuff, but return nothing } function nada(){ // I do stuff, but also do not return anything } function add( a, b ){ return a + b; } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/functions#function-scopes) Function Scopes --------------------------------------------------------------------------------------------------------------------- You must be getting into the habit of scopes by now. Functions also has access to all Component scopes plus a few more that are only available to the function itself. * `arguments` - Collects all the incoming arguments. If the function is called via positional, then this will be a struct with numbers as keys. If the function is called via name-value pairs, then the struct will contain the same name-value pairs. * `local` - A struct that contains all the variables that are ONLY defined in the functions via the `var` keyword. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/functions#function-var-scope-or-local-scope) Function Var Scope or Local Scope --------------------------------------------------------------------------------------------------------------------------------------------------------- Each function has a `local` scope that is ONLY available for the life-time of the execution of the function. This is where you will be defining localized variables since your object can be multi-threaded. Always Always Always plan for multi-threaded applications and make sure you var scope your variables. Why? Well, if you do not var scope a variable then your variable will end up in the implicit scope which is `variables`. Copy // Sum is not var scoped, so it will be placed in the variables scope, memory leak anyone? function hello(){ sum = a + b; return sum; } function hello( a, b ){ var sum = a + b; return sum; } function hello( a, b ){ local.sum = a + b; return local.sum; } CFML also has a weird cascading lookup for variables, so if you do not explicitly specify the scope it is in, CFML will look for it for you. If you use a variable name without a scope prefix, CFML checks the scopes in the following order to find the variable: * Local (function-local, UDFs and CFCs only) * Arguments * Thread local (inside threads only) * Query (not a true scope; variables in query loops) * Thread * Variables * CGI * Cffile * URL * Form * Cookie * Client Because CFML must search for variables when you do not specify the scope, you can improve performance by specifying the scope for all variables. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/functions#executing-functions) Executing Functions ----------------------------------------------------------------------------------------------------------------------------- You can execute functions once you have an instance or reference of a component. If the function has arguments, you can pass them in three ways: positional, name-value pairs, or using a collection (array,struct) via the `argumentCollection` attribute. Copy user = new User( name="luis" ); writeoutput( user.getName() ); hello = user.sayHello( "bob" ); hello = user.sayHello( target="bob" ); results = calculator.add( 1, 2 ); results = calculator.add( a=1, b=2 ); vals = [ 1, 2 ]; results = calculator.add( argumentCollection=vals ); vals = { a = 1, b = 2 }; results = calculator.add( argumentCollection=vals ); [PreviousPropertieschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/components/properties) [NextStatic Constructschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/components/static-constructs) Last updated 4 years ago Was this helpful? --- # Null & Nothingness | Learn Modern ColdFusion in 100 Minutes What is nothingness? Is there nothingness only in outer space? If a tree falls in the forest and nobody listens, does it make a sound? Starting to see the point? Does nothing really mean nothing? To be or not to be? OK, I think we are going on a philosophical tangent, so let's get back to our geekiness: `null` is Java's way to refer to "nothingness.", something that does not exist and has no value. Support for the`null`keyword itself was introduced as an option in ColdFusion 2018 (as discussed in [this blog postarrow-up-right](https://coldfusion.adobe.com/2018/07/null-support-in-coldfusion-2018/) ) and has existed as an option in Lucee (as discussed in [this guidearrow-up-right](https://docs.lucee.org/guides/cookbooks/NullSupport.html) ). [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/null-and-nothingness#full-null-support) Full-Null Support ------------------------------------------------------------------------------------------------------------------------- Please note that full null support is **NOT** the default in the CFML engines. Meaning you will not be able to use the `null` keyword until it is activated or get real `null` values from databases or external services. In reality, you still could simulate `null` without full null support in both engines, and sometimes you get an empty string, sometimes a full Java `null`. So basically, the nonfull null support is a partial null support, which makes it hard for developers. **So as a rule of thumb, we always recommend checking for nullness no matter WHAT!** Eventually, this flag should default to true, in our opinion, and offer full-null support out of the box. Ok, back to activating full-null support. You can do this in the admin or programmatically via the `Application.cfc` file, which can be used when building web applications. You can learn more [about it here](https://modern-cfml.ortusbooks.com/beyond-the-100/applicationcfc) Application.cfc Copy component{ this.enableNullSupport = true; } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/null-and-nothingness#checking-for-nullness) Checking For Nullness --------------------------------------------------------------------------------------------------------------------------------- Use the `isNull()` or `isDefined()` methods to evaluate for nothingness. Copy r = getMaybeData() if( isNull( r ) ){ // do something because r doesn't exist } if( isDefined( "r" ) ){ } Also, remember that you can use the [Elvis operator](https://modern-cfml.ortusbooks.com/cfml-language/operators#elvis-operator-null-coalescing) to test for null and an operator and expression. Copy results = getMaybeData() ?: "default value" circle-info We would recommend that you use `isNull()` as it expresses coherently its purpose. Since `isDefined()` can also evaluate expressions. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/null-and-nothingness#creating-nulls) Creating Nulls ------------------------------------------------------------------------------------------------------------------- You can create nulls in different ways in CFML. Let's explore these: Approach Full Null Description `null` keyword check `r = null` Non returning function call If a function returns nothing, its assignment will produce a null. `function getNull(){}` `r = getNull()` `nullValue()` Lucee only function. `r = nullValue()` `javaCast( "null", "" )` Available in all engines `r = javaCast( "null", "" )` [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/null-and-nothingness#in-practice) In Practice ------------------------------------------------------------------------------------------------------------- If you have three eggs, and eat three eggs, then you might think you have "nothing," but in terms of eggs you have "0". Zero is something, it’s a number, and it’s not nothing. If you’re working with words and have a string like "hello" then delete the "h", "e", "l"s, and "o" you might think you’d end up with nothing, but you really have "" which is an empty string. It’s still something. Null in CFML is usually encountered when you ask for something that doesn’t exist. When looking at arrays, for instance, we created a list with five elements then asked CFML to give us the sixth element of that list. There is no sixth element, so CFML gave us null. It isn’t that there’s a blank in that sixth spot (""), it’s not a number 0, it’s nothingness – null. **Examples** Copy function getData( filter ){ if( isNull( arguments.filter ) ){ // then do this } else { // use the filter } } function returnsNull(){ if( key.exists( "invalid" ) ){ return key[ "invalid" ]; } } results = returnsNull(); writeOutput( isNull( results ) ); Also note that if a function returns **nothing** it will be the same as returning `null`. [PreviousOperatorschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/operators) [NextStringschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/strings) Last updated 1 year ago Was this helpful? --- # Static Constructs | Learn Modern ColdFusion in 100 Minutes triangle-exclamation Adobe 2018 does not support static constructors. Lucee 5+, and Adobe 2021+ supports it. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/static-constructs#what-is-static) What is static? In CFML, a static variable is a variable of a component that isn’t associated with an **instance** of a component. Instead, the variable belongs to the component definition itself. As a result, you can access the static variable without first creating the component instance. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/static-constructs#why-use-static) Why use static? This allows you to create pure utility objects or stateless services that require no instance or holds no instance data. It can also accelerate the retrieval of such variables or methods since no instance has to be ever instantiated in order to be used. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/static-constructs#where-can-i-apply-it) Where can I apply it? In CFML, the `static` keyword can be applied in the pseudo-constructor in order to initialize static variables in a component. This is called the **static constructor**. The keyword can also be applied to functions within a Component in order to declare static functions. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/static-constructs#static-constructor) Static Constructor ----------------------------------------------------------------------------------------------------------------------------------- The static constructor is execute once before the component is loaded for the first time, so every component of the same type will share the same **static** scope. This construct is placed inside the pseudo-constructor of the component. Copy component MyFunkyCalculator{ // Static Constructor static { CACHE_KEY = "luis"; multiplier = 4; } } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/static-constructs#static-methods) Static Methods --------------------------------------------------------------------------------------------------------------------------- Static methods can be used without an instance of the component and can also access static variables declared in the static constructor by using the `static` scope from within the same component. Copy component MyFunkyCalculator{ // Static Constructor static { CACHE_KEY = "luis"; multiplier = 4; } public static function calculate( a ){ return static.multiplier * a; }; public static function getGlobalCacheKey(){ return static.CACHE_KEY; } } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/static-constructs#accessing-static-constructs) Accessing Static Constructs ----------------------------------------------------------------------------------------------------------------------------------------------------- We have seen how to declare the static constructor and static methods, but how in the world do we acces them from outside the component? We leverage the `::` double colon syntax. Copy // Refer to the CFC by path, then use the :: and call a function or variable MyFunkyCalculator::CACHE_KEY; MyFunkyCalculator::calculate( 1 ); [PreviousFunctionschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/components/functions) [NextFinal Constructschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/components/final-constructs) Last updated 1 year ago Was this helpful? --- # Final Constructs | Learn Modern ColdFusion in 100 Minutes Both Adobe 2018 and Lucee Engines support the usage of `final` constructs for three contexts: * Components * Methods * Variables (Constants) Final modifiers disallow the modifications to the source code to maintain stricter programming constructs. This would be used when you do not want to allow code to override your component or function or variable. This can be a great asset if you are building libraries, frameworks or APIs that require fine granular control of how they can be extended or used. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/final-constructs#final-components) Final Components ------------------------------------------------------------------------------------------------------------------------------ Components can be declared as final, meaning they cannot be extended (inheritance) by other components. This is the ultimate code reuse blocker! However, a final component CAN extend other components. circle-check Final components can be used to prevent inheritance where it is not allowed. Great for APIs, frameworks, and libraries where the author wants to be strict about the usage of such code templates. Copy final component{} final component extends="MyService"{} circle-info Unlike `abstract` a function can be `final` even if the component is not `final`. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/final-constructs#final-functions) Final Functions ---------------------------------------------------------------------------------------------------------------------------- Functions within a component can also be declared as `final`. Final methods cannot be overridden by sub-components. Final methods can be used to limit the extent to which sub-components redefine the behavior of the parent classes. Copy component BaseUtil{ final function getFile(){ return getCurrentTemplatePath(); } } // Throws exception due to final method being overriden. component extends="BaseUtil"{ function getFile(){ return "hijacked"; } } circle-check This may be useful when frameworks/base components are being developed, to ensure the same implementation is being followed in all derived classes. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/final-constructs#final-variables) Final Variables ---------------------------------------------------------------------------------------------------------------------------- Variables declared as final are ensured to be constants for the rest of the execution process. The value of that final variable cannot be modified post-construction of the component. Usually these constructs are used in variables defined in the pseudo-constructor. Copy component{ final static CACHE_KEY = "cb_"; final NAME = "John Majano" NAME = "Lui Majano" // Throws a final variable exception final DETAILS = { "age" : 1 } DETAILS[ "nickname" ] = "Johnny Bravo" // Allowed DETAILS = {} // Disallowed } Usually, final variables should be in uppercase to denote them as contstants as per Java conventions and best practices. triangle-exclamation **Important**: The variables that contain references to other objects cannot be re-bound to reference news or other objects. i.e., If a `final` variable holds a reference to an array, the reference may not be updated to a new array – but the contents of the original array itself may be updated. The same should apply to structures. [PreviousStatic Constructschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/components/static-constructs) [NextAbstract Constructschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/components/abstract-constructs) Last updated 5 years ago Was this helpful? --- # Abstract Constructs | Learn Modern ColdFusion in 100 Minutes The abstract constructs can be both used in Lucee and Adobe 2018. The main goal of abstraction is to handle complexities by hiding/encapsulating unnecessary details from other users. Abstraction is implemented in most languages by defining a class that has methods, properties & constructors. Abstract will allow you to define two contexts of operation: 1. Components 2. Functions ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-Llb4dF663f83euBMP_-%252F-Lld6RR_t-EfkkqYWtmt%252FAbstract-Class-vs-Interface.png%3Falt%3Dmedia%26token%3D2227da20-e0ed-4889-92a9-b77e32bcbb30&width=768&dpr=3&quality=100&sign=1b4b1cad&sv=2) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/abstract-constructs#abstract-components) Abstract Components --------------------------------------------------------------------------------------------------------------------------------------- An abstract component allows you to make a template or blueprint for a component that will be eventually inherited from, so the inheriting class doesn't have to implement all of the methods. Therefore, abstract classes cannot be instantiated but only extended. Abstract classes can have both abstract and concrete methods defined within it. Abstract methods have no body, they are just declared, much like interfaces. Usually, you would do this to satisfy an interface declaration. In my years of experience, abstract classes usually go hand in hand with interfaces and usually implement [strategy patternsarrow-up-right](https://en.wikipedia.org/wiki/Strategy_pattern) . We would suggest that if you define abstract components that you add the prefix `Abstract` to the component name as best practice: `AbstractAnimal, AbstractLogger, AbstractPerson`. This goes a long way to help with readability and standards. circle-info In an inheritance hierarchy the first non-abstract class should implement **all** the abstract methods. AbstractAnimal.cfc Copy /** * An abstract animal class */ abstract component implements="IAnimal"{ property animalSize; property animalType; function init( animalSize, animalType ){ variables.animalSize = arguments.animalSize; variables.animalType = arguments.animalType; return this; } /** * Shortcut for getting the animal size */ function getSize(){ return variables.animalSize; } abstract function eat( any prey="" ) abstract function makeNoise() abstract function poop() } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/abstract-constructs#abstract-functions) Abstract Functions ------------------------------------------------------------------------------------------------------------------------------------- As you can see from the example above, abstract functions can be defined ONLY in an abstract component. These functions are demarcated as abstract so inherited components can implement them. You can have many abstract functions in your abstract component and you can also have many concrete functions as well: AbstractLogger.cfc Copy abstract component implements="ILogger"{ /** * Min logging level */ property name="levelMin" type="numeric"; /** * Max logging level */ property name="levelMax" type="numeric"; /** * Appender properties */ property name="properties" type="struct"; /** * Write an entry into the appender. You must implement this method yourself. * * @logEvent The logging event to log */ abstract function logMessage( required coldbox.system.logging.LogEvent logEvent ) /** * Setter for level min * * @throws AbstractAppender.InvalidLogLevelException */ AbstractAppender function setLevelMin( required levelMin ){ // Verify level if( this.logLevels.isLevelValid( arguments.levelMin ) AND arguments.levelMin lte getLevelMax() ){ variables.levelMin = arguments.levelMin; return this; } else { throw( message = "Invalid Log Level", detail = "The log level #arguments.levelMin# is invalid or greater than the levelMax (#getLevelMax()#). Valid log levels are from 0 to 5", type = "AbstractAppender.InvalidLogLevelException" ); } } /** * Utiliy to send to output to console. * * @message Message to send * @addNewLine Add a line break or not, default is yes */ private function out( required message, boolean addNewLine=true ){ if( arguments.addNewLine ){ arguments.message &= chr( 13 ) & chr( 10 ); } createObject( "java", "java.lang.System" ).out.println( arguments.message ); } } circle-info Only **abstract** components can contain **abstract** functions. [PreviousFinal Constructschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/components/final-constructs) [NextInterfaceschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/components/interfaces) Last updated 6 years ago Was this helpful? --- # Structures | Learn Modern ColdFusion in 100 Minutes A structure is a collection of data where each element of data is addressed by a **name or key** and it can hold a value of any type. Like a dictionary but on steroids: Copy // Create a struct via function myStruct = structnew() // Create a struct via literal syntax myStruct = {} circle-check **Tip** Underneath the hood, all CFML structures are based on the `java.util.Map` interface. So if you come from a Java background, structures are untyped `HashMaps`. As an analogy, think about a refrigerator. If we’re keeping track of the produce inside the fridge, we don’t really care about where the produce is in, or basically: **order doesn’t matter**. Instead, we organize things by name, which are unique, and each name can have any value. The name _grapes_ might have the value 2, then the name _lemons_ might have the value 1, and _eggplants_ the value 6. circle-info All CFML structures are passed to functions as memory references, not values. Keep that in mind when working with structures. There is also the `passby=reference|value` attribute to function arguments where you can decide whether to pass by reference or value. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#key-value-pairs) Key-Value Pairs ----------------------------------------------------------------------------------------------------------- A structure is an _unordered collection_ where the data gets organized as a key and value pair. CFML syntax for structures follows the following syntax: Copy produce = { grapes = 2, lemons = 1, eggplants = 6 }; circle-check **Tip** Please note that `=` sign and `:` are interchangeable in CFML. So you can use any to define your structures. Since CFML is a case-insensitive language, the above structure will store all keys in uppercase. If you want the **exact casing** to be preserved in the structure, then surround the keys with quotes (`"`). circle-info The exact casing is extremely important if you will be converting these structures into JSON in the future. Copy produce = { "grapes" = 2, "lemons" = 1, "eggplants" = 6 }; ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LA-UbMqUYOVVZvx_rxu%252F-LA-Ur94dmX8J9bORxX2%252FScreen%2520Shot%25202017-10-05%2520at%25204.46.02%2520PM.png%3Fgeneration%3D1523648003617604%26alt%3Dmedia&width=768&dpr=3&quality=100&sign=efb2584b&sv=2) The _key_ is the address, and the _value_ is the data at that address. Please note that the _value_ can be ANYTHING. It can be an array, an object, a simple value, or even an embedded structure. It doesn't matter. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#retrieving-values) Retrieving Values --------------------------------------------------------------------------------------------------------------- Retrieving values from structures can be done via dot or array notation or the `structFind()` function. Let's explore these approaches: ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#array-notation) Array Notation Copy writeOutput( "I have #produce[ "grapes" ]# grapes in my fridge!" ); writeOutput( "I have #produce[ "eggplants" ]# eggplants in my fridge!" ); ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#dot-notation) Dot Notation Copy writeOutput( "I have #produce.grapes# grapes in my fridge!" ); writeOutput( "I have #produce.eggplants# eggplants in my fridge!" ); ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#structfind-structure-key-defaultvalue) structFind( structure, key, \[defaultValue \] ) [https://cfdocs.org/structfindarrow-up-right](https://cfdocs.org/structfind) Copy // Member Function writeOutput( "I have #produce.find( "grapes" )# grapes in my fridge!" ); writeOutput( "I have #produce.find( "eggplants" )# eggplants in my fridge!" ); // Global Function writeOutput( "I have #structFind( produce, "grapes" )# grapes in my fridge!" ); writeOutput( "I have #structFind( produce, "eggplants" ) eggplants in my fridge!" ); circle-exclamation However, please be aware that when dealing with native Java hashmaps, we recommend using array notation as the case is preserved in array notation, while in dot notation, it does not. circle-check CFML offers also the `structGet()` function which will search for a key or a key path. If there is no structure or array present in the path, this function creates structures or arrays to make it a valid variable path. [https://cfdocs.org/structgetarrow-up-right](https://cfdocs.org/structget) ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#safe-navigation) Safe Navigation CFML also supports the concept of [safe navigation](https://modern-cfml.ortusbooks.com/cfml-language/operators#safe-navigation-operator) when dealing with structures. Sometimes it can be problematic when using dot notation on nested structures since some keys might not exist or be `null`. You can avoid this pain by using the safe navigation operator `?.` instead of the traditional `.` , and combine it with the elvis operator `?:` so if null, then returning a value. Copy user = { age : 40 } echo( user.age ) // 40 echo( user.salary ) // throws exception echo( user?.salary ) // nothing, no exception echo( user?.salary ?: 0 ) // 0 [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#setting-values) Setting Values --------------------------------------------------------------------------------------------------------- I can also set new or override structure values a la carte. You can do so via array/dot notation or via the `structInsert(), structUpdate()` functions ([https://cfdocs.org/structinsertarrow-up-right](https://cfdocs.org/structinsert) , [https://cfdocs.org/structupdatearrow-up-right](https://cfdocs.org/structupdate) ) Copy // new key using default uppercase notation produce.apples = 3; // new key using case sensitive key produce[ "apples" ] = 3; // I just ate one grape, let's reduce it produce[ "grapes" ] = 1; // or produce.grapes--; produce.insert( "newVeggie", 2 ) produce.update( "newVeggie", 1 ) structInsert( produce, "carrots", 5 ) structUpdate( produce, "carrots", 2 ) circle-check **Tip** You can use the `toString()` call on any structure to get a string representation of its keys+values: `produce.toString()` [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#checking-contents-and-size) Checking Contents & Size ------------------------------------------------------------------------------------------------------------------------------- CFML also offers some useful methods when dealing with structures: Function Member Function `structIsEmpty()` `isEmpty()` `structCount()` `count()` [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#key-values-and-existence) Key Values & Existence --------------------------------------------------------------------------------------------------------------------------- Here are some great functions that deal with getting all key names, and key values or checking for existence: Function Member Function `structKeyArray()` `keyArray()` `structKeyList()` `keyList()` `structKeyExists()` `keyExists()` Copy produce.keyArray() .each( (item) => echo( item ) ) writeOutput( "My shopping bag has: #produce.keyList()# " ) writeOutput( "Do you have carrots? #produce.keyExists( 'carrots' )#" ) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#structure-types) Structure Types ----------------------------------------------------------------------------------------------------------- In CFML, not only can you create case-insensitive unordered structures but also the following types using the `structNew()` function ([https://cfdocs.org/structnewarrow-up-right](https://cfdocs.org/structnew) ) Type Adobe 2018 Adobe 2021 Lucee `casesensitive` check `normal` check check check `ordered` or `linked` check check check `ordered-casesensitive` check `soft` check `synchronized` check `weak` check Here is the signature for the `structnew()` function on Adobe engines: Copy structNew( [type[[,sortType][,sortOrder][,localeSensitive]|[,callback]]] ) Here is the signature for Lucee engines ([https://docs.lucee.org/reference/functions/structnew.htmlarrow-up-right](https://docs.lucee.org/reference/functions/structnew.html) ) Copy structNew( [type, [onMissingKey] ] ) Now let's create some different types of structures Copy produce = structNew(); pickyProduce = structNew( "casesensitive" ) queue = structNew( "ordered" ) pickyQueue = structNew( "ordered-casesensitive" ) linkedList = structNew( 'ordered' ); cache = structnew( 'soft' ); ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#literal-syntax) Literal Syntax You can also use literal syntax for some of these types: Copy // ordered struct myStruct = [:] or [=] // Case sensitive struct ACF Only myStruct = ${} // Case sensitive ordered struct ACF Only myStruct = $[=] [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#common-methods) Common Methods --------------------------------------------------------------------------------------------------------- Once you create structures, you can use them in many funky ways. Please check out all the [structure functionsarrow-up-right](https://cfdocs.org/struct-functions) and all the structure modern [member functionsarrow-up-right](https://cfdocs.org/member) that are available to you. ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LA-UbMqUYOVVZvx_rxu%252F-LA-UrDELNzOehtFU3eI%252FScreen%2520Shot%25202017-10-05%2520at%25204.57.20%2520PM.png%3Fgeneration%3D1523648003558789%26alt%3Dmedia&width=768&dpr=3&quality=100&sign=4af4db78&sv=2) As you can see, there are many cool methods for detecting keys, values, lengths, counts, etc. A very cool method is `keyArray()` which gives you the listing of keys as an array: ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LA-UbMqUYOVVZvx_rxu%252F-LA-UrDTBpfFGIWSKjxL%252FScreen%2520Shot%25202017-10-05%2520at%25204.58.09%2520PM.png%3Fgeneration%3D1523648003555518%26alt%3Dmedia&width=768&dpr=3&quality=100&sign=9d8eb319&sv=2) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#looping-over-structures) Looping Over Structures --------------------------------------------------------------------------------------------------------------------------- You can use different constructs for looping over structures: * `for` loops * `loop` constructs * `each()` closures Copy for( var key in produce ){ systemOutput( "I just had #produce[ key ]# #key#" ); } produce.each( function( key, value ){ systemOutput( "I just had #value# #key#" ); } ); ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#multi-threaded-looping) Multi-Threaded Looping As of now, only Lucee and Adobe 2021 allows you to leverage the `each()` operations in a multi-threaded fashion. The `structEach()` or `each()` functions allow for a `parallel` and `maxThreads` arguments so the iteration can happen concurrently on as many `maxThreads` as supported by your JVM. Copy structEach( struct, callback, parallel:boolean, maxThreads:numeric ); each( collection, callback, parallel:boolean, maxThreads:numeric ); This is incredibly awesome as now your callback will be called concurrently! However, please note that once you enter concurrency land, you should shiver and tremble. Thread concurrency will be of the utmost importance, and you must ensure that var scoping is done correctly and that appropriate locking strategies are in place. Copy myStruct.each( function( key, value ){ myservice.process( value ); }, true, 20 ); Even though this approach to multi-threaded looping is easy, it is not performant and/or flexible. Under the hood, the engines use a single thread executor for each execution, do not allow you to deal with exceptions, and if an exception occurs in an element processor, good luck; you will never know about it. This approach can be verbose and error-prone, but it's easy. You also don't control where the processing thread runs and are at the mercy of the engine. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/structures#coldbox-futures-parallel-programming) ColdBox Futures Parallel Programming If you would like a functional and much more flexible approach to multi-threaded or parallel programming, consider using the ColdBox Futures approach (usable in ANY framework or non-framework code). You can use it by installing ColdBox or WireBox into any CFML application and leveraging our `async` programming constructs, which behind the scenes, leverage the entire Java Concurrency and Completable Futures frameworks. [![Logo](https://coldbox.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1096988991-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fspaces%252F-LA-UVvJIdbk5Kfk3bDs%252Favatar.png%3Fgeneration%3D1547216546996685%26alt%3Dmedia&width=48&height=48&sign=3b26690c&sv=2)Parallel Computations | ColdBox HMVC Documentationcoldbox.ortusbooks.comchevron-right](https://coldbox.ortusbooks.com/digging-deeper/promises-async-programming/parallel-computations) ColdBox Futures and Async Programming Here are some methods that will allow you to do parallel computations: * `all( a1, a2, ... ):Future` : This method accepts an infinite amount of future objects, closures, or an array of closures/futures to execute them in parallel. When you call on it, it will return a future that will retrieve an array of the results of all the operations. * `allApply( items, fn, executor ):array` : This function can accept an array of items or a struct of items of any type and apply a function to each of the items in parallel. The `fn` argument receives the appropriate item and must return a result. Consider this a parallel `map()` operation. * `anyOf( a1, a2, ... ):Future` : This method accepts an infinite amount of future objects, closures, or an array of closures/futures and will execute them in parallel. However, instead of returning all of the results in an array like `all()`, this method will return the future that executes the fastest! Race Baby! * `withTimeout( timeout, timeUnit )` : Apply a timeout to `all()` or `allApply()` operations. The `timeUnit` can be days, hours, microseconds, milliseconds, minutes, nanoseconds, and seconds. The default is milliseconds. [PreviousArrayschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/arrays) [NextDatabase Querieschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/queries) Last updated 3 years ago Was this helpful? --- # Numbers | Learn Modern ColdFusion in 100 Minutes There are two basic kinds of numbers in CFML: **integers** (whole numbers) and **floats** (have a decimal point). Internally, each CFML engine treats them uniquely and backs up each numerical value as a Java class: `java.lang.Double` or `java.lang.Integer`. Type Size (bits) Min Value Max Value `Integer` 32 \-2,147,483,648 (-231) 2,147,483,647 (231 - 1) Type Size (bits) Significant Bits Exponent Bits Decimal Digits `Double` 64 53 11 15-16 triangle-exclamation Lucee stores all numerical values as Doubles triangle-exclamation Adobe stores integers as Integer and floats as Doubles circle-check **Tip:** If you are dealing with currency or tracking precision, please read about `precisionEvaluate()` to represent big numbers and precision results: [https://cfdocs.org/precisionevaluatearrow-up-right](https://cfdocs.org/precisionevaluate) Copy a = 1; b = 50.1; writeOutput( a * b ); Also, note that CFML will do the auto-casting for you when converting between integers and doubles. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/numbers#numeric-type) Numeric Type -------------------------------------------------------------------------------------------------- Once we start looking at functions/closures and lambdas, you will see that you can also type the incoming arguments and results of functions. You also won't need to type it with integer or float, just as `numeric:` Copy numeric function add( numeric a, numeric b ){ return a + b; } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/numbers#operators-and-functions) Operators & Functions ---------------------------------------------------------------------------------------------------------------------- CFML offers tons of mathematical [operators](https://modern-cfml.ortusbooks.com/cfml-language/operators#arithmetic-operators) and functions: [https://cfdocs.org/math%2Dfunctionsarrow-up-right](https://cfdocs.org/math%2Dfunctions) abs aCos arrayAvg arraySum aSin atn bitAnd bitMaskClear bitMaskRead bitMaskSet bitNot bitOr bitSHLN bitSHRN bitXor ceiling cos decrementValue expt fix floor formatBaseN incrementValue inputBaseN int log log10 max min pi precisionEvaluate rand randomize randRange round sgn sin sqr tan [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/numbers#casting-parsing) Casting/Parsing -------------------------------------------------------------------------------------------------------- CFML also has a `toNumeric()` function that you can use to cast a value to a number using different [radixesarrow-up-right](https://en.wikipedia.org/wiki/Radix) . Copy toNumeric( "29.5" ) toNumeric( "FF0011", "hex" ) toNumeric( "1010", "bin" ) The `parseNumber()` is also used to convert a string number into a numeral system ([https://cfdocs.org/parsenumberarrow-up-right](https://cfdocs.org/parsenumber) ) circle-info In a [positional numeral systemarrow-up-right](https://en.wikipedia.org/wiki/Positional_numeral_system) , the radix or base is the number of unique [digitsarrow-up-right](https://en.wikipedia.org/wiki/Numerical_digit) , including the digit zero, used to represent numbers. For example, for the [decimal systemarrow-up-right](https://en.wikipedia.org/wiki/Decimal) (the most common system in use today) the radix is ten, because it uses the ten digits from 0 through 9. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/numbers#is-it-a-number) Is it a number? ------------------------------------------------------------------------------------------------------- CFML provides the `isNumeric()` function to determine if the passed value can be converted to a numeric value. Copy isNumeric( 23 ) // yes isNumeric( "twenty" ) // no isNumeric( 5e2 ) // yes [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/numbers#repeating-instructions) Repeating Instructions ---------------------------------------------------------------------------------------------------------------------- Number variables can be used to repeat instructions. Like in many other languages, CFML supports the `for`, `while` and `loop` constructs: Copy for( var i = 0; i <= 10; i++ ){ writeOutput( "Showing day " & i ); } i =1; while( i <= 10 ){ writeOutput( "Showing day " & i++ ); } circle-info Please note that the syntax varies from tag to script, so refer to the docs for subtle differences. Please also note that you can iterate over structures, arrays, queries, and objects in CFML; we will see this in later sections. See [https://cfdocs.org/cflooparrow-up-right](https://cfdocs.org/cfloop) , [https://cfdocs.org/cfwhilearrow-up-right](https://cfdocs.org/cfwhile) for more information [PreviousJSONchevron-left](https://modern-cfml.ortusbooks.com/cfml-language/json) [NextArrayschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/arrays) Last updated 3 years ago Was this helpful? --- # Interfaces | Learn Modern ColdFusion in 100 Minutes Interfaces are a type of component that have a set of signatures for specific functions and in some of the latest versions of Lucee and Adobe ColdFusion it can even have some implemented functions. You can basically call an interface a signature map for the type of components you want to create. In statically typed languages, they make a lot of sense since they can allow you to add/modify behavior of classes that the compiler can understand on how to link and compile. In a dynamic language, where functions can mutate or even be removed or injected at runtime, interfaces don't make soooo much sense. However, interfaces are a great way to provide documented signatures for developers to follow. ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-Llb4dF663f83euBMP_-%252F-Lld64SOtd84odKmPPVg%252Finterfaces-vs-abstract-classes-1.png%3Falt%3Dmedia%26token%3De3ae8479-46c6-40e1-aca1-545fc6d20f08&width=768&dpr=3&quality=100&sign=4e502f4f&sv=2) If you are developing frameworks, libraries or structured domain models where implementations can be done at a later point of time, or different strategies adapted; interfaces are king. ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-Llb4dF663f83euBMP_-%252F-Lld6LFvsOF-8E6LZBmd%252F6a00e5501e33db8834016302f63fc2970d-500wi.png%3Falt%3Dmedia%26token%3Dc4e6cfda-3acb-4a3d-bd98-21da0ae82a06&width=768&dpr=3&quality=100&sign=43bd5bae&sv=2) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/interfaces#declaration) Declaration -------------------------------------------------------------------------------------------------------------- Interfaces are defined in a file template with a `.cfc` extension. For best practice you can start the name of the interface with a capital `I,` example: `IAnimal.cfc, ILogger.cfc, IAdapter.cfc` Copy interface extends="other_interfaces"{ any function returnAny( required numeric obj, boolean why=false ) function sayHello() ILogger function logEvent( required logEvent ) // If in Adobe2018 or Lucee, you can implement default behavior function getCacheKey(){ return "default_key"; } } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components/interfaces#implementation) Implementation -------------------------------------------------------------------------------------------------------------------- Interfaces can extend other interfaces and components that implement them can also implement many interfaces: Copy component implements="ILogger,IAdapter"{ any function returnAny( required numeric obj, boolean why=false ){ // implementation here. } function sayHello(){ return "Hola"; } ILogger function logEvent( required logEvent ){ // log this... return this; } } [PreviousAbstract Constructschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/components/abstract-constructs) [NextClosureschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/closures) Last updated 6 years ago Was this helpful? --- # Conditionals | Learn Modern ColdFusion in 100 Minutes [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/conditionals#operators) Operators ------------------------------------------------------------------------------------------------- Conditional statements evaluate to **true** or **false** only. The most common conditional operators are `==` (equal), `!=` (not equal), `>` (greater than), `>=` (greater than or equal to), `<` (less than), and `<=` (less than or equal to). You can also define the operators as abbreviations: `EQ, NEQ, GT, GTE, LT, and LTE`. Copy a = 1; if( a == 1 ) if( a > 2 ) if( a < 2 ) if( a != 2 ) if( a >= 1 ) if( a <= 1 ) Some instructions return a `true` or `false`, so they're used in conditional statements, for example, `IsArray` which is `true` only when the variable is an "array". Structures have an instruction named `structKeyExists()` or `keyExists()` which returns `true` if a key is present in a structure. Strings can also be used for conditional operations by checking the `.length()` member function. Copy a = [1,3]; if( isArray( a ) ){ // work on the array } produce = { grapes = 2, lemons = 1, eggplants = 6 }; if( produce.keyExists( "grapes" ) ){ // eat a grape produce.grapes--; } Also integers can be evaluated as **true** or **false**. In ColdFusion, **0 (zero)** is **false** and any other integers are **true**. Copy I am true so will show I am true so will show I am false so will not show [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/conditionals#if-else-if-and-else) If, Else If, & Else --------------------------------------------------------------------------------------------------------------------- Why do we have conditional statements? Most often it's to control conditional instructions, especially `if` / `else if` / `else` expressions. Let's write an example by adding a method to our `PersonalChef.cfc` class: Copy component accessors=true{ property name="status"; function init(){ status = "The water is not boiling yet."; return this; } function water_boiling( numeric minutes ){ if( arguments.minutes < 7 ){ status = "The water is not boiling yet."; } else if ( arguments.minutes == 7 ){ status = "It's just barely boiling."; } else if ( arguments.minutes == 8 ){ status = "It's boiling!"; } else { status = "Hot! Hot! Hot!"; } return this; } } Try this example using 5, 7, 8 and 9 for the values of minutes. Copy chef = new PersonalChef(); for( i in [ 5, 7, 8, 9 ] ){ chef.water_boiling( i ); systemOutput( chef.getStatus() ); } * When the minutes is 5, here is how the execution goes: Is it true that 5 is less than 7? Yes, it is, so print out the line `The water is not boiling yet.`. * When the minutes is 7, it goes like this: Is it true that 7 is less than 7? No. Next, is it true that 7 is equal to 7? Yes, it is, so print out the line `It's just barely boiling`. * When the minutes is 8, it goes like this: Is it true that 8 is less than 7? No. Next, is it true that 8 is equal to 7? No. Next, is it true that 8 is equal to 8? Yes, it is, so print out the line `It's boiling!.` Lastly, when total is 9, it goes:" Is it "true" that 9 is less than 7? No. Next, is it true that 9 is equal to 7? No. Next, is it true that 9 is equal to 8? No. Since none of those are true, execute the else and print the line `Hot! Hot! Hot!`. An `if` block has: * One `if` statement whose instructions are executed only if the statement is **true** * Zero or more `else if` statements whose instructions are executed only if the statement is **true** * Zero or one `else` statement whose instructions are executed if no `if` nor `else if` statements were **true** Only one section of the `if / else if / else` structure can have its instructions run. If the if is **true**, for instance, CFML will never look at the `else if`. Once one block executes, that’s it. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/conditionals#ternary-operator) Ternary Operator --------------------------------------------------------------------------------------------------------------- The ternary operator is a compact way to do an `if, else, else if` expression statements. It is very common in other languages and can be used for a more fluent expressive conditional expression. Copy ( 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. Please note that you can chain the `trueStatement` and the `falseStatement` into more tenrary operations. However, don't abuse it as they will look ugly and just be very complex to debug. Copy ( 1 == 1 ) ? systemOutput( "true" ) : systemOutput( "false" ); The output of the above statement will be..... `true` of course! [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/conditionals#elvis-operator) Elvis Operator ----------------------------------------------------------------------------------------------------------- Before Elvis we had `isDefined(), structKeyExists()` and `IF` statements to do these kind of evaluations. They work, but not very expressive or concise. 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` or does not exist. For instance, Copy myName = userName ?: "Anonymous"; If `userName` does not exist or evaluates to `null` then the default value of the `myName` will be assigned the right part of the `?:` elvis operator -> `Anonymous` circle-exclamation **Warning:** The elvis operator is incredibly flawed in Adobe ColdFusion 10-11-2016 and Lucee 4.5. Just avoid using it if you are using those versions. Unfortunate but true. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/conditionals#safe-navigation-operator) Safe Navigation Operator ------------------------------------------------------------------------------------------------------------------------------- The safe navigation operator was introduced in Adobe ColdFusion 2016 and Lucee 5.2 and it allows for you to navigate structures by not throwing the dreaded `key not exists` exception but returning an `undefined` or `null` value. You can then combine that with the elvis operator and create nice chainable struct navigation. For example instead of doing things like: Copy result = ""; if( structKeyExists( var, "key" ) ){ if( structKeyExists( var.key, "otherkey" ){ result = var.key.otherkey; } } You can do things like this: Copy result = var?.key?.otherKey ?: ""; The hook operator (`?`) along with the dot operator (`.`) is known as safe navigation operator(`?.`). The safe navigation operator makes sure that if the variable used before the operator is not defined or java `null`, then instead of throwing an error, the operator returns `null` for that particular access. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/conditionals#switch-case-and-default) Switch, Case, & Default ----------------------------------------------------------------------------------------------------------------------------- Another situation that involves conditional logic is when a single variable or expression that can have a variety of values and different statements or functions needed to be executed depending on what that value is. One way of handling this situation is with a `switch / case / default` block. Copy switch( expression ){ case value : [ case otherValue ] : { // operations break; } default : { // Default operations } } Much like how the `if` statement marks the start of an `if` block and contains one or more `else if` statements and perhaps one (and only one) `else` statement, the `switch` statement marks the start of a `switch` block and can contain multiple `case` statements and perhaps one (and only one) `default` statement. The main difference is that `switch / case / default` can only evaluate the resulting value of a single variable or expression, while the `if / else if / else` block lets you evaluate the `true or false` result of different variables or expressions throughout the block. Copy switch( city ){ case "New York": region= "East Coast"; break; case "Los Angeles": region= "West Coast"; break; case "Phoenix": region= "Phoenix"; break; case "Cleveland" : case "Cincinnati" : { region= "Midwest"; break; } default: region="Unknown"; } Please note that you can create a body for the `case` statements with curly braces. As best practice, do so for all `case` and/or `default` blocks [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/conditionals#while-loops) While Loops ----------------------------------------------------------------------------------------------------- The `while( conditional )` expression allows you to execute a code block as many times as the `conditional` expression evaluates to **true**. This is a great way to work with queues, stacks or just simple evaluations. Copy testCondition = true; count = 0; while( testCondition ){ count++; if( count == 5) { testCondition = false; } } systemOutput( count ); [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/conditionals#the-and-common-mistake) The `==` and `=` Common Mistake ------------------------------------------------------------------------------------------------------------------------------------ The #1 mistake people encounter when writing conditional statements is the difference between `=` and `==`. * `=` is an assignment. It means "take what's on the right side and stick it into whatever is on the left side" (or its telling not asking.) * `==` is a question. It means "is the thing on the right equal to the thing on the left" (or its asking not telling.) [PreviousDatabase Querieschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/queries) [NextException Managementchevron-right](https://modern-cfml.ortusbooks.com/cfml-language/exception-management) Last updated 5 months ago Was this helpful? --- # Exception Management | Learn Modern ColdFusion in 100 Minutes [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/exception-management#try-catch-finally) Try/Catch/Finally ------------------------------------------------------------------------------------------------------------------------- The CFML language also provides you with a traditional approach to deal with error handling at the code block level. This is usually a trio of constructs: * `try`: The try block allows you to demarcate the code to test if it fails or passes ([https://cfdocs.org/cftryarrow-up-right](https://cfdocs.org/cftry) ) * `catch` : The catch block is executed when the try block fails ([https://cfdocs.org/cfcatcharrow-up-right](https://cfdocs.org/cfcatch) ) * `finally` : The finally block executes no matter if the try fails or passes. It is guaranteed to always execute. ([https://cfdocs.org/cffinallyarrow-up-right](https://cfdocs.org/cffinally) ) Basically, a try and catch statement attempts some code. If the code fails, CFML will do whatever is in the exception to try to handle it without breaking. Of course, many different types of exceptions can occur, which should sometimes be handled in a different manner than the others. Copy try{ // code to try to execute } catch( any e ) { // the any type catches ALL errors from the try above } catch( myType e ){ // Catch the `myType` only type of exception } finally { // this code executes no matter what } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/exception-management#catch-types) Catch Types ------------------------------------------------------------------------------------------------------------- The catch construct can take an `any` or a custom exception type declared by the CFML engine, Java code or custom exceptions within your code. This is a great way to be able to intercept for specific exception types and address them differently. Copy try{ } catch( database e ){ } catch( template e ){ } ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/exception-management#native-exception-types) Native Exception Types Some of the exception types found in CFML are the following * `application`: catches application exceptions * `database`: catches database exceptions * `template`: catches ColdFusion page exceptions * `security`: catches security exceptions * `object`: catches object exceptions * `missingInclude`: catches missing include file exceptions * `expression`: catches expression exceptions * `lock`: catches lock exceptions * `custom_type`: catches the specified custom exception type that is defined in a [cfthrowarrow-up-right](https://cfdocs.org/cfthrow) tag * `java.lang.Exception`: catches Java object exceptions * `searchengine`: catches Verity search engine exceptions * `any`: catches all exception types ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/exception-management#custom-exception-types) Custom Exception Types Custom exception types are defined by you the programmer and they can also be intercepted via their defined name. Let's say that the exception type is "`InvalidInteger`" then you can listen to it like this: Copy try{ throw( type="invalidInteger" ); } catch ( "InvalidInteger" e ){ } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/exception-management#throwing-exceptions) Throwing Exceptions ----------------------------------------------------------------------------------------------------------------------------- Now that you have seen how to listen to exceptions, let's discover the `throw` or `cfthrow` constructs used to throw a developer-specific exception. ([https://cfdocs.org/cfthrowarrow-up-right](https://cfdocs.org/cfthrow) ) The `throw()` function or tag has several attributes: * **Type** : A custom or CFML core type * **Message** : Describes the exception event * **Detail** : A detailed description of the event * **errorCode** : A custom error code * **extendedInfo** : Custom extended information to send in the exception, can be anything * **object** : Mutually exclusive with the other attributes, usually another exception object or a raw Java exception type. Copy try { throw( message="Oops", detail="xyz", errorCode=12 ); } catch (any e) { writeOutput( "Error: " & e.message); } finally { writeOutput( "I run even if no error" ); } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/exception-management#rethrowing-exceptions) Rethrowing Exceptions --------------------------------------------------------------------------------------------------------------------------------- The `rethrow` or `cfrethrow` construct allows you to well, `rethrow` the active exception by preserving all of the exception information and types. Usually you use `rethrow` within a catch block after you have done some type of operations on the incoming exception. ([https://cfdocs.org/cfrethrowarrow-up-right](https://cfdocs.org/cfrethrow) ) Copy try{ runAroundEachClosures( arguments.suite, arguments.spec ); } catch( any e ){ rethrow; } finally { runAfterEachClosures( arguments.suite, arguments.spec ); } // Mix In Stub try{ // include it arguments.targetObject.$include = variables.$include; arguments.targetObject.$include( instance.mockBox.getGenerationPath() & tmpFile ); structDelete( arguments.targetObject, "$include" ); // Remove Stub removeStub( genPath & tmpFile ); } catch( any e ) { // Remove Stub removeStub( genPath & tmpFile); rethrow; } [PreviousConditionalschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/conditionals) [NextComponentschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/components) Last updated 2 years ago Was this helpful? --- # Properties | Learn Modern ColdFusion in 100 Minutes Properties are a way to create attributes/fields/data for your object, which can also adhere to inheritance rules. They are almost the same as fields in Java. In CFML, they can also be used to describe further capabilities for RESTFul/SOAP web services and Hibernate ORM. If `accessors` are enabled, CFML will track those properties in the `variables` scope according to their name and create automatic getter and setter methods for those properties. ([https://cfdocs.org/cfpropertyarrow-up-right](https://cfdocs.org/cfproperty) ) Copy property name="firstName" default=""; property name="lastName" default=""; property name="age" type="numeric" default="0"; property name="address" type="array"; The `property` construct can also have different name-value pair attributes that can enhance its functionality. You can find all of them here: [https://cfdocs.org/cfpropertyarrow-up-right](https://cfdocs.org/cfproperty) . Below are the most common ones: * `type` - A valid CFML type * `default` - Default value when the object is created, else defaults to `null`. * `setter` - Generate a setter method or not, defaults to true * `getter` - Generate a getter method or not, defaults to true Please note that in CFML you can also declare these attributes via annotations in the comments section, weird, I know! Copy /** * The user age * @type numeric * @default 0 */ property name="age" [PreviousComponentschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/components) [NextFunctionschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/components/functions) Last updated 6 years ago Was this helpful? --- # Components | Learn Modern ColdFusion in 100 Minutes **ColdFusion (CFML) is object-oriented, period!** CFML is an Object-Oriented programming language which means that all the things we interact with inside the virtual machine are objects, which in our case we will call Components (CFCs). Objects can hold data, called **properties**, and they can perform actions, called **methods** or **functions,** they can inherit from other objects, they can implement interfaces, they can contain metadata, and even act as RESTFul webservices. circle-info Remember that objects are not only data but data + behavior. For an example of an object, think about **you** as a human being. You have properties/attributes like height, weight, and eye color. You have functions/methods like walk, run, wash dishes, and daydream. Different kinds of objects have different properties and functions. Some might even just be a collection of functions (utility/static/service objects) or what are referred to as stateless objects, there is no instance data that they represent. CFML supports not only the traditional avenues for object orientation but many unique constructs and dynamic runtime additions. Enjoy! [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components#classes-and-instances) Classes and Instances ----------------------------------------------------------------------------------------------------------------------- In Object-Oriented programming we define **classes** which are abstract descriptions of a category or type of thing; a blueprint. In our case, we will call them components and it defines what properties and functions all objects (instances) of that type have. You can consider them to be a blueprint of your object representation. They should have a distinct job and a **single** responsibility (if possible), try to avoid creating God objects. > In object-oriented programming, a God object is an object that knows too much or does too much. The God object is an example of an anti-pattern. A common programming technique is to separate a large problem into several smaller problems (a divide and conquer strategy) and create solutions for each of them. - [https://en.wikipedia.org/wiki/God\_objectarrow-up-right](https://en.wikipedia.org/wiki/God_object) Let's check out an example of a simple Component, `User.cfc` Copy /** * I represent a user in the system * @author Luis Majano */ component accessors="true"{ /** * The name of the user */ property name="name"; /** * The age of the user */ property name="age" type="numeric"; /** * Constructor */ function init( required name ){ variables.name = arguments.name; return this; } function run(){ // run baby, run! } } Please check out the following articles: * [https://en.wikipedia.org/wiki/Class\_(computer\_programming)arrow-up-right](https://en.wikipedia.org/wiki/Class_(computer_programming)) * [https://en.wikipedia.org/wiki/Instance\_(computer\_science)arrow-up-right](https://en.wikipedia.org/wiki/Instance_(computer_science)) * [https://en.wikipedia.org/wiki/Encapsulation\_(computer\_programming)arrow-up-right](https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)) * [https://en.wikipedia.org/wiki/Abstraction\_(software\_engineering)arrow-up-right](https://en.wikipedia.org/wiki/Abstraction_(software_engineering)) * [https://en.wikipedia.org/wiki/God\_objectarrow-up-right](https://en.wikipedia.org/wiki/God_object) * [http://www.learncfinaweek.com/week1/OOP/arrow-up-right](http://www.learncfinaweek.com/week1/OOP/) * [https://en.wikipedia.org/wiki/Mutator\_methodarrow-up-right](https://en.wikipedia.org/wiki/Mutator_method) ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components#notes-of-interest) Notes of Interest The attribute `accessors` in the component definition denotes that automatic **getters (**[**accessors**arrow-up-right](https://en.wikipedia.org/wiki/Mutator_method) **)** and **setters (**[**mutators**arrow-up-right](https://en.wikipedia.org/wiki/Mutator_method) **)** will be created for all defined properties in the object. Also notice that the component and each property can be documented using `/** **/` notation, which is great for automatic documentation generators like [DocBoxarrow-up-right](https://www.forgebox.io/view/docbox) . circle-check Get into the habit of inline documentation, it can go a long way for automatic generators and make you look like you can document like a machine! ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components#creating-instances) Creating Instances The _User.cfc_ component above is a representation of _any_ user or the _idea_ of a user. In order to bring it to life we will create an [**instance**arrow-up-right](https://en.wikipedia.org/wiki/Instance_(computer_science)) of it, populate it with instance data and then use it. An instance, is a copy of that blueprint that you are bringing to life that will be stored in memory and used by the language during a set of executions. Usually via a `new` or `createObject()` keyword operation from another file, which can be a template or yet another component. Copy // Create a new instance of the User class user = new User( name="luis" ); // execute a function within it user.run(); * See [https://cfdocs.org/newarrow-up-right](https://cfdocs.org/new) and [https://cfdocs.org/createobjectarrow-up-right](https://cfdocs.org/createobject) Please note that the `new` keyword will automatically call an object's constructor: the `init()` method. The `createObject()` will not, you will have to call the constructor manually: Copy user = createObject( "component", "User" ).init(); In later chapters we will investigate the concept of [dependency injection](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection) . Please also note that the `createObject()` function can also be used to create different types of objects in CFML like: * Components * Webservices (WSDL based) * Java Objects * .NET assemblies * COM Objects * Corba [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components#constructors) Constructors ----------------------------------------------------------------------------------------------------- Every object in theory should have a constructor method or a method that initializes the object to a **ready** state. Even if the constructor is empty, get into the habit of creating one. Copy function init(){ // prepare object state, cache data, start the engines return this; } Note that the constructor returns the `this` scope. This is a reference of the object itself that is returned. You can also return `this` from **ANY** other function which allows for expressive or fluently chainable methods. Copy function setValue( required val ){ variables.value = arguments.val; return this; } obj .setValue( 'myvalue' ) .setValue( 'otherValue' ); By default when using the `new Object()` operator, the Object's `init()` function will be called for you automatically. If you use the `createObject()` then the `init()` is NOT called automatically for you, you will call it explicitly. Copy // Implicit Constructor var obj = new Object(); // Explicit Constructor var obj = createObject( "component", "Object" ).init(); ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components#pseudo-constructor) Pseudo-Constructor The pseudo-constructor can be found in use in CFML and it's a unique beast. Any source code that exists between the `cfcomponent` declaration and the first function is considered to be the pseudo-constructor. This area of execution will be executed for you implicitly whenever the object is created, even before the implicit `init()` method call. I know confusing, but here is a simple sequence: `new()/createObject() -> pseudo-constructor -> init()` Copy component{ // Pseudo Constructor starts here this.helper = now(); static { staticVar : 2 }; // Pseudo Constructor ends here function init(){ return this; } } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components#component-scopes) Component Scopes ------------------------------------------------------------------------------------------------------------- Every component has certain visibility scopes where properties, variables and functions are attached to. * `variables` - Private scope, visible internally to the CFC only, where all `properties` are placed in by default. Public and private function references are place here as well. * `this` - Public scope, visible from the outside world (can break encapsulation) public function references are placed here. * `static` - Same as in Java, ability to staticly declare variables and functions at the blueprint level and not at the instance level. (Lucee only) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components#component-attributes) Component Attributes --------------------------------------------------------------------------------------------------------------------- The `component` construct can also have many attributes or name-value pairs that will give it some extra functionality for SOAP/REST web services and for Hibernate ORM Persistence. Each CFML engine provides different capabilities. You can find all of them here: [https://cfdocs.org/cfcomponentarrow-up-right](https://cfdocs.org/cfcomponent) . Below are the most common ones: * `accessors` - Enables automatic getters/setters for properties * `extends` - Provides inheritance via the path of the Component (CFC) * `implements` - Names of the interfaces it implements * `persistent` - Makes the object a Hibernate Entity which can be fine tuned through a slew of other attributes. * `serializable` - Whether the component can be serialized into a string/binary format or not. Default is `true`. Copy component accessors="true" serializable="false" extends="BaseUser"{ } component implements="cachebox.system.cache.ICacheProvider"{} Please note that in CFML you can also declare these attributes via annotations in the comments section, weird, I know! Copy /** * My User * @extends BaseUser * @accessors true * @serializable true */ component{ } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/components#undefined) ------------------------------------------------------------------------------------ [PreviousException Managementchevron-left](https://modern-cfml.ortusbooks.com/cfml-language/exception-management) [NextPropertieschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/components/properties) Last updated 2 years ago Was this helpful? --- # Variables | Learn Modern ColdFusion in 100 Minutes In CFML, variables are just pointers to a piece of data. They can hold **any** value you like and even change their value or **type** at runtime. In some languages, you need to specify the type of data you want your variable to hold at compile-time. You do not need to assign one in CFML, as everything is dynamic or inferred. The Lucee and Adobe 2021 servers infer types according to the initial value you assign to your variable. Copy a = "string"; // string b = now(); // datetime c = 123; // integer d = 1.34; // float f = false; // boolean, or a string for Adobe :) triangle-exclamation Please note that assignments are evaluated from right to left instead of traditional reading from left to right. Open up the CommandBox Shell and go into CommandBox **REPL** mode by typing `repl`. Every time you assign a value to a variable, the CommandBox REPL will output or echo the variable for you. Please note that in REPL mode, the termination for a line of code is omitted. A line terminator in ColdFusion is the `;`. ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252Fsync%252Ff7bb95597acc9015b6a483dc78be3ba38d47d2a2.png%3Fgeneration%3D1627309017547989%26alt%3Dmedia&width=768&dpr=3&quality=100&sign=8321a765&sv=2) As you can see, we can create [strings](https://modern-cfml.ortusbooks.com/cfml-language/strings) , [numerics](https://modern-cfml.ortusbooks.com/cfml-language/numbers) , [arrays](https://modern-cfml.ortusbooks.com/cfml-language/arrays) , [structs](https://modern-cfml.ortusbooks.com/cfml-language/structures) , and so much more. No need for types or special assignments. The ColdFusion engine will determine or infer it and use it accordingly, thus a dynamic language. circle-check The CommandBox REPL is based on a Lucee 5 server, which is why semi-colons are optional, and the default syntax is script and not tags. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#case-insensitive) Case Insensitive ------------------------------------------------------------------------------------------------------------ **CFML is a case-insensitive language** as well. Meaning if you create a variable `a` and reference it as `A` they are the same. This can be a big gotcha for developers from languages like Java or JavaScript. However, as best practice, we would recommend **ALWAYS** using the same case as when you define the variable: **Don't do this** Copy a = "Hola Luis"; writeOutput( A ); **Do this** Copy a = "Hola Luis"; writeOutput( a ); [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#naming-requirements) Naming Requirements ------------------------------------------------------------------------------------------------------------------ Most CFML variables have a few requirements imposed by the Virtual Machine (VM) * It must begin with a letter, underscore, or Unicode currency symbol. * It can contain letters, numbers, underscore characters, and Unicode currency symbols. * NO SPACES! * Not case-sensitive #### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#reserved-words) Reserved Words As with any programming language, there are specific names you just can't use, and some you can use, but they can be very confusing for developers or the engine. Here is a list of some of those: * The name of any of the internal ColdFusion engine scopes: `form, session, cgi, client, url, application, function` * Technically you can create the variable by long scoping (`local.form`), but it is confusing and error-prone. So please be careful. Reserved Word Lucee Adobe `abstract` √ `and` √ `break` √ `case` √ `catch` √ `continue` √ `contains` √ `default` √ `do` √ `else` √ `eq` √ `eqv` √ `false` √ √ `finally` √ `final` √ `for` √ `function` √ `gt` √ `gte` √ `import` √ `imp` √ `in` √ `is` √ `if` √ `interface` √ `lt` √ `lte` √ `local` (within a function) √ `neq` √ `not` √ `null` (If null support is on) √ √ `pageenconding` √ `or` √ `return` v `switch` √ `true` √ √ `try` √ `while` √ `xor` √ [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#flexible-typing) Flexible Typing ---------------------------------------------------------------------------------------------------------- You can also create a variable with one type and then switch it to another dynamically: ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252Fsync%252Ff8f3a7a5599ec4cb8445abf1decd7b7f5e78dbed.png%3Fgeneration%3D1627309017726957%26alt%3Dmedia&width=768&dpr=3&quality=100&sign=8e449a45&sv=2) As you can see, the last equality wins! In this case, `a` is now an array. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#types) Types -------------------------------------------------------------------------------------- As we are now seeing, CFML is a typeless language, but internal types always exist. CFML will automatically cast so you can do flexible typing assignments when evaluating expressions. It does all the tedious and hard job for you. If we were to categorize CFML variables into categories, these would be: Category Description **Binary** Raw data from files such as images, pdfs, etc **Complex** A data container that represents more than one value: structures, arrays, queries, XML document objects, etc. **Objects** Complex constructs representing data and functional operations. ColdFusion Components or Java Objects. **Simple** One value and used directly in expressions. These include numbers, strings, floats, booleans, and date-time values. CFML also includes many validation functions available to you to test for the type of variable you are working with. You can also use the `getmetdata()` function to get the metadata about the variable as well. Copy qData = getMetadata( query ) a = now() writedump( a.getMetadata() ) * `isArray()` * `isBinary()` * `isBoolean()` * `isCustomFunction()` * `isClosure()` * `isDate()` * `isDateObject()` * `isDDX()` * `isJSON()` * `isNumeric()` * `isNumericDate()` * `isObject()` * `isNull()` * `isPDFFile()` * `isPDFObject()` * `isQuery()` * `isSimpleValue()` * `isSpreadsheetFile()` * `isSpreadsheetObject()` * `isStruct()` * `isWDDX()` * `isXML()` * `isXmlDoc()` ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#conversions) Conversions You can also in CFML convert variables from one type to another. Here are some functions that will assist you in conversions: * `arrayToList()` * `binaryDecode()` * `binaryEncode()` * `charsetDecode()` * `charsetEncode()` * `deserializeJSON()` * `entityToQuery()` * `hash()` * `hmac()` * `HTMLParse()` * `lcase()` * `listToArray()` * `parseNumber()` * `serializeJSON()` * `toBase64()` * `toBinary()` * `toScript()` * `toString()` * `URLDecode()` * `URLEncode()` * `URLEncodedFormat()` * `val()` * `XMLFormat()` * `XMLParse()` * `XMLTransform()` circle-info Please note that some of them can be used as member functions directly on a specific object type. [https://cfdocs.org/conversion%2Dfunctionsarrow-up-right](https://cfdocs.org/conversion%2Dfunctions) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#outputting-variables-interpolation) Outputting Variables (Interpolation) -------------------------------------------------------------------------------------------------------------------------------------------------- You can also output or evaluate variables by using the `#` operators and using the variable name. This is referred to as interpolation in some languages: Copy a = "Hola Luis" writeoutput( "Welcome to CFML: #a#" ) // Echo is the same as writeOutput but LUCEE only echo( "Welcome" ) Also, note that using the `#` hashes for output on assignments can be redundant if you do NOT use string interpolation but just variable assignments. **Don't do this** Copy a = "hello luis"; b = #a#; or b = "#a#"; **Do this** Copy a = "hello luis"; b = a; [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#debugging-variables) Debugging Variables ------------------------------------------------------------------------------------------------------------------ CFML offers one of the most used functions/tags ever: `, writeDump()` and `, abort;`. These are used to dump the entire contents of a variable to the browser, console, or even a file. You can then leverage the `abort` construct to abort the request and see the output of your dumped variables. This will work with both simple and complex variables. However, be very careful when using it with Nested ORM objects, as you can potentially dump your entire database and crash the server. Leverage the `top` argument to limit dumping. Copy writeDump( complex );abort; writeDump( var=arrayOfORM, top=5 );abort; ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#server-debugging-templates) Server Debugging Templates CFML Engines also allow you to turn on/off a debugging template that shows up at the bottom of requests when running in server mode. You can activate this debugging by logging in to the appropriate engine administrator and looking for the **debugging** section. Turn it on and debug like a champ. triangle-exclamation **Important:** Adobe Engines have a very evil setting called _Report Execution Times_, make sure it is always turned **OFF**. If you use it with any application that leverages Components, it will slow down your application tremendously. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#paraming-variables) Paraming Variables ---------------------------------------------------------------------------------------------------------------- CFML allows you to set default values for variables in case you use a variable that doesn't exist. You can use the `` tag or the `param` construct: Copy or Copy param myVariable = "luis"; circle-check You can even assign types to parameterize variables and much more. Check out the docs for it: [https://cfdocs.org/cfparamarrow-up-right](https://cfdocs.org/cfparam) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#checking-for-existence) Checking For Existence ------------------------------------------------------------------------------------------------------------------------ You can verify if variables exist in many different ways. The following section showcases how variables are stored in visibility and persistence scopes which are all structures or hash maps in Java terms. Meaning you can leverage structure operations for checking for existence and much more. Below are several ways to verify variable existence: * `isDefined()` - Evaluates a string value to determine whether the variable named in it exists. * `isNull()` - Returns `true` if the specified object is null, else `false`. * `structKeyExists( key, value )` - Verifies if the specified key variable exists in a structure. Copy // Notice the variable name is in quotes if( isDefined( "myVariable" ) ){ writeOutput( myVariable ); } else { writeOutput( "Not Defined!" ); } // Notice that the variable is NOT in quotes if( isNull( myVariable ) ){ writeOutput( "Not Defined!" ); } else { writeOutput( myVariable ); } // What is this variables scopes??? if( structKeyExists( variables, "myVariable" ) ){ writeOutput( myVariable ); } else { writeOutput( "Not Defined!" ); } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#java-integration) Java Integration ------------------------------------------------------------------------------------------------------------ As we have discussed, CFML is a dynamic language built on Java. Thus each variable internally is represented by a native Java data type: `String, Int, Float, Array, Vector, HashMap, etc`. This is important because each variable you create has member functions available to you that delegate or reflect its native Java class. Copy a = "hello"; writeOutput( a.getClass().getName() ); If you run the script above in the REPL tool, you will see the output as `java.lang.String`. Therefore, the variable is typed as a `String` and can call on any method that `java.lang.String` implements. You can try this for the many types in CFML, like structs, arrays, objects, etc. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#member-functions) Member Functions ------------------------------------------------------------------------------------------------------------ Besides the native Java member functions available to you, CFML also allows you to call on each variable's data type functions and chain them to create friendly language DSLs. This way, you do not have to pass variables into functions but treat the variables as objects. You can see all the member functions available according to data type here: [https://cfdocs.org/memberarrow-up-right](https://cfdocs.org/member) Here are some examples: Copy // Function passing var myArray = []; ArrayAppend( myArray, "objec_new" ); ArraySort( myArray, "ASC" ); // Member Functions myArray.append( "objec_new" ); myArray.sort( "ASC" ); // Java Functions + CFML Functions var myProductObject = createObject( "java", "myJavaclass" ); myjavaList = myProductObject.getProductList(); myjavaList.add( "newProduct" ); // Java API myjavaList.append( "newProduct" ); // CF API myjavaList.sort( "ASC" ); // DSL Chaining s="the"; s = s.listAppend("quick brown fox", " ") .listAppend("jumps over the lazy dog", " ") .ucase() .reverse(); #### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#member-functions-for-the-following-data-types-are-supported) Member functions for the following data types are supported: * Array * String * List * Struct * Date * Spreadsheet * XML * Query * Image Please see [https://cfdocs.org/memberarrow-up-right](https://cfdocs.org/member) for further information on member functions. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/variables#naming-coding-standards) Naming Coding Standards -------------------------------------------------------------------------------------------------------------------------- At [Ortus Solutionsarrow-up-right](https://www.ortussolutions.com/) , we have developed a set of development standards for many languages. You can find our ColdFusion standards here: [https://github.com/Ortus-Solutions/coding-standardsarrow-up-right](https://github.com/Ortus-Solutions/coding-standards) [PreviousCommentschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/comments) [NextVariable Scopeschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/variable-scopes) Last updated 3 years ago Was this helpful? --- # Application.cfc | Learn Modern ColdFusion in 100 Minutes [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/applicationcfc#introduction) Introduction ---------------------------------------------------------------------------------------------------------- If you are running ColdFusion in a [web server like CommandBoxarrow-up-right](https://commandbox.ortusbooks.com/embedded-server) and a ColdFusion page (.cfm/.cfc) is requested, the engine will look for a special file called `Application.cfc` and if found, it will execute it for you **implicitly**. This file is used to define the following: 1. Application-wide settings, default variables, session/client storages, file mappings, datasources, style settings, ORM settings and so much more. These are created by placing them in the `this` scope and in the pseudo-constructor of the object. 2. Application **life-cycle** event handlers which the engine will execute for you **implicitly** by you just creating the appropriate available methods. circle-info Usually you will place this file in your **webroot**. Any page in the same directory or sub-directories that is requested will execute this file implicitly. ### [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/applicationcfc#transient-file) Transient File This file is created on every request, so make sure that it is optimized accordingly. The `application` scope can be leveraged for global persistence. Also note, that because it is instantiated on every request, you have the potential to change settings and events on a per-request basis if needed. Great use cases for this can be the following: * Switching datasources * Lowering session/client timeouts for scopes if a bot is requesting a page * Increased security * Stopping requests * Much More... circle-exclamation Please note that this file is execute for every request, so make sure it is optimized accordingly. The engine will also traverse your directories upwards until it finds this file. ### [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/applicationcfc#sample-template) Sample Template Application.cfc Copy component{ this.name = "My Awesome App"; this.applicationTimeout = createTimeSpan( 30, 0, 0, 0 ); //30 days this.sessionStorage = true; this.sessionTimeout = createTimeSpan( 0, 0, 60, 0 ); // 1 hour function onApplicationStart(){} function onApplicationEnd( struct applicationScope ) {} function onSessionStart() {} function onSessionEnd( struct sessionScope, struct applicationScope ) {} function onRequestStart( string targetPage ) {} function onRequest( string targetPage ) { include arguments.targetPage; } function onRequestEnd() {} function onCFCRequest( cfcname, method, struct args) { return; } function onError( any Exception, string EventName ) {} function onAbort( required string targetPage ) {} function onMissingTemplate( required string targetPage ) {} } circle-info You can find all the settings and event handlers defined for `Application.cfc` in cfdocs: [https://cfdocs.org/application-cfcarrow-up-right](https://cfdocs.org/application-cfc) . [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/applicationcfc#life-cycle-events) Life-Cycle Events -------------------------------------------------------------------------------------------------------------------- The `Application.cfc` also acts like a big event listener waiting for the ColdFusion server engine to call its methods in callback fashion. You can listen to when an error occurs to even when a missing template is requested and much more. If I am missing some here, please refer to the latest documentation for the latest updates: [https://cfdocs.org/applicationarrow-up-right](https://cfdocs.org/application) * **onApplicationStart**: The very first time your application is requested, the `onApplicationStart` event is broadcast. It only happens once, until your application times out, the process is restarted, or the computer is restarted. * **onSessionStart**: Whenever a NEW user requests any resource in your web application ColdFusion will assign them a unique session identifier and call this method for you. * **onRequestStart**: Executes before every requested resource and receives the targeted page in the arguments. You can decide to process the page or not by returning a boolean variable. * **onRequest**: This callback allows you to actually include the requested page or not. Consider the `onRequestStart()` as a before advice and the `onRequest` as an around advice over the request. You must `include` the requested page or the page will never be processed * **onRequestEnd**: Also receives the targetPage and executes after onRequestStart() and onRequest() have fired. * **onSessionEnd**: Once a unique session has expired this method will be called for you by the engine with the session and application scope structure as arguments. * **onApplicationEnd**: Once the application times out or is flushed you can listen to it. It also accepts the entire application scope as an incoming argument. * **onError**: Like a big try/catch statement across the application. This will fire whenever an untrapped exception is caught. You will receive the exception struct and the `eventName` that generated the exception. * **onAbort:** Runs when you execute the abort tag somewhere and you want to know where that pesky abort exists. It receives the `targetPage` that the abort came from. * **onCFCRequest**: Intercepts any HTTP or AMF calls to an application based on CFC request. * **onMissingTemplate**: Executed whenever a template is requested and it does not exist in the server. circle-info The [ColdBox HMVC Frameworkarrow-up-right](https://www.coldbox.org/) builds heavily on top of these life-cycle methods to provide you with a rich event-driven architecture for web applications. You can create an application with CommandBox just by running: `coldbox create app MyApp` [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/applicationcfc#coldfusion-web-applications) ColdFusion Web Applications ---------------------------------------------------------------------------------------------------------------------------------------- ColdFusion differs from other Java web languages in the sense that there is one Java context application deployed (The CFML Engine) with many servlet definitions, but you can create many ColdFusion applications within the running context. All you need is to demarcate them with the `Application.cfc`, with a unique name which defines the separate ColdFusion applications. **Anything in that directory and sub-directories will be considered part of the application.** Your ColdFusion application is nothing more than a memory space reservation using the `this.name` property as the unique name for it. It can contain the variables scopes like `application`, `session`, and `client` which are unique per this reservation name. This way two ColdFusion applications can have different persistence variable scopes and can even be embedded between each other: Copy + webroot + admin/ + Application.cfc // Embedded admin app + Application.cfc // Root public app ### [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/applicationcfc#application-longevity) Application Longevity This is why you can't really kill the `application` scopes. The application is reserved for a specific duration which is defined using the `this.applicationTimeout` property or defined in the Administrator. Once it expires, the engine will purge it from memory and recreate it fresh. circle-check **Tip** You can force the stopping of the Application scope by leveraging the method `applicationStop()`. Be careful though, as it stops full execution and restarts it. ([https://cfdocs.org/applicationstoparrow-up-right](https://cfdocs.org/applicationstop) ) [PreviousBeyond The 100chevron-left](https://modern-cfml.ortusbooks.com/beyond-the-100/beyond-the-language) [NextFile Handlingchevron-right](https://modern-cfml.ortusbooks.com/beyond-the-100/file-handling) Last updated 2 years ago Was this helpful? --- # Arrays | Learn Modern ColdFusion in 100 Minutes Almost every programming language allows you to represent different types of collections. In CFML, we have three types of collections: arrays, [structures](https://modern-cfml.ortusbooks.com/cfml-language/structures) , and [queries](https://modern-cfml.ortusbooks.com/cfml-language/queries) . An array is a number-indexed list. Imagine you had a blank piece of paper and drew a set of three small boxes in a line: Copy --- --- --- | || || | --- --- --- You could number each one by its position from left to right: Copy --- --- --- | || || | --- --- --- 1 2 3 Then put strings in each box: Copy ------------- --------- ---------- | "Breakfast" || "Lunch" || "Dinner" | ------------- --------- ---------- 1 2 3 We have a three-element Array. CFML arrays can grow and shrink dynamically at runtime, just like Array Lists or Vectors in Java, so if we added an element, it’d usually go on the end or be appended at the end. Copy ------------- --------- ---------- ----------- | "Breakfast" || "Lunch" || "Dinner" || "Dessert" | ------------- --------- ---------- ----------- 1 2 3 4 If you asked the array for the element in position two, you’d get back `Lunch`. Ask for the last element, and you’d get back: `Dessert`. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#the-story-of-one) The Story of One --------------------------------------------------------------------------------------------------------- Now, have you detected something funny with the ordering of the elements? Come on, look closer....... They start with `1` and not `0`, now isn't that funny. CFML is one of the few languages where array indexes start at `1` and not `0`. So if you have a PHP, Ruby, or Java background, remember that `1` is where you start. Is this good or bad? Well, we will refrain from pointing fingers for now. circle-info All CFML arrays in Adobe ColdFusion are passed by values, while in Lucee, they are **passed by reference**. Please remember this when working with arrays and passing them to functions. There is also the `passby=reference|value` attribute to function arguments where you can decide whether to pass by reference or value. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#arrays-in-code) Arrays in Code ----------------------------------------------------------------------------------------------------- Let's go ahead and model some code in CFML using our fancy REPL tool CommandBox: ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LA-UbMqUYOVVZvx_rxu%252F-LA-UoqWcqEVkZYuctRY%252Farrays_in_code.png%3Fgeneration%3D1523647994794760%26alt%3Dmedia&width=768&dpr=3&quality=100&sign=42ea5c16&sv=2) Check it out: * The array was created by putting pieces of data between square brackets (`[]`) and separated by commas * We added an element to the array using the member function `append()` * We fetched the element at a specific position by using square brackets (`[ x ]`) and replaced `x` with the index, we wanted * We retrieved the size of the array by using the member function `len()` * We searched the contents of the array using the member function `findNoCase()` , and it gave us the index position of the element in the array. Please note that all member functions can also be used as traditional [array functionsarrow-up-right](https://cfdocs.org/array-functions) . However, [member functionsarrow-up-right](https://cfdocs.org/member) do look so much better for readability. circle-check **Tip:** You can use the `toString()` call on any array to get a string representation of its values: `grid.toString()` [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#multi-dimensional-arrays) Multi-Dimensional Arrays ------------------------------------------------------------------------------------------------------------------------- To create grids or matrix constructs, you must create two-dimensional arrays. Basically, giving you an **x** and **y** axis of data. You will do so using the `arrayNew( dimensions = max 3 )` method: circle-check **Tip:** CFML only supports two and three-dimensional arrays, so you can easily represent x, y and z axis. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#common-methods) Common Methods ----------------------------------------------------------------------------------------------------- The best way to learn about using arrays is to check out the available [member functionsarrow-up-right](https://cfdocs.org/member) and [array functionsarrow-up-right](https://cfdocs.org/array-functions) . [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#typed-arrays) Typed Arrays ------------------------------------------------------------------------------------------------- CFML engines also allow you to create strongly typed arrays. This is useful if you want to determine the array's contents specifically. Similar to [genericsarrow-up-right](https://www.baeldung.com/java-generic-array) in Java. This is accomplished with a new construct but ONLY on Adobe Engines: This syntax will allow you to define that an array is of a certain type and how many dimensions. If you want to use typed arrays in Lucee, then you will have to declare it via the `ArrayNew()` method via the second argument: Different syntax than Adobe Engines: circle-exclamation Please note that the CFML engines will try to cast values automatically into the type defined by the array container. circle-info **Tip**: By default, all CFML arrays are _Unsynchronized_. That means they are not thread-safe when accessing the data from multiple threads or shared scopes. According to the CF2016 Performance whitepaper: Unsynchronized arrays are about 93% faster due to lock avoidance. So with much power comes much responsibility. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#array-types) Array Types The allowed types are: * Array * Binary * Boolean * Component * CFC by Name / SubType * Date / Datetime * Function * Numeric * Query * String * Struct ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#literal-syntax) Literal Syntax Adobe engines also support a way to do a declaration of a typed array using a literal syntax: This is a nice way to declare them literally: [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#negative-indices) Negative Indices --------------------------------------------------------------------------------------------------------- Adobe 2021+ and Lucee engines also support the concept of negative indices. This allows you to retrieve the elements from the end of the array backward. So you can easily count back instead of counting forwards: [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#array-slices) Array Slices ------------------------------------------------------------------------------------------------- Both CFML engines support the [slicingarrow-up-right](https://cfdocs.org/arrayslice) of an array via the `arraySlice()` method or the `slice()` member function, respectively. However, Adobe engines also support a slicing literal syntax that is really useful and expressive. It follows this syntax: This allows you to get sub-arrays easily with no looping necessary. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#looping-over-arrays) Looping Over Arrays --------------------------------------------------------------------------------------------------------------- You can use different constructs for looping over arrays: * `for` loops * `loop` constructs * `each()` closures ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#multi-threaded-looping) Multi-Threaded Looping Lucee and Adobe 2021 allow you to leverage the `each()` operations in a multi-threaded fashion. The `arrayEach()` or `each()` functions allow for a `parallel` and `maxThreads` arguments so the iteration can happen concurrently on as many `maxThreads` as supported by your JVM. This is incredibly awesome as now your callback will be called concurrently! However, please note that once you enter concurrency land, you should shiver and tremble. Thread concurrency will be of the utmost importance, and you must ensure that var scoping is done correctly and that appropriate locking strategies are in place when accessing shared scopes and/or resources. Even though this approach to multi-threaded looping is easy, it is not performant and/or flexible. Under the hood, the engines use a single thread executor for each execution, do not allow you to deal with exceptions, and if an exception occurs in an element processor, good luck; you will never know about it. This approach can be verbose and error-prone, but it's easy. You also don't control where the processing thread runs and are at the mercy of the engine. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#coldbox-futures-parallel-programming) ColdBox Futures Parallel Programming If you would like a functional and much more flexible approach to multi-threaded or parallel programming, consider using the ColdBox Futures approach (usable in ANY framework or non-framework code). You can use it by installing ColdBox or WireBox into any CFML application and leveraging our `async` programming constructs, which behind the scenes, leverage the entire Java Concurrency and Completable Futures frameworks. [![Logo](https://coldbox.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1096988991-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fspaces%252F-LA-UVvJIdbk5Kfk3bDs%252Favatar.png%3Fgeneration%3D1547216546996685%26alt%3Dmedia&width=48&height=48&sign=3b26690c&sv=2)Parallel Computations | ColdBox HMVC Documentationcoldbox.ortusbooks.comchevron-right](https://coldbox.ortusbooks.com/digging-deeper/promises-async-programming/parallel-computations) ColdBox Futures and Async Programming Here are some methods that will allow you to do parallel computations: * `all( a1, a2, ... ):Future` : This method accepts an infinite amount of future objects, closures, or an array of closures/futures to execute them in parallel. When you call on it, it will return a future that will retrieve an array of the results of all the operations. * `allApply( items, fn, executor ):array` : This function can accept an array of items or a struct of items of any type and apply a function to each of the items in parallel. The `fn` argument receives the appropriate item and must return a result. Consider this a parallel `map()` operation. * `anyOf( a1, a2, ... ):Future` : This method accepts an infinite amount of future objects, closures, or an array of closures/futures and will execute them in parallel. However, instead of returning all of the results in an array like `all()`, this method will return the future that executes the fastest! Race Baby! * `withTimeout( timeout, timeUnit )` : Apply a timeout to `all()` or `allApply()` operations. The `timeUnit` can be days, hours, microseconds, milliseconds, minutes, nanoseconds, and seconds. The default is milliseconds. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#spread-operator) Spread Operator ------------------------------------------------------------------------------------------------------- Arrays also allow the usage of the spread operator syntax to quickly copy all or part of an existing array or object into another array or object. This operator is used by leveraging three dots `...` in specific expressions. The Spread syntax allows an iterable such as an array expression or string, to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected. Here are some examples to help you understand this operator: #### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#function-calls) Function Calls #### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#array-definitions) Array Definitions [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#rest-operator) Rest Operator --------------------------------------------------------------------------------------------------- The rest operator is similar to the spread operator but behaves oppositely. Instead of expanding the literals, it contracts them into an array you designate via the `...{name}` syntax. You can use this to define endless arguments for a function, for example. In this case, I can create a dynamic `findBy` function that takes in multiple criteria name-value pairs. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/arrays#array-destructuring-acf2021) Array Destructuring (ACF2021+) ---------------------------------------------------------------------------------------------------------------------------------- Array destructuring is a very unique technique that allows you to extract an array's value(s) into new variables. Let's start first with how we would accomplish this without the destructuring syntax: This is useful, but let's use the destructuring syntax to simplify this: [PreviousNumberschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/numbers) [NextStructureschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/structures) Last updated 3 years ago Was this helpful? * [The Story of One](https://modern-cfml.ortusbooks.com/cfml-language/arrays#the-story-of-one) * [Arrays in Code](https://modern-cfml.ortusbooks.com/cfml-language/arrays#arrays-in-code) * [Multi-Dimensional Arrays](https://modern-cfml.ortusbooks.com/cfml-language/arrays#multi-dimensional-arrays) * [Common Methods](https://modern-cfml.ortusbooks.com/cfml-language/arrays#common-methods) * [Typed Arrays](https://modern-cfml.ortusbooks.com/cfml-language/arrays#typed-arrays) * [Array Types](https://modern-cfml.ortusbooks.com/cfml-language/arrays#array-types) * [Literal Syntax](https://modern-cfml.ortusbooks.com/cfml-language/arrays#literal-syntax) * [Negative Indices](https://modern-cfml.ortusbooks.com/cfml-language/arrays#negative-indices) * [Array Slices](https://modern-cfml.ortusbooks.com/cfml-language/arrays#array-slices) * [Looping Over Arrays](https://modern-cfml.ortusbooks.com/cfml-language/arrays#looping-over-arrays) * [Multi-Threaded Looping](https://modern-cfml.ortusbooks.com/cfml-language/arrays#multi-threaded-looping) * [ColdBox Futures Parallel Programming](https://modern-cfml.ortusbooks.com/cfml-language/arrays#coldbox-futures-parallel-programming) * [Spread Operator](https://modern-cfml.ortusbooks.com/cfml-language/arrays#spread-operator) * [Rest Operator](https://modern-cfml.ortusbooks.com/cfml-language/arrays#rest-operator) * [Array Destructuring (ACF2021+)](https://modern-cfml.ortusbooks.com/cfml-language/arrays#array-destructuring-acf2021) Was this helpful? Copy grid = arrayNew( 2 ); grid[ 1 ][ 1 ] = 'Hammer'; grid[ 1 ][ 2 ] = 'Nail'; grid[ 2 ][ 1 ] = 'Screwdriver'; grid[ 1 ][ 2 ] = 'Screw'; Copy // Sort an array meals.sort( "textnocase" ); // Clear the array meals.clear(); // Go on a diet meals.delete( "Dessert" ); meals.deleteAt( 4 ); // Iterate meals.each( function( element, index) { systemOutput( element & " " & index ); } ); // Filter an array meals.filter( function( item ){ return item.findNoCase( "unch" ) gt 0 ? true : false; } ); // Convert to a list meals.toList(); // Map/ Reduce complexData = [ {a: 4}, {a: 18}, {a: 51} ]; newArray = arrayMap( complexData, function(item){ return item.a; }); writeDump(newArray); complexData = [ {a: 4}, {a: 18}, {a: 51} ]; sum = arrayReduce( complexData, function(prev, element) { return prev + element.a; }, 0 ); writeDump(sum); Copy Syntax: arrayNew[ type ]( dimensions ) Copy // array of strings stringArray = arrayNew[ "String" ]( 1 ) // array of numerics numericArray = arrayNew[ "Numeric" ]( 1 ) // array of User CFCs aUsers = arrayNew[ "User" ]( 1 ) Copy ArrayNew( dimension, type, synchronized:boolean ) Copy // array of strings stringArray = arraynew( 1, "String" ) // array of numerics numericArray = arraynew( 1, "Numeric" ) // array of User CFCs aUsers = arraynew( 1, "User" ) Copy [ type ][ elem1, elem2, .. elemN ] Copy stringArray = [ 'String' ][ 1, "Word1", "Word2" ] writeDump( stringArray ) Copy numbers = [1,2,3,4,5] writedump( numbers[ -1 ] ) // 5 writedump( numbers[ -2 ] ) // 4 writedump( numbers[ -3 ] ) // 3 writedump( numbers[ -4 ] ) // 2 writedump( numbers[ -5 ] ) // 1 writedump( numbers[ -6 ] ) // EXCEPTION!!! Array index out of range Copy Syntax: array[ from : to : step:1 ] Copy fruits = [ "apple", "orange", "pear", "grape" ] writedump( fruits[:] ) // Dump all fruits writedump( fruits[ 1: -1 ] ) // Dump all fruits too // Dump all fruits too but in increments of two items not 1. writedump( fruits[ 1: -1 : 2 ] ) // dumps apple and pear // Items in reverse writedump( fruits[ -1:1:-1 ] ) Copy for( var thisMeal in meals ){ systemOutput( "I just had #thisMeal#" ); } for( var x = 1; x lte meals.len(); x++ ){ systemOutput( "I just had #meals[ x ]#" ); } meals.each( function( element, index ){ systemOutput( "I just had #element#" ); } ); cfloop( from=1, to=meals.len(), index=x ){ systemOutput( "I just had #meals[ x ]#" ); } Copy arrayEach( array, callback, parallel:boolean, maxThreads:numeric ); each( collection, callback, parallel:boolean, maxThreads:numeric ); Copy myArray.each( function( item ){ myservice.process( item ); }, true, 20 ); Copy // Let's find the fastest dns server var f = asyncManager().anyOf( ()=>dns1.resolve(), ()=>dns2.resolve() ); // Let's process some data var data = [1,2, ... 100 ]; var results = asyncManager().all( data ); // Process multiple futures var f1 = asyncManager.newFuture( function(){ return "hello"; } ); var f2 = asyncManager.newFuture( function(){ return "world!"; } ); var aResults = asyncManager.newFuture() .withTimeout( 5 ) .all( f1, f2 ); // Process mementos for an array of objects function index( event, rc, prc ){ return async().allApply( orderService.findAll(), ( order ) => order.getMemento() ); } Copy numbers = [ 1, 2, 3 ] function sum( x, y, z ){ return x + y + z; } // Call the function using the spread operator results = sum( ...numbers ) // 6 // Ignore the others numbers = [ 1, 2, 3, 4, 5 ] results = sum( ...numbers ) // 6 Copy numbers = [ 1, 2, 3 ] myArray = [ 3, 4, ...numbers ] myArray2 = [ ...numbers ] myArray2 = [ ...numbers, 4, 66 ] Copy function findBy( ...args ){ writeDump( args ) } findBy( 1, 2, 3, 4, 5 ) function findBy( entityName, ...args ){ writeDump( args ) } findBy( "Luis", 1, 2, 3, 4, 5 ) Copy kids = [ "alexia", "lucas", "matias", "isabella" ] // Assign an array's value into a new variable k1 = kids[ 1 ] k2 = kids[ 2 ] k3 = kids[ 3 ] writeDump( k1 ) writeDump( k2 ) writeDump( k3 ) Copy kids = [ "alexia", "lucas", "matias", "isabella" ] // Destructure by assignment via an array // Each item in the array is a new variable in the variables scope [ k1, k2, k3, k4 ] = kids writeDump( k1 ) writeDump( k2 ) writeDump( k3 ) writeDump( k4 ) --- # Database Queries | Learn Modern ColdFusion in 100 Minutes CFML became famous in its infancy because it was easy to query databases with a simple `cfquery` tag and no verbose ceremonious coding. There is no ceremony, just a plain datasource definition in the administrator, and we could easily query the database. In modern times, we have many more ways to query the database, and defining data sources can occur not only in the admin but in our web application's `Application.cfc` or even define it at runtime programmatically or within the query constructs themselves. circle-info See [Application.cfc](https://modern-cfml.ortusbooks.com/beyond-the-100/applicationcfc) for more information on how to leverage it for web development. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#what-is-a-datasource) What is a Datasource? ------------------------------------------------------------------------------------------------------------------- A datasource is a **named** connection to a specific database with specified credentials. You can define an infinite amount of data sources in your CFML applications in the following locations: * Global ColdFusion Engine (Adobe or Lucee) Administrator * **Adobe** : `http://localhost:port/CFIDE/adminstrator` * **Lucee**: `http://localhost:port/lucee/admin/server.cfm` * The `Application.cfc`, which will dictate the data sources for that specific ColdFusion application * Inline in `cfquery` or `queryexecute` calls The datasource is then used to control the database's connection pool and allow the ColdFusion engine to execute JDBC calls against it. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#what-is-a-query) What is a query? --------------------------------------------------------------------------------------------------------- A query is a request to a database representing the results' rows and columns. It returns a CFML `query` object containing a **record set** and other metadata information about the query. The query can ask for information from the database, write new data to the database, update existing information in the database, or delete records from the database. This can be done in several ways: * Using the `cfquery` tag. ([https://cfdocs.org/cfqueryarrow-up-right](https://cfdocs.org/cfquery) ) * Using the `queryExecute()` function. ([https://cfdocs.org/queryexecutearrow-up-right](https://cfdocs.org/queryexecute) ) circle-info In Lucee, a query is backed by the following class: `lucee.runtime.type.QueryImpl` In Adobe, a query is backed by the following class: `coldfusion.sql.QueryTable` circle-check If you are using **Lucee**, the datasource can even be defined inline. So instead of giving the name of the `datasource` it can be a `struct` definition of the datasource you want to connect to, just like the struct in `Application.cfc` [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#default-datasource) Default Datasource -------------------------------------------------------------------------------------------------------------- You can also omit the `datasource` completely from query calls, and CFML will use the one defined in `Application.cfc` as the **default** datasource connection. This is a great way to encapsulate the datasource in a single location. However, we all know that there could be some applications with multiple data sources; that's ok; at least you can have one by default. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#defining-datasources) Defining Datasources ------------------------------------------------------------------------------------------------------------------ If you want to use the ColdFusion Engine's administrators for registering data sources, you must visit each administrator's interfaces and follow their wizards. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#coldfusion-engine-administrator) ColdFusion Engine Administrator [https://docs.lucee.org/guides/cookbooks/datasource-define-datasource.htmldocs.lucee.orgchevron-right](https://docs.lucee.org/guides/cookbooks/datasource-define-datasource.html) [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fwww.adobe.com%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=40f989eb&sv=2)Data Source Management for ColdFusionhelpx.adobe.comchevron-right](https://helpx.adobe.com/coldfusion/configuring-administering/data-source-management-for-coldfusion.html) ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#application.cfc) `Application.cfc` You can also define the datasources in the `Application.cfc`, which is sometimes our preferred approach as the connections are versioned controlled and more visible than in the admin. You will do this by defining a struct called `this.datasources`. Each **key** will be the name of the datasource to register and the **value** of each key a struct of configuration information for the datasource. However, we recommend that you setup environment variables in order to NOT store your passwords in plain-text in your source code. circle-check For the inline approach, you will use the struct definition, as you see in the `Application.cfc` above and pass it into the `cfquery` or `queryexecute` call. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#portable-datasources) Portable Datasources You can also make your data sources portable from application to application or CFML engine to engine by using our [CFConfigarrow-up-right](https://cfconfig.ortusbooks.com/) project. CFConfig allows you to manage almost every setting that shows up in the web administrator, but instead of logging into a web interface, you can manage it from the command line by hand or as part of a scripted server setup. You can seamlessly transfer config for all the following: * CF Mappings * Data sources * Mail servers * Request, session, or application timeouts * Licensing information (for Adobe) * Passwords \-Template caching settings \-Basically any settings in the web based administrator You can easily place a `.cfconfig.json` in the web root of your project, and if you start up a CommandBox server on any CFML engine, CFConfig will transfer the configuration to the engine's innards: [![Logo](https://cfconfig.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1692063955-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fspaces%252F-LA-UVv7_78Z7jt-5fGx%252Favatar.png%3Fgeneration%3D1523647939878418%26alt%3Dmedia&width=48&height=48&sign=12fd14bd&sv=2)Command Overview | CFConfig Documentationcfconfig.ortusbooks.comchevron-right](https://cfconfig.ortusbooks.com/using-the-cli/command-overview) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#displaying-results) Displaying Results -------------------------------------------------------------------------------------------------------------- The query object can be iterated on like a normal collection through a `for, cfloop or cfoutput` , `each()` constructs. [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fcfdocs.org%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=12889214&sv=2)cfoutput Code Examples and CFML DocumentationCF Docschevron-right](https://cfdocs.org/cfoutput) [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fcfdocs.org%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=12889214&sv=2)cfloop Code Examples and CFML DocumentationCF Docschevron-right](https://cfdocs.org/cfloop) **In a CFM Template** You leverage the `cfoutput` tag by passing the `query` to it. Then in the block of the tag you use dot/array notation and interpolation to output the column you want. CFML will iterate over all rows in the query for you. circle-info By specifying `encodefor="html"` each variable is encoded using the `encodeForHTML` function before it is output. **Using Loops** As you can see, many ways to iterate over the query exist. Choose the approach that suits your needs. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#multi-threaded-looping) Multi-Threaded Looping Lucee and Adobe 2021+ allow you to leverage the `each()` operations in a multi-threaded fashion. The `queryEach()` or `each()` functions allow for a `parallel` and `maxThreads` arguments so the iteration can happen concurrently on as many `maxThreads` as supported by your JVM. This is incredibly awesome, as now your callback will be called concurrently! However, please note that once you enter concurrency land, you should shiver and tremble. Thread concurrency will be of the utmost importance, and you must ensure that var scoping is done correctly and that appropriate locking strategies are in place. Even though this approach to multi-threaded looping is easy, it is not performant and/or flexible. Under the hood, the engines use a single thread executor for each execution, do not allow you to deal with exceptions, and if an exception occurs in an element processor, good luck; you will never know about it. This approach can be verbose and error-prone, but it's easy. You also don't control where the processing thread runs and are at the mercy of the engine. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#coldbox-futures-parallel-programming) ColdBox Futures Parallel Programming If you would like a functional and much more flexible approach to multi-threaded or parallel programming, consider using the ColdBox Futures approach (usable in ANY framework or non-framework code). You can use it by installing ColdBox or WireBox into any CFML application and leveraging our `async` programming constructs, which behind the scenes, leverage the entire Java Concurrency and Completable Futures frameworks. [![Logo](https://coldbox.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1096988991-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fspaces%252F-LA-UVvJIdbk5Kfk3bDs%252Favatar.png%3Fgeneration%3D1547216546996685%26alt%3Dmedia&width=48&height=48&sign=3b26690c&sv=2)Parallel Computations | ColdBox HMVC Documentationcoldbox.ortusbooks.comchevron-right](https://coldbox.ortusbooks.com/digging-deeper/promises-async-programming/parallel-computations) ColdBox Futures and Async Programming Here are some methods that will allow you to do parallel computations: * `all( a1, a2, ... ):Future` : This method accepts an infinite amount of future objects, closures, or an array of closures/futures to execute them in parallel. When you call on it, it will return a future that will retrieve an array of the results of all the operations. * `allApply( items, fn, executor ):array` : This function can accept an array of items or a struct of items of any type and apply a function to each of the items in parallel. The `fn` argument receives the appropriate item and must return a result. Consider this a parallel `map()` operation. * `anyOf( a1, a2, ... ):Future` : This method accepts an infinite amount of future objects, closures, or an array of closures/futures and will execute them in parallel. However, instead of returning all of the results in an array like `all()`, this method will return the future that executes the fastest! Race Baby! * `withTimeout( timeout, timeUnit )` : Apply a timeout to `all()` or `allApply()` operations. The `timeUnit` can be days, hours, microseconds, milliseconds, minutes, nanoseconds, and seconds. The default is milliseconds. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#using-input) Using Input ------------------------------------------------------------------------------------------------ We usually won't have the luxury of simple queries; we will need user input to construct our queries. Here is where you need to be extra careful not to allow for [SQL injection.arrow-up-right](https://owasp.org/www-community/attacks/SQL_Injection) CFML has several ways to help you prevent SQL Injection, whether using tags or script calls. Leverage the `cfqueryparam` construct/tag ([https://cfdocs.org/cfqueryparamarrow-up-right](https://cfdocs.org/cfqueryparam) ) and always sanitize your input via the `encode` functions in CFML. You can use the `:varname` notation in your SQL construct to denote a **variable** placeholder or `?` to denote a **positional** placeholder. The `cfqueryparam` tag or the inline `cfsqltype` construct will bind the value to a specific database type to avoid SQL injection and to further the database explain plan via types. The available SQL binding types are: * `bigint` * `bit` * `char` * `blob` * `clob` * `nclob` * `date` * `decimal` * `double` * `float` * `idstamp` * `integer` * `longvarchar` * `longnvarchar` * `money` * `money4` * `nchar` * `nvarchar` * `numeric` * `real` * `refcursor` * `smallint` * `sqlxml` * `time` * `timestamp` * `tinyint` * `varchar` circle-exclamation Please note that the types can be prefixed with `cf_sql_{type}` or just used as `{type}`. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#query-methods) Query Methods ---------------------------------------------------------------------------------------------------- Several query methods are available in CFML that can help you manage queries and create them on the fly ([https://cfdocs.org/query-functionsarrow-up-right](https://cfdocs.org/query-functions) ). Please note that you can also use chaining and member functions as well. * `queryNew()` * `queryAddRow()` * `queryAddColumn()` * `queryColumnArray()` * `queryColumnCount()` * `queryColumnData()` * `queryColumnExists()` * `queryColumnList()` * `queryCurrentRow()` * `queryDeleteColumn()` * `queryDeleteRow()` * `queryEach()` * `queryEvery()` * `queryFilter()` * `queryGetCell()` * `queryGetResult()` * `queryGetRow()` * `queryMap()` * `queryRecordCount()` * `queryReduce()` * `queryRowData()` * `querySetCell()` * `querySlice()` * `querySome()` * `querySort()` * `quotedValueList()` * `valueList()` [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#building-queries) Building Queries ---------------------------------------------------------------------------------------------------------- You can use a combination of the methods above to create your own queries: [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#query-of-queries) Query of Queries ---------------------------------------------------------------------------------------------------------- Query a local database variable without going through your database is another great way to query an already queried query. Too many queries? Please note that using a query of queries can be quite slow sometimes, not all the time. An alternative approach is to use modern `queryFilter()` operations to actually filter out the necessary data from a query or `querySort()`, etc. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#returning-arrays-of-structs-or-struct-of-structs) Returning Arrays of Structs or Struct of Structs -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- In Lucee and Adobe 2021+, you can also determine the return type of database queries as something other than the CFML query object. You can choose an array of structs or a struct of structs. This is fantastic for modern applications that rely on rich JavaScript frameworks and produce JSON. This is achieved by passing the `returntype` attribute within the query options or just an attribute of the `cfquery` tag ([https://cfdocs.org/cfqueryarrow-up-right](https://cfdocs.org/cfquery) ) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/queries#qb-query-builder) QB = Query Builder ------------------------------------------------------------------------------------------------------------ We have created a fantastic module to deal with queries in a fluent and elegant manner. We call it **QB** short for **q**uery **b**uilder ([https://www.forgebox.io/view/qbarrow-up-right](https://www.forgebox.io/view/qb) ). You can install it using CommandBox into your application by just saying: Using qb, you can: * Quickly scaffold simple queries * Make complex, out-of-order queries possible * Abstract away differences between database engines You can find all the documentation in our Ortus Books docs: [http://qb.ortusbooks.com/arrow-up-right](http://qb.ortusbooks.com/) [PreviousStructureschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/structures) [NextConditionalschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/conditionals) Last updated 3 years ago Was this helpful? * [What is a Datasource?](https://modern-cfml.ortusbooks.com/cfml-language/queries#what-is-a-datasource) * [What is a query?](https://modern-cfml.ortusbooks.com/cfml-language/queries#what-is-a-query) * [Default Datasource](https://modern-cfml.ortusbooks.com/cfml-language/queries#default-datasource) * [Defining Datasources](https://modern-cfml.ortusbooks.com/cfml-language/queries#defining-datasources) * [ColdFusion Engine Administrator](https://modern-cfml.ortusbooks.com/cfml-language/queries#coldfusion-engine-administrator) * [Application.cfc](https://modern-cfml.ortusbooks.com/cfml-language/queries#application.cfc) * [Portable Datasources](https://modern-cfml.ortusbooks.com/cfml-language/queries#portable-datasources) * [Displaying Results](https://modern-cfml.ortusbooks.com/cfml-language/queries#displaying-results) * [Multi-Threaded Looping](https://modern-cfml.ortusbooks.com/cfml-language/queries#multi-threaded-looping) * [ColdBox Futures Parallel Programming](https://modern-cfml.ortusbooks.com/cfml-language/queries#coldbox-futures-parallel-programming) * [Using Input](https://modern-cfml.ortusbooks.com/cfml-language/queries#using-input) * [Query Methods](https://modern-cfml.ortusbooks.com/cfml-language/queries#query-methods) * [Building Queries](https://modern-cfml.ortusbooks.com/cfml-language/queries#building-queries) * [Query of Queries](https://modern-cfml.ortusbooks.com/cfml-language/queries#query-of-queries) * [Returning Arrays of Structs or Struct of Structs](https://modern-cfml.ortusbooks.com/cfml-language/queries#returning-arrays-of-structs-or-struct-of-structs) * [QB = Query Builder](https://modern-cfml.ortusbooks.com/cfml-language/queries#qb-query-builder) Was this helpful? Copy // Tag syntax SELECT QUANTITY, ITEM FROM CUPBOARD ORDER BY ITEM // script syntax qItems = queryExecute( "SELECT QUANTITY, ITEM FROM CUPBOARD ORDER BY ITEM" ); // Lucee datasource inline definition queryExecute( "SELECT * FROM Employees WHERE empid = ? AND country = ?", // sql [ 1, "USA" ], // params { // options datasource : { class : "com.microsoft.sqlserver.jdbc.SQLServerDriver", connectionString : "jdbc:sqlserver://#getSystemSetting("DB_CONNECTIONSTRING")#", username : getSystemSetting("DB_USER"), password : getSystemSetting("DB_PASSWORD") } } ) Application.cfc Copy component{ this.name = "myApp"; // Default Datasource Name this.datasource = "pantry"; } Application.cfc Copy component{ this.datasources = { // Adobe Driver Approach mysql = { database : "mysql", host : "localhost", port : "3306", driver : "MySQL", username : "root", password : "mysql", options : value }, // Adobe url approach mysql2 = { driver : "mysql", url : "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useLegacyDatetimeCode=true", username : "", password : "" }, // Shorthand Lucee Approach myLuceeDNS = { class : "com.mysql.jdbc.Driver", connectionString : "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useLegacyDatetimeCode=true", username : "", password : "" }, // Long Lucee Approach myLuceeDNS = { type : "mysql", database : "mysql", host : "localhost", port : "3306", username : "", password : "" } }; } .cfconfig.json Copy { "requestTimeoutEnabled":true, "whitespaceManagement":"white-space-pref", "requestTimeout":"0,0,5,0", "cacheDefaultObject":"coldbox", "caches":{ "coldbox":{ "storage":"true", "type":"RAM", "custom":{ "timeToIdleSeconds":"1800", "timeToLiveSeconds":"3600" }, "class":"lucee.runtime.cache.ram.RamCache", "readOnly":"false" } }, "datasources" : { "coldbox":{ "host":"${DB_HOST}", "dbdriver":"${DB_DRIVER}", "database":"${DB_DATABASE}", "dsn":"jdbc:mysql://{host}:{port}/{database}", "custom":"useUnicode=true&characterEncoding=UTF-8&useLegacyDatetimeCode=true&autoReconnect=true", "port":"${DB_PORT}", "class":"${DB_CLASS}", "username":"${DB_USER}", "password":"${DB_PASSWORD}", "connectionLimit":"100", "connectionTimeout":"1" } } } Copy There are #qItems.Quantity# #qItems.Item# in the pantry
Copy There are #qItems[ 'quantity' ]# #qItems[ 'item' ]# in the pantry
Copy for( var row in qItems ){ systemOutput( "There are #row.quantity# #row.item# in the pantry" ); } qItems.each( function( row, index ){ systemOutput( "There are #row.quantity# #row.item# in the pantry" ); } ); for( var i = 1; i lte qItems.recordCount; i++ ){ systemOutput( "There are #qItems.quantity[ i ]# #qItems.item[ i ]# in the pantry" ); } Copy queryEach( array, callback, parallel:boolean, maxThreads:numeric ); each( collection, callback, parallel:boolean, maxThreads:numeric ); Copy myquery.each( function( row ){ myservice.process( row ); }, true, 20 ); Copy // Named variable holder // automatic parameterization via inline struct definitions queryExecute( "select quantity, item from cupboard where item_id = :itemID" { itemID = { value=arguments.itemID, cfsqltype="numeric" } } ); // Positional placeholder queryExecute( "select quantity, item from cupboard where item_id = ?" [ { value=arguments.itemID, cfsqltype="varchar" } ] ); Copy news = queryNew("id,title", "integer,varchar"); queryAddRow(news); querySetCell(news, "id", "1"); querySetCell(news, "title", "Dewey defeats Truman"); queryAddRow(news); querySetCell(news, "id", "2"); querySetCell(news, "title", "Men walk on Moon"); writeDump(news); users = queryNew( "firstname", "varchar", [{"firstname":"Han"}] ); subUsers = queryExecute( "select * from users", {}, { dbtype="query" } ); writedump( subUsers ); news = queryNew("id,title", "integer,varchar", [ {"id":1,"title":"Dewey defeats Truman"}, {"id":2,"title":"Man walks on Moon"} ]); writeDump(news); news = queryNew("id,title", "integer,varchar", {"id":1,"title":"Dewey defeats Truman"}); writeDump(news); Copy users = queryNew( "firstname", "varchar", [{"firstname":"Han"}] ); subUsers = queryExecute( "select * from users", {}, { dbtype="query" } ); writedump( subUsers ); Copy users = queryNew( "firstname", "varchar", [{"firstname":"Han"}] ); subUsers = queryExecute( "select * from users", {}, { dbtype="query", returntype="array" } ); writedump( subUsers ); users = queryNew( "id, firstname", "integer, varchar", [{"id":1, "firstname":"Han"}] ); subUsers = queryExecute( "select * from users", {}, { dbtype="query", returntype="struct", columnkey="id" } ); writedump( subUsers ); Copy box install qb Copy // qb query = wirebox.getInstance( 'Builder@qb' ); q = query.from( 'posts' ) .whereNotNull( 'published_at' ) .whereIn( 'author_id', [5, 10, 27] ) .get(); --- # Includes | Learn Modern ColdFusion in 100 Minutes If you've used other scripting environments such as PHP, or dynamic HTML, you would be familiar with the concept of **server side includes**. An **include** is a file that is embedded, or **included** within another file making it part of the execution; simple as that. This can be very useful when you want multiple CFML templates to share the same block of code, scopes and visibility. In modern times, you can call this a **mixin**. A typical example might be your website's header and footer, or the reuse of included functions. The ColdBox MVC framework even allows you to define mixin helper templates that can be injected at runtime in Controller objects, views, layouts and much more. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/includes#a-stern-warning) A Stern Warning --------------------------------------------------------------------------------------------------------- Now, even though doing includes/mixins are easy to do in CFML, let me give you a **BIG WARNING**. Includes are one of the most abused features in ANY language, that bring confusion and sustainability issues. Easy doesn't mean sustainable or maintainable. Do not go crazy with includes, there are many other design patterns like dependency injection and composition/aggregation that can solve reusability in much better approaches. Think about it not twice, but thrice! > **Mixin** : In object-oriented programming languages, a mixin is a class that contains methods for use by other classes without having to be the parent class of those other classes; No inheritance needed. - [https://en.wikipedia.org/wiki/Mixinarrow-up-right](https://en.wikipedia.org/wiki/Mixin) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/includes#implementation) Implementation ------------------------------------------------------------------------------------------------------- CFML provides the `` tag and the `include` construct for including files in script - [https://cfdocs.org/cfincludearrow-up-right](https://cfdocs.org/cfinclude) . Copy // script include "template.cfm" runonce=true; The `template` argument is a relative, absolute or CFML mapping path to the template to inject. Copy include template="path/to/libraries/mixins.cfm"; [PreviousThreadingchevron-left](https://modern-cfml.ortusbooks.com/cfml-language/threading) [NextJava Integrationchevron-right](https://modern-cfml.ortusbooks.com/cfml-language/java-integration) Last updated 2 years ago Was this helpful? * [A Stern Warning](https://modern-cfml.ortusbooks.com/cfml-language/includes#a-stern-warning) * [Implementation](https://modern-cfml.ortusbooks.com/cfml-language/includes#implementation) Was this helpful? --- # Threading | Learn Modern ColdFusion in 100 Minutes CFML allows you create asynchronous threads so you can execute a body of code in a separate thread. This is achieved via the `cfthread` tag & the `thread` construct. Threads are independent streams of execution, and multiple threads on a page can execute simultaneously and asynchronously, letting you perform asynchronous processing in CFML. CFML code within the `cfthread` tag body executes on a separate thread while the page request thread continues processing without waiting for the `cfthread` body to finish. You can allow the thread body to continue executing in the background or you can wait for it to finish. ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LlrhPKUAD9hkU30EdHm%252F-LlrnLRAHaySHceVGAIv%252FScreen%2520Shot%25202019-08-09%2520at%25202.14.00%2520PM.png%3Falt%3Dmedia%26token%3Dd85ea577-a4af-4007-b46b-9fb17ab0fc7b&width=768&dpr=3&quality=100&sign=dd5c6dac&sv=2) triangle-exclamation **IMPORTANT:** You cannot spawn a thread from within a thread in any of the CFML engines. This approach is very very simplistic, if you want more control of your asynchronous programming aspects then we can move into leveraging CFML Future's via the `runAsync()` function or parallel Java streams using the [cbStreamsarrow-up-right](https://www.forgebox.io/view/cbStreams) project. Please see our [Asynchronous Programming](https://modern-cfml.ortusbooks.com/beyond-the-100/asynchronous-programming) section for information on advanced asynchronous programming. [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fwww.adobe.com%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=40f989eb&sv=2)Creating and managing ColdFusion threadshelpx.adobe.comchevron-right](https://helpx.adobe.com/coldfusion/developing-applications/developing-cfml-applications/using-coldfusion-threads/creating-and-managing-coldfusion-threads.html) [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fwww.adobe.com%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=40f989eb&sv=2)Working with threadshelpx.adobe.comchevron-right](https://helpx.adobe.com/coldfusion/developing-applications/developing-cfml-applications/using-coldfusion-threads/working-with-threads.html) ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/threading#a-fair-warning) A Fair Warning Please note that once you get into concurrency you will start to get many headaches. Your code must be thread safe, appropriate locking must be in place and overall concurrency based programming will be needed on any shared resource. It is also very difficult to debug because you are no longer in the same thread and a `writedump() + abort` combo usually goes into ether. Logging will be your best friend and outputting logs to the console for debugging purposes. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/threading#thread-logging) Thread Logging Here are some utility functions to assist with logging: * `systemOutput( obj, addNewLine:boolean, doErrorStream:boolean)` - Writes the given text or complex objects to the output or error stream. Complex objects are outputted as JSON. (Lucee-only) [https://cfdocs.org/systemoutputarrow-up-right](https://cfdocs.org/systemoutput) * `cfdump( var="text", output="console" )` - Send the variables to the output console, even complex variables. Complex objects are outputted as JSON. [https://cfdocs.org/cfdumparrow-up-right](https://cfdocs.org/cfdump) * `cflog( text, log, file, type ) or writeLog()` - Leverage the ColdFusion engine's logging facilities to send typed messages. [https://cfdocs.org/cflogarrow-up-right](https://cfdocs.org/cflog) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/threading#thread-construct) Thread Construct ------------------------------------------------------------------------------------------------------------ Writing `thread` is extremely easy, just use the construct, give it a few attributes an boom you are in multi-threaded land. In tags you can use the `` tag. Examples: [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/threading#thread-data) Thread Data -------------------------------------------------------------------------------------------------- Because multiple threads can process simultaneously within a single template request, applications must ensure that data from one thread does not pollute or affect data in another thread. CFML provides several scopes that you can use to manage thread data, and a request-level lock mechanism that you use to prevent problems caused by threads that access page-level data. CFML also provides metadata variables that contain any thread-specific output and information about the thread, such as its status, processing time and much more, which extremely useful. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/threading#thread-scopes) Thread Scopes * Thread `local` scope * `Thread` scope * `Attributes` scope #### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/threading#thread-local-scope) Thread local Scope The thread-local scope is an implicit scope that contains variables that are available only to the thread, and exist only for the life of the thread. This exactly the same as the function `local` scope. Any variable that you define inside the `thread` body without specifying a scope name prefix is in the thread local scope and cannot be accessed or modified by other threads. #### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/threading#thread-scope) `Thread` Scope The `Thread` scope contains thread-specific variables and metadata about the thread. Only the owning thread can **write** data to this scope, but the page thread and all other threads in a request can **read** the variable values in this scope. Thread scope data remains available until the page and all threads that started from the page finish, even if the page finishes before the threads complete processing. **So be careful with what you store in this scope or you can create memory leaks.** To write to this scope you can use the `thread` scope or actually the **name** of the thread as well, which is pretty cool. To read from this scope outside the `thread` construct you can use the name of the thread or the thread scope, but you must reference which thread scope within it using it's name: `thread.myThreadName` triangle-exclamation Thread scoped variables are only available to the page that created the thread or to other threads created by that page. No other page can access the data, ever! If one page must access another page's `Thread scope` data, you must place the data in a shared location such as a shared scope or a file or database. #### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/threading#thread-attributes-scope) Thread Attributes Scope The thread body executes in isolation, but sometimes you need to be able to pass certain data that the thread body cannot access. In this case, we will pass them via the `thread` construct as a name-value pair. The CFML engine will then place those in the thread's `attributes` scope so they can be used for the life of the thread. **WARNING** **All variables passed as attributes will be duplicated by the engine (deep copy). That's right! A raw duplicate() will be executed for the passing variable. If it is an array or struct, the entire collection will be duplicated. If it is an object with an object graph, the ENTIRE object graph will be duplicated.** In some cases, that's ok, but it can be expensive and produce results that are not expected. Only pass variables to the attributes that you know and are ok with being duplicated. Copying the data ensures that the values passed to threads are thread-safe, because the attribute values cannot be changed by any other thread. If you do not want duplicate data, do not pass it to the thread as an attribute but use a shared scope instead that the thread body can access. That's it for threading. Such a simple but powerful construct built right into the CFML language. Like mentioned before, if you need much more granular control or advanced ways to do [asynchronous programming](https://modern-cfml.ortusbooks.com/beyond-the-100/asynchronous-programming) , go to our section on running async code fluently. [PreviousCode Lockingchevron-left](https://modern-cfml.ortusbooks.com/cfml-language/locking) [NextIncludeschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/includes) Last updated 2 years ago Was this helpful? * [A Fair Warning](https://modern-cfml.ortusbooks.com/cfml-language/threading#a-fair-warning) * [Thread Logging](https://modern-cfml.ortusbooks.com/cfml-language/threading#thread-logging) * [Thread Construct](https://modern-cfml.ortusbooks.com/cfml-language/threading#thread-construct) * [Thread Data](https://modern-cfml.ortusbooks.com/cfml-language/threading#thread-data) * [Thread Scopes](https://modern-cfml.ortusbooks.com/cfml-language/threading#thread-scopes) Was this helpful? Copy // Lucee Only sytemOutput( "Hello from thread land", true ); sytemOutput( myComplexObject, true ); // Dumps writedump( var="Hello from thread land", output="console" ); writedump( var=myComplexObject, output="console" ); // Cflogs writeLog( text = "Logging some info.", type = "information", application = "false", file = "myLogFile" ); // By default, with no file or log type it sends it to the application.log writeLog( text = "Logging more info.", type = "error" ); Copy thread name = "The name of the thread, must be unique" action="run, sleep, join, or terminate" duration="The number of milliseconds to suspend the thread processing" priority="high, low, or normal" timeout="Number in milliseconds the current thread waits for this thread to finish." { // Body to execute in a separate thread // All variables declared implicity will be placed in the thread's local scope // You still have access to all scopes. } Copy thread action="run" name="myThread" { // do single thread stuff } // Wait for the myThread and myOtherThread to finish thread action="join" name="myThread,myOtherThread"; // A fancy one thread name="#thisThreadName#" action="run" priority="#arguments.asyncPriority#" interceptData="#arguments.interceptData#" threadName="#thisThreadName#" buffer="#arguments.buffer#" key="#key#" { // Retrieve interceptor to fire and local context var thisInterceptor = this.getInterceptors().get( attributes.key ); var event = variables.controller.getRequestService().getContext(); // Check if we can execute this Interceptor if( variables.isExecutable( thisInterceptor, event, attributes.key ) ){ // Invoke the execution point variables.invoker( interceptor = thisInterceptor, event = event, interceptData = attributes.interceptData, interceptorKey = attributes.key, buffer = attributes.buffer ); // Debug interceptions if( variables.log.canDebug() ){ variables.log.debug( "Interceptor '#getMetadata( thisInterceptor ).name#' fired in asyncAll chain: '#this.getState()#'" ); } } } // end thread Copy thread name="mythread"{ var localData = "this data"; // A thread local variable. believeItOrNot = "this goes into the local scope and not the variables scope"; } Copy thread name="mythread"{ // create a shared struct data variable. thread.myDataProcess = { name = "hello" }; thread.threadStartedAt = now(); // Or use the thread name mythread.myDataProcess.value = 1; } // Outside of the thread, you can use the thread scope or the named thread. cflog( thread.myThread.myDataProcess.hello ); cflog( mythread.myDataProcess.value + 1 ); Copy // A fancy one thread name="#thisThreadName#" action="run" priority="#arguments.asyncPriority#" // custom variables passed as attributes interceptData="#arguments.interceptData#" threadName="#thisThreadName#" buffer="#arguments.buffer#" key="#key#" { // Retrieve interceptor to fire and local context var thisInterceptor = this.getInterceptors().get( attributes.key ); var event = variables.controller.getRequestService().getContext(); // Check if we can execute this Interceptor if( variables.isExecutable( thisInterceptor, event, attributes.key ) ){ // Invoke the execution point variables.invoker( interceptor = thisInterceptor, event = event, interceptData = attributes.interceptData, interceptorKey = attributes.key, buffer = attributes.buffer ); // Debug interceptions if( variables.log.canDebug() ){ variables.log.debug( "Interceptor '#getMetadata( thisInterceptor ).name#' fired in asyncAll chain: '#this.getState()#'" ); } } } // end thread --- # Closures | Learn Modern ColdFusion in 100 Minutes > A closure is the combination of a function and the lexical environment within which that function was declared. Remember that functions (UDFs) in CFML are objects, and closures are objects. So, are closures and functions the same? The answer is yes and no. The main difference between a UDF and a closure is that closures have access to the lexical environment in which they are declared. Both functions and closures can be manipulated at runtime and passed around to other functions and closures or returned from other functions and closures. Phew! A closure can be used in any of the following ways: * Defined inline without giving a name. * They can be assigned to a variable, array item, struct, and variable scope. * It can be returned directly from a function. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/closures#assigned-closures) Assigned Closures ------------------------------------------------------------------------------------------------------------- Copy function hello(){ var name = "luis"; var display = function(){ systemOutput( name ); }; display(); } hello(); If we execute this template via CommandBox, our output will be **luis**. This means the `display` closure has access to its surroundings to display the `name` variable. It can manipulate it, add to it, remove from it, and more. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/closures#returned-closures-high-order-functions) Returned Closures/High-Order Functions ------------------------------------------------------------------------------------------------------------------------------------------------------- We can also have a function return a closure that can leverage the function's variable environment. In this case, the `makeAdder` creates a function that will add the passed-in variable with another via a delay of execution. You can then execute the resultant closures `add` with another number to get your calculation of `3` in this case. **Funky!!** [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/closures#passed-closures) Passed Closures --------------------------------------------------------------------------------------------------------- CFML also has the concept of functional programming using several modern operations, like `map(), reduce(), filter(), each(), etc` you can pass closures into other functions for operating on different data structures. Please note that you can construct your very own functional member functions on your objects and generate very functional custom DSL (Domain Specific Languages) by being creative. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/closures#delayed-execution) Delayed Execution ------------------------------------------------------------------------------------------------------------- Another big advantage of leveraging closures for functional programming is that closures are the blueprint of a function and are not executed until you want to. They are useful for delaying execution and great for design patterns like observers, filters, iterators, and much more. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/closures#closure-scopes) Closure Scopes ------------------------------------------------------------------------------------------------------- A closure retains a copy of variables visible at its creation. The global variables (like ColdFusion specific scopes) and the local variables (including declaring or outer function's local and arguments scope) are retained at the time of a closure creation. Functions are static. The following details the scope of closure based on the way they are defined: Scenario Scope In a CFC function Closure argument scope, enclosing function local scope and argument scope, this scope, variable scope, and super scope In a CFM function Closure argument scope, enclosing function local scope and argument scope, this scope, variable scope, and super scope As function argument Closure argument scope, variable scope, and this scope and super scope (if defined in CFC component). In a closure, the following is the order of search for an unscoped variable: * Closure's `local` scope * Closure's `arguments` scope * Outer function' `local` scope if available * Owner function's `local` scope if available * ColdFusion built-in scope [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/closures#isclosure) isClosure() ----------------------------------------------------------------------------------------------- CFML has a built-in function called `isClosure()` that allows you to evaluate if a variable is a closure or not: [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/closures#lambda-expressions-or-arrow-functions) Lambda Expressions or Arrow Functions ----------------------------------------------------------------------------------------------------------------------------------------------------- Supported only in Lucee and Adobe 2018+. triangle-exclamation Please note that they are not REAL lambdas or pure functions. Pure functions are not supposed to interact with their environment and should have no side effects on their surroundings. However, in ColdFusion, they are just implemented using the expression syntax, not the semantic nature of pure functions. Arrow functions reduce much of the syntax around creating closures. In its simplest form, you can eliminate the `function` keywords, curly braces, and `return` statements. Arrow expressions implicitly return the results of the expression body. A simple arrow expression with multiple arguments: A complex arrow expression with an argument: [PreviousInterfaceschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/components/interfaces) [NextCode Lockingchevron-right](https://modern-cfml.ortusbooks.com/cfml-language/locking) Last updated 2 years ago Was this helpful? * [Assigned Closures](https://modern-cfml.ortusbooks.com/cfml-language/closures#assigned-closures) * [Returned Closures/High-Order Functions](https://modern-cfml.ortusbooks.com/cfml-language/closures#returned-closures-high-order-functions) * [Passed Closures](https://modern-cfml.ortusbooks.com/cfml-language/closures#passed-closures) * [Delayed Execution](https://modern-cfml.ortusbooks.com/cfml-language/closures#delayed-execution) * [Closure Scopes](https://modern-cfml.ortusbooks.com/cfml-language/closures#closure-scopes) * [isClosure()](https://modern-cfml.ortusbooks.com/cfml-language/closures#isclosure) * [Lambda Expressions or Arrow Functions](https://modern-cfml.ortusbooks.com/cfml-language/closures#lambda-expressions-or-arrow-functions) Was this helpful? Copy function makeAdder( required x ){ return function( required y ){ return x + y; }; } add = makeAdder( 1 ); systemOutput( add( 2 ) ); Copy fruitArray = [\ { fruit='apple', rating=4 }, \ { fruit='banana', rating=1 }, \ { fruit='orange', rating=5 }, \ { fruit='mango', rating=2 }, \ { fruit='kiwi', rating=3 }\ ]; favoriteFruits = fruitArray.filter( function( item ){ return item.rating >= 3; } ); systemOutput( favoriteFruits ); Copy var observe = function( val ){ // manipulate the val and return it return val; } describe( "A spec suite", function(){ it( "can do funky stuff", function(){ // I can do funky stuff here } ); } ); Copy if( isClosure( arguments.body ) ){ arguments.body(); } Copy // Using a traditional closure makeSix = function(){ return 5 + 1; } // Using an arrow expression makeSix = () => 5 + 1; // returns 6 systemOutput( makeSix() ); Copy // Takes two numeric values and adds them add = ( numeric x, numeric y ) => x + y; // returns 4 systemOutput( add( 1, 3 ) ); Copy // Takes a numeric value and returns a string isOdd = ( numeric n ) => { if( n % 2 == 0 ){ return 'even'; } else { return 'odd'; } }; // returns 'odd' SystemOutput( isOdd( 1 ) ); // returns 'even' SystemOutput( isOdd( 10 ) ); --- # File Handling | Learn Modern ColdFusion in 100 Minutes CFML allows you to manipulate, read, upload, etc files via its built in methods which are great and easy to use. It can even help you manipulate zip/jar archives! We won't go into every single detail of file handling, but below you can find the majority of functions to deal with file handling. circle-check You can find the file system functions here: [https://cfdocs.org/filesystem-functionsarrow-up-right](https://cfdocs.org/filesystem-functions) . * [DirectoryCopyarrow-up-right](https://docs.lucee.org/reference/functions/directorycopy.html) Copies the contents of a directory to a destination directory. * [DirectoryCreatearrow-up-right](https://docs.lucee.org/reference/functions/directorycreate.html) Creates new directory for specified path * [DirectoryDeletearrow-up-right](https://docs.lucee.org/reference/functions/directorydelete.html) Deltes directory for given path * [DirectoryExistsarrow-up-right](https://docs.lucee.org/reference/functions/directoryexists.html) Determines whether a directory exists. * [DirectoryListarrow-up-right](https://docs.lucee.org/reference/functions/directorylist.html) Lists the directory and returns the list of files under it as array or query * [DirectoryRenamearrow-up-right](https://docs.lucee.org/reference/functions/directoryrename.html) Renames given directory * [ExpandPatharrow-up-right](https://docs.lucee.org/reference/functions/expandpath.html) Creates an absolute, platform-appropriate path that is equivalent to the value of relative\_path, appended to the base path. This function (despite its name) can accept an absolute or relative path in the relative\_path attribute * [FileAppendarrow-up-right](https://docs.lucee.org/reference/functions/fileappend.html) appends the entire content to the specified file. * [FileClosearrow-up-right](https://docs.lucee.org/reference/functions/fileclose.html) Closes an file that is open. * [FileCopyarrow-up-right](https://docs.lucee.org/reference/functions/filecopy.html) Copies the specified on-disk or in-memory source file to the specified destination file. * [FileDeletearrow-up-right](https://docs.lucee.org/reference/functions/filedelete.html) Deletes the specified file on the server. * [FileExistsarrow-up-right](https://docs.lucee.org/reference/functions/fileexists.html) Determines whether a file exists * [FileGetMimeTypearrow-up-right](https://docs.lucee.org/reference/functions/filegetmimetype.html) Returns the mimetype of the given file * [FileInfoarrow-up-right](https://docs.lucee.org/reference/functions/fileinfo.html) returns detailed info about the given file. * [FileIsEOFarrow-up-right](https://docs.lucee.org/reference/functions/fileiseof.html) Determines whether Lucee has reached the end of the file while reading it. * [FileMovearrow-up-right](https://docs.lucee.org/reference/functions/filemove.html) Moves file from source to destination * [FileOpenarrow-up-right](https://docs.lucee.org/reference/functions/fileopen.html) Opens an file to read, write, or append. * [FileReadarrow-up-right](https://docs.lucee.org/reference/functions/fileread.html) Reads an on-disk or in-memory text file or a file object created with the FileOpen function. * [FileReadLinearrow-up-right](https://docs.lucee.org/reference/functions/filereadline.html) Reads a line from an file. * [FileSeekarrow-up-right](https://docs.lucee.org/reference/functions/fileseek.html) Shifts the file pointer to the given position. The file must be opened with seekable option * [FileSetAccessModearrow-up-right](https://docs.lucee.org/reference/functions/filesetaccessmode.html) Sets the attributes of an on-disk file on UNIX or Linux. This function does not work with in-memory files. * [FileSetAttributearrow-up-right](https://docs.lucee.org/reference/functions/filesetattribute.html) For the given path, sets the file attributes. * [FileSetLastModifiedarrow-up-right](https://docs.lucee.org/reference/functions/filesetlastmodified.html) For the given file, set the last modification date * [FileSkipBytesarrow-up-right](https://docs.lucee.org/reference/functions/fileskipbytes.html) Shifts the file pointer by the given number of bytes. * [FileToucharrow-up-right](https://docs.lucee.org/reference/functions/filetouch.html) Touches given file, creates the file if not already exists. * [FileUploadarrow-up-right](https://docs.lucee.org/reference/functions/fileupload.html) Uploads file to a directory on the server. * [FileUploadAllarrow-up-right](https://docs.lucee.org/reference/functions/fileuploadall.html) Uploads file to a directory on the server. * [FileWritearrow-up-right](https://docs.lucee.org/reference/functions/filewrite.html) If you specify a file path, writes the entire content to the specified file. If you specify a file object, writes text or binary data to the file object. * [FileWriteLinearrow-up-right](https://docs.lucee.org/reference/functions/filewriteline.html) Opens up the file (or uses the existing file object) and appends the given line of text * [GetFileInfoarrow-up-right](https://docs.lucee.org/reference/functions/getfileinfo.html) Retrieves information about file. * [GetFreeSpacearrow-up-right](https://docs.lucee.org/reference/functions/getfreespace.html) Returns the number of unallocated bytes in the partition named by this abstract path name. * [GetTempDirectoryarrow-up-right](https://docs.lucee.org/reference/functions/gettempdirectory.html) Returns the full path to the currently assigned temporary directory * [GetTempFilearrow-up-right](https://docs.lucee.org/reference/functions/gettempfile.html) Creates a temporary file in a directory whose name starts with (at most) the first three characters of prefix. * [ImageWritearrow-up-right](https://docs.lucee.org/reference/functions/imagewrite.html) Writes a image to the specified filename or destination. [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/file-handling#dealing-with-large-files) Dealing With Large Files --------------------------------------------------------------------------------------------------------------------------------- If you want to read or manipulate large files we would recommend that you leverage our [cbStreamsarrow-up-right](https://forgebox.io/view/cbstreams) library or native Java file streaming. Below you can find some sample usage of reading large files with [cbStreamsarrow-up-right](https://forgebox.io/view/cbstreams) which implements the Java Streams API. [PreviousApplication.cfcchevron-left](https://modern-cfml.ortusbooks.com/beyond-the-100/applicationcfc) [NextImage Manipulationchevron-right](https://modern-cfml.ortusbooks.com/beyond-the-100/image-manipulation) Last updated 2 years ago Was this helpful? Was this helpful? Copy // A few examples content = fileRead( expandPath( "/config/myfile.txt" ) ); if( fileExists( "filepath.txt" ) ){ } fileDelete( "filepath.txt" ) fileWrite( getTempFile( getTempDirectory(), "tempFile"), "My Data" ); directoryList( "/my/path" ) directoryExists( "/my/path" )
if( structKeyExists( form, "fileInput" )) { try { uploadedFile = fileUpload( getTempDirectory(), "fileInput", "image/jpeg,image/pjpeg", "MakeUnique" ); // check the file extension of the uploaded file; mime types can be spoofed if (not listFindNoCase("jpg,jpeg", cffile.serverFileExt)) { throw("The uploaded file is not of type JPG."); } // do stuff with uploadedFile... } catch ( coldfusion.tagext.io.FileUtils$InvalidUploadTypeException e ) { writeOutput( "This upload form only accepts JPEG files." ); } catch (any e) { writeOutput( "An error occurred while uploading your file: #e.message#" ); } } Copy stream = streamBuilder.new().ofFile( absolutePath ); try{ //work on the stream of lines of files and close it in the finally block } finally{ stream.close(); } //You can even process file lines concurrently stream = streamBuilder.new() .parallel() .ofFile( absolutePath ); --- # Java Integration | Learn Modern ColdFusion in 100 Minutes ,CFML is compiled to [Java bytecodearrow-up-right](https://en.wikipedia.org/wiki/Java_bytecode) and runs on the JVM. This gives CFML a unique advantage that not only can you write CFML but you can also integrate with the running JDK libraries or any Java library you tell the engine to use. This is great, because if there is something already written in Java, just drop it in and use it, well most of the time :) Unless Jar loading hell occurs. circle-info CommandBox even allows you to install jar's from any endpoint into your projects: [https://commandbox.ortusbooks.com/package-management/code-endpoints/jar-via-httparrow-up-right](https://commandbox.ortusbooks.com/package-management/code-endpoints/jar-via-http) Copy install "jar:https://github.com/coldbox-modules/cbox-bcrypt/blob/master/modules/bcrypt/models/lib/jbcrypt.jar?raw=true" [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fcfdocs.org%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=12889214&sv=2)Java Integration Guide CFML DocumentationCF Docschevron-right](https://cfdocs.org/java) [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fwww.adobe.com%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=40f989eb&sv=2)Enhanced Java integration in ColdFusionhelpx.adobe.comchevron-right](https://helpx.adobe.com/coldfusion/developing-applications/using-web-elements-and-external-objects/integrating-jee-and-java-elements-in-cfml-applications/enhanced-java-integration-in-coldfusion.html) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#creating-java-objects) Creating Java Objects ----------------------------------------------------------------------------------------------------------------------------- The easiest way to integrate with Java is to be able to instantiate Java objects or call Java static methods on objects. You will do this via the `createObject()` or the `new` operator approach. Here is the signatures for both approaches: Examples: [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#java-casting) Java Casting ----------------------------------------------------------------------------------------------------------- You must remember that Java is a static and typed language. CFML is not! If you need to pass in arguments to Java functions that require native types you will have to cast them. We will use the fancy `JavaCast()` function built-in to the language. The `javaCast()` method takes in two arguments: * `type` : The type of casting * `variable` : The value to cast The available casting types are: * `boolean` * `double` * `float` * `int` * `long` * `string` * `null` * `byte` * `bigdecimal` * `char` * `short` If you need to cast the type but as an array then you can use the `[]` in the casting construct. Let's create a stream from an incoming list of values and cast them to an array of objects in Java. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#java-nulls) Java Nulls Ohh the dreaded day [nulls](https://modern-cfml.ortusbooks.com/cfml-language/null-and-nothingness) where created. The variable that means that nothing exists. If you need to pass null into Java object calls then you have two approaches to create them: [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#loading-custom-jars-libraries) Loading Custom Jars/Libraries --------------------------------------------------------------------------------------------------------------------------------------------- The `createObject( "java" )` method will look into the CFML engine's class loader to discover the class you request. If the class is not located an exception is thrown that the class could not be found. If you want to integrate with third-party Jar's and libraries then you will need to tell the engine where to look for those classes. There are essentially three ways to add custom libraries to the CFML engine: 1. Add the jars/libs to the CFML Lib paths. These are those obscure directories both Adobe and Lucee give you so you can drop your libraries and the engine's class loader can well, load them. Each engine has different paths, please see their docs on the matter. We won't cover this approach as it is incredibly rigid: 1. [https://docs.lucee.org/guides/Various/tutorial-lucee/tutorial-java-in-lucee.htmlarrow-up-right](https://docs.lucee.org/guides/Various/tutorial-lucee/tutorial-java-in-lucee.html) 2. [https://helpx.adobe.com/coldfusion/developing-applications/using-web-elements-and-external-objects/integrating-jee-and-java-elements-in-cfml-applications/about-coldfusion-java-and-jee.htmlarrow-up-right](https://helpx.adobe.com/coldfusion/developing-applications/using-web-elements-and-external-objects/integrating-jee-and-java-elements-in-cfml-applications/about-coldfusion-java-and-jee.html) 2. The `Application.cfc` allows you to declare a `this.javaSettings` struct where you can declare an array of locations of the libraries to load upon application startup with some nice modifiers. This will allow you to store and even leverage CommandBox for the management of such jars. 3. In Lucee, the `createObject( "java" )` construct allows you to pass in a third argument which can be a location or an array of locations of libraries to class load. This is also great for custom CFCs, task runners, or isolated class loading. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#this.javasettings) this.javaSettings This `Application.cfc` structure takes in 3 keys that will allow you to class load any jar/.class libraries into the running ColdFusion application: Key Description `loadPaths` An array of paths to the directories that contain Java classes or JAR files.You can also provide the path to a JAR or a class. If the paths are not resolved, an error occurs. `loadColdFusionClassPath` Indicates whether to load the classes from the ColdFusion lib directory. The default value is false. `reloadOnChange` Indicates whether to reload the updated classes and JARs dynamically, without restarting ColdFusion. The default value is false. `watchInterval` Specifies the time interval in seconds after which to verify any change in the class files or JAR files. This attribute is applicable only if the reloadOnChange attribute is set to true. The default value is 60 seconds. `watchExtensions` Specifies the extensions of the files to monitor for changes. By default, only `.class and .jar` files are monitored. Once that is declared in your Application.cfc and you execute a `createobject()` with a class from those libraries, ColdFusion will know about them and create them. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#createobject-lucee-class-loading) createObject() Lucee Class Loading The other approach is to leverage the `createObject()` call to do class loading. Please note that only Lucee supports this feature as of now. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#dynamic-proxies) Dynamic Proxies ----------------------------------------------------------------------------------------------------------------- Both ColdFusion engines also allows you to create dynamic proxies from existing ColdFusion Components (CFCs). What this means is that a Dynamic proxy lets you pass ColdFusion components to Java objects. Java objects can work with the ColdFusion components seamlessly as if they are native Java objects by implementing the appropriate Java interfaces. You can even use them to simulate Java lambdas as ColdFusion components. If you want to leverage a Java library that requires a certain type of Java object as an argument and instead of you creating that object in Java, you can see if that argument adheres to a certain interface and CFML will create a dynamic proxy that binds it. Basically, your CFC must implement the appropriate methods the interface(s) tell you that it needs. After that, your CFC will be Javafyied, and it can be used like a native Java interface implementing objects! Enjoy! [PreviousIncludeschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/includes) [NextBeyond The 100chevron-right](https://modern-cfml.ortusbooks.com/beyond-the-100/beyond-the-language) Last updated 2 years ago Was this helpful? * [Creating Java Objects](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#creating-java-objects) * [Java Casting](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#java-casting) * [Java Nulls](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#java-nulls) * [Loading Custom Jars/Libraries](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#loading-custom-jars-libraries) * [this.javaSettings](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#this.javasettings) * [createObject() Lucee Class Loading](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#createobject-lucee-class-loading) * [Dynamic Proxies](https://modern-cfml.ortusbooks.com/cfml-language/java-integration#dynamic-proxies) Was this helpful? Copy createObject( "java", "java.class.path" ) new java( "class.path" ); // ACF2018 ONLY Copy // Create a Java JDK Object var buffer = createObject( "java", "java.lang.StringBuilder" ); // Using a constructor currentFile = createObject( "java", "java.io.File" ).init( getCurrentTemplatePath() ); writeOutput( currentFile.lastModified() ); // Invoking a static method javaSystem = new java( "java.lang.System" ); currentTime = javaSystem.currentTimeMillis(); writeOutput( currentTime ); Copy integerObject = createObject( "java", "java.lang.Integer" ); maxInt = integerObject.max( javaCast( "int", 5 ), javaCast( "int", 6 ) ); Copy createObject( "java", "java.util.Arrays" ) .stream( javaCast( "java.lang.Object[]", listToArray( arguments.target, "" ) ) ); Copy // Adobe + Lucee javaCast( "null", "" ); // Lucee only nullValue(); Application.cfc Copy component{ this.javaSettings = { loadPaths = [ "./lib", "./config/java/myjar.jar" ], reloadOnChange = false } } Copy // Reference createObject( "java", "path", array or jar location ) // Example variables.LIB_PATH = expandPath( "/mylib/apache.jar" ); createObject( "java", "org.apache.pdfbox.pdmodel.PDDocument", variables.LIB_PATH ); Copy createDynamicProxy( cfc, interfaces ) Copy createDynamicProxy( new proxies.Consumer( arguments.consumer ), // create a Consumer CFC [ "java.util.function.Consumer" ] // match it to this interface ) // Here is the Consumer CFC /** * Functional Interface that maps to java.util.function.Consumer * See https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html */ component extends="BaseProxy"{ /** * Constructor * * @f The lambda or closure to be used in the accept() method */ function init( required f ){ super.init( arguments.f ); return this; } /** * Performs this operation on the given argument. */ void function accept( t ){ loadContext(); variables.target( t ); } function andThen( after ){} } --- # Code Locking | Learn Modern ColdFusion in 100 Minutes Locking is an essential piece of software engineering. There are occasions where shared resources must be locked in order to write to them or read from them. This process of locking can be very simple or extremely complex. Sometimes it can lead to deadlocks and serious concurrency issues. Further to say, we will only cover basic usage of the locking constructs in CFML. circle-check You can find an in-depth article on locking here: [https://helpx.adobe.com/coldfusion/developing-applications/developing-cfml-applications/using-persistent-data-and-locking/locking-code-with-cflock.htmlarrow-up-right](https://helpx.adobe.com/coldfusion/developing-applications/developing-cfml-applications/using-persistent-data-and-locking/locking-code-with-cflock.html) You can also find great knowledge in the Java Synchronization tutorial: [https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.htmlarrow-up-right](https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/locking#cflock) cflock -------------------------------------------------------------------------------------- CFML gives you the `cflock` tag/construct which you can use to ensure the integrity of shared data and it allows you to have two types of locks: 1. **Exclusive** - Allows single-thread access to the CFML constructs in its body. The tag body can be executed by **one** request at a time. No other requests can start executing code within the tag while a request has an exclusive lock. ColdFusion issues exclusive locks on a first-come, first-served basis. 2. **ReadOnly** - Allows multiple requests to access CFML constructs within the tag body concurrently. Use a read-only lock only when shared data is read and not modified. If another request has an exclusive lock on shared data, the new request waits for the exclusive lock to be released Apart from the type of lock, you can also have two different locking strategies: 1. **Named Locking** : Where a name is used to identify the locking construct 2. **Scoped Locking**: Where you will lock access to a specific CFML scope. Copy lock type="exclusive|readOnly" timeout="15" name="mylock" scope="application|server|session|request" throwOnTimeout="true|false" { // Your code that is synchronized goes here } ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/locking#attributes) Attributes Here are the attributes to the `cflock` construct Attribute Type Default Description `timeout` numeric `required` Max length in seconds to wait to obtain the lock. If lock is obtained, tag execution continues. Otherwise, behavior depends on throwOnTimeout attribute value. `scope` string Lock scope. Mutually exclusive with the `name` attribute. Only one request in the specified scope can execute the code within this tag (or within any other cflock tag with the same lock scope scope) at a time. Values are: `application, request, server, session` `name` string Lock name. Mutually exclusive with the scope attribute. Only one request can execute the code within a `cflock` tag with a given name at a time. Cannot be an [emptyarrow-up-right](https://cfdocs.org/empty) string. `throwOnTimeout` boolean true If true and a timeout is reached an exception is thrown, else it is ignored. `type` string exclusive **readOnly**: lets more than one request read shared data. **exclusive**: lets one request read or write shared data. triangle-exclamation **Important**: Please note that when using named locks, the name is shared across the entire ColdFusion server, no matter the `cfapplication` it is under. Please be aware of it and use unique enough names. Lock names are global to a ColdFusion server. They are shared among applications and user sessions, but not clustered servers. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/locking#named-locking) Named Locking ---------------------------------------------------------------------------------------------------- Named locking is the easiest, where access to the construct is by name. Lock names are global to a ColdFusion server. They are shared among applications and user sessions, but not clustered servers. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/locking#scoped-locking) Scoped Locking ------------------------------------------------------------------------------------------------------ Scoped locking will allow you to lock access to a specific CFML scope like: `application, server, session and request.` You usually do this to synchronize access to variables placed within those scopes. In all essence, scope locking is expensive as it is a BIG lock around the entire scope access. I would suggest to stick to named locks so you can have pin-point accuracy when dealing with code synchronization. Remember that locking can be expensive. triangle-exclamation I highly discourage the use of scope locks as it throws a huge locking mechanism around the entire scope access. Tread with caution. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/locking#deadlocks) Deadlocks -------------------------------------------------------------------------------------------- ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-Lli44wSQAHZ7iJwGa8V%252F-LliEiijroFNlA0pAcCl%252F22-2.png%3Falt%3Dmedia%26token%3Dedbcfc8a-50fb-43df-90bc-11fac5b6c976&width=768&dpr=3&quality=100&sign=ffe99970&sv=2) A deadlock is a state in which no request can execute the locked construct. After a deadlock occurs, neither thread can break it, because all requests to the protected section of the lock are blocked until the deadlock can be resolved by a lock time-out. The `cflock` tag/construct uses kernel level synchronization objects that are released automatically upon time out and/or the abnormal termination of the thread that owns them. Therefore, while processing a `cflock` , the server never deadlocks for an infinite period. However, large time-outs can block request threads for long periods, and radically decrease throughput. To. prevent this, always use the minimum time-out value. Another cause of blocked request threads is inconsistent **nesting** of `cflocks` and inconsistent naming of locks. If you nest locks, everyone accessing the locked variables must consistently nest `cflocks` in the same order. Otherwise, a deadlock can occur. More information can be found here: [https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-tags/tags-j-l/cflock.htmlarrow-up-right](https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-tags/tags-j-l/cflock.html) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language/locking#race-conditions-double-locking) Race Conditions: Double Locking --------------------------------------------------------------------------------------------------------------------------------------- There will be cases where race conditions will exist and multiple threads will be waiting for access into a lock body construct. Furthermore, you will want that only ONE thread enters the body construct and does something and the rest get ignored. This is a race condition and it must be treated with a double lock approach. What this does is that it evaluated the condition of your body (business logic) and if available then enters the lock. Let's do a simple example where you only want ONE thread to ever populate the cache with data and return it from a function. Let's see how NOT to do it first: I am sure that you see this nice function and you are like, well yep it is correct! We check for the existence of the cached data, if null, we load it up and return it. WROOONG!!! This can lead to race conditions where if multiple threads are ALREADY waiting within the lock area, multiple threads can set and re-set the cached data. If we really ONLY want one thread to set the data, we must do a double lock approach: [PreviousClosureschevron-left](https://modern-cfml.ortusbooks.com/cfml-language/closures) [NextThreadingchevron-right](https://modern-cfml.ortusbooks.com/cfml-language/threading) Last updated 2 years ago Was this helpful? * [cflock](https://modern-cfml.ortusbooks.com/cfml-language/locking#cflock) * [Attributes](https://modern-cfml.ortusbooks.com/cfml-language/locking#attributes) * [Named Locking](https://modern-cfml.ortusbooks.com/cfml-language/locking#named-locking) * [Scoped Locking](https://modern-cfml.ortusbooks.com/cfml-language/locking#scoped-locking) * [Deadlocks](https://modern-cfml.ortusbooks.com/cfml-language/locking#deadlocks) * [Race Conditions: Double Locking](https://modern-cfml.ortusbooks.com/cfml-language/locking#race-conditions-double-locking) Was this helpful? Copy lock name="cache-population-myapp" timeout=10 type="exclusive"{ myData = myservice.getData(); cache.set( "mykey", myData ); } Copy lock scope="application" timeout="15"{ application.myNumber += 5; } lock scope="application" timeout="20" type="readonly"{ writeOutput( "I have #application.number# of sock(s) in my closet" ); } Copy function loadData(){ var myData = cache.get( "mykey" ); if( isNull( myData ) ){ lock name="cache-population-myapp" timeout=10 type="exclusive"{ myData = myservice.getData(); cache.set( "mykey", myData ); } } return myData; } Copy function loadData(){ var myData = cache.get( "mykey" ); if( isNull( myData ) ){ lock name="cache-population-myapp" timeout=10 type="exclusive"{ if( !cache.exists( "mykey" ) ){ myData = myservice.getData(); cache.set( "mykey", myData ); } else { return cache.get( "mykey" ); } } } return myData; } --- # Beyond The 100 | Learn Modern ColdFusion in 100 Minutes We cannot possibly cover all the features of the ColdFusion Engines in this book as our focus was more on the core CFML language. However, please note that the engines offer a tremendous middle-ware capabilities that extend beyond normal language features. There are many areas that make ColdFusion one of the most (if not the most) **rapid application development (RAD)** languages around. circle-check Check out the [cfdocsarrow-up-right](https://cfdocs.org/) and the engine documentation sites for all the different capabilities they can offer. In our **Beyond The 100** section you will find more in-depth topics of how CFML can be used for web applications, database interactions, Java integration, RESTFul services_,_ Image manipulation and much more. Here is a simple listing of going beyond with CFML: * PDF Creation * PDF Manipulation * Database Introspection * Object Relational Manager via Hibernate/JPA * Stored Procedures Support * Multiple JDBC Connectors * Job Scheduling * Server Monitoring * API Monitoring, Caching, Gateway * Exchange Support * LDAP Support * Spreadsheet Support * Open Office Support * Mathematical Functions * OSGI Bundle Support * Distributed Caching Support * Much More! [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fdocs.lucee.org%2Fassets%2Fimages%2Ffavicon.png&width=20&dpr=3&quality=100&sign=51451920&sv=2)Lucee Documentationlucee\_serverchevron-right](https://docs.lucee.org/index.html) [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fwww.adobe.com%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=40f989eb&sv=2)Adobe ColdFusion Learn & Supporthelpx.adobe.comchevron-right](https://helpx.adobe.com/support/coldfusion.html) [PreviousJava Integrationchevron-left](https://modern-cfml.ortusbooks.com/cfml-language/java-integration) [NextApplication.cfcchevron-right](https://modern-cfml.ortusbooks.com/beyond-the-100/applicationcfc) Last updated 2 years ago Was this helpful? Was this helpful? --- # Image Manipulation | Learn Modern ColdFusion in 100 Minutes Both CFML engines (Lucee & Adobe) have a very extensive and awesome image manipulation library that will allow you to create and manipulate images in an easy syntax. We cannot see every single detail about image manipulation, but it is necessary to understand that this functionality is easy in CFML and it exists. Apart from having core image functions all functions can be applied as member functions to an image object. Yes, CFML allows you to deal with image objects natively. Copy imgObj = imageRead("http://cfdocs.org/apple-touch-icon.png"); imgObj.resize(50,50); cfimage(action="writeToBrowser", source=imgObj); imgObj = imageRead("http://cfdocs.org/apple-touch-icon.png"); imgObj.blur(5); cfimage(action="writeToBrowser", source=imgObj); imgObj = imageRead("http://cfdocs.org/apple-touch-icon.png"); imgObj.rotate(90); cfimage(action="writeToBrowser", source=imgObj); imgObj = imageRead("http://cfdocs.org/apple-touch-icon.png"); info = imgObj.info(); writeDump(info); You can find some great samples here: [https://cfdocs.org/cfimagearrow-up-right](https://cfdocs.org/cfimage) and a listing of all manipulation functions here: [https://cfdocs.org/image%2Dfunctionsarrow-up-right](https://cfdocs.org/image%2Dfunctions) * [GetReadableImageFormatsarrow-up-right](https://docs.lucee.org/reference/functions/getreadableimageformats.html) Returns a list of image formats that Lucee can read on the operating system where Lucee is deployed. * [GetWriteableImageFormatsarrow-up-right](https://docs.lucee.org/reference/functions/getwriteableimageformats.html) Returns a list of image formats that Lucee can write on the operating system where Lucee is deployed. * [ImageAddBorderarrow-up-right](https://docs.lucee.org/reference/functions/imageaddborder.html) Adds a rectangular border around the outside edge of a image. * [ImageBlurarrow-up-right](https://docs.lucee.org/reference/functions/imageblur.html) Smooths image. * [ImageCaptchaarrow-up-right](https://docs.lucee.org/reference/functions/imagecaptcha.html) Creates a captcha image * [ImageClearRectarrow-up-right](https://docs.lucee.org/reference/functions/imageclearrect.html) Clears the specified rectangle by filling it with the background color of the current drawing surface. * [ImageCopyarrow-up-right](https://docs.lucee.org/reference/functions/imagecopy.html) Copies a rectangular area of an image. * [ImageCroparrow-up-right](https://docs.lucee.org/reference/functions/imagecrop.html) Crops a image to a specified rectangular area. * [ImageDrawArcarrow-up-right](https://docs.lucee.org/reference/functions/imagedrawarc.html) Draws a circular or elliptical arc. * [ImageDrawBeveledRectarrow-up-right](https://docs.lucee.org/reference/functions/imagedrawbeveledrect.html) Draws a rectangle with beveled edges. * [ImageDrawCubicCurvearrow-up-right](https://docs.lucee.org/reference/functions/imagedrawcubiccurve.html) Draws a cubic curve. * [ImageDrawImagearrow-up-right](https://docs.lucee.org/reference/functions/imagedrawimage.html) this function is deprecated, use ImagePaste instead. Draws a image on a image with the baseline of the first character positioned at (x,y) in the image. * [ImageDrawLinearrow-up-right](https://docs.lucee.org/reference/functions/imagedrawline.html) Draws a single line defined by two sets of x and y coordinates on a image. * [ImageDrawLinesarrow-up-right](https://docs.lucee.org/reference/functions/imagedrawlines.html) Draws a sequence of connected lines defined by arrays of x and y coordinates. * [ImageDrawOvalarrow-up-right](https://docs.lucee.org/reference/functions/imagedrawoval.html) Draws an oval. * [ImageDrawPointarrow-up-right](https://docs.lucee.org/reference/functions/imagedrawpoint.html) Draws a point at the specified (x,y) coordinate. * [ImageDrawQuadraticCurvearrow-up-right](https://docs.lucee.org/reference/functions/imagedrawquadraticcurve.html) Draws a curved line. The curve is controlled by a single point. * [ImageDrawRectarrow-up-right](https://docs.lucee.org/reference/functions/imagedrawrect.html) Draws a rectangle. * [ImageDrawRoundRectarrow-up-right](https://docs.lucee.org/reference/functions/imagedrawroundrect.html) Draws a rectangle with rounded corners. * [ImageDrawTextarrow-up-right](https://docs.lucee.org/reference/functions/imagedrawtext.html) Draws a text string on a image with the baseline of the first character positioned at (x,y) in the image. * [ImageFilterarrow-up-right](https://docs.lucee.org/reference/functions/imagefilter.html) the function ImageFilter allows to execute a filter against a image. * [ImageFilterColorMaparrow-up-right](https://docs.lucee.org/reference/functions/imagefiltercolormap.html) These are passed to the function ImageFilters (see ImageFilter documentation) which convert gray values to colors. * [ImageFilterCurvesarrow-up-right](https://docs.lucee.org/reference/functions/imagefiltercurves.html) the curves for the wrap grid * [ImageFilterKernelarrow-up-right](https://docs.lucee.org/reference/functions/imagefilterkernel.html) These are passed to the function ImageFilters * [ImageFilterWarpGridarrow-up-right](https://docs.lucee.org/reference/functions/imagefilterwarpgrid.html) A warp grid. These are passed to the function ImageFilters (see ImageFilter documentation). * [ImageFliparrow-up-right](https://docs.lucee.org/reference/functions/imageflip.html) Flips an image across an axis. * [ImageFontsarrow-up-right](https://docs.lucee.org/reference/functions/imagefonts.html) return all available * [ImageFormatsarrow-up-right](https://docs.lucee.org/reference/functions/imageformats.html) return all available readers and writers * [ImageGetBlobarrow-up-right](https://docs.lucee.org/reference/functions/imagegetblob.html) Retrieves the bytes of the underlying image. The bytes are in the same image format as the source image. * [ImageGetBufferedImagearrow-up-right](https://docs.lucee.org/reference/functions/imagegetbufferedimage.html) Returns the java.awt.BufferedImage object underlying the current image. * [ImageGetEXIFMetadataarrow-up-right](https://docs.lucee.org/reference/functions/imagegetexifmetadata.html) Retrieves the Exchangeable Image File Format (EXIF) headers in an image as a CFML structure. * [ImageGetEXIFTagarrow-up-right](https://docs.lucee.org/reference/functions/imagegetexiftag.html) Retrieves the specified EXIF tag in an image. * [ImageGetHeightarrow-up-right](https://docs.lucee.org/reference/functions/imagegetheight.html) Retrieves the height of the image in pixels. * [ImageGetIptcMetadataarrow-up-right](https://docs.lucee.org/reference/functions/imagegetiptcmetadata.html) Retrieves the International Press Telecommunications Council (IPTC )headers in a image as a struct. The IPTC metadata contains text that describes the image that is stored with it. IPTC metadata includes, but is not limited to, caption, keywords, credit, copyright, object name, created date, byline, headline, and source * [ImageGetIPTCTagarrow-up-right](https://docs.lucee.org/reference/functions/imagegetiptctag.html) Retrieves the value of the IPTC tag for a image. * [ImageGetWidtharrow-up-right](https://docs.lucee.org/reference/functions/imagegetwidth.html) Retrieves the width of the specified image. * [ImageGrayscalearrow-up-right](https://docs.lucee.org/reference/functions/imagegrayscale.html) Converts a image to grayscale. * [ImageInfoarrow-up-right](https://docs.lucee.org/reference/functions/imageinfo.html) Returns a structure that contains information about the image, such as height, width, color model, size, and filename. * [ImageNegativearrow-up-right](https://docs.lucee.org/reference/functions/imagenegative.html) Inverts the pixel values of a image. * [ImageNewarrow-up-right](https://docs.lucee.org/reference/functions/imagenew.html) Creates a image. * [ImageOverlayarrow-up-right](https://docs.lucee.org/reference/functions/imageoverlay.html) Reads two source images and overlays the second source image on the first source image. * [ImagePastearrow-up-right](https://docs.lucee.org/reference/functions/imagepaste.html) Takes two images and an (x,y) coordinate and draws the second image over the first image with the upper-left corner at coordinate (x,y). * [ImageReadarrow-up-right](https://docs.lucee.org/reference/functions/imageread.html) Reads the source pathname or URL and creates a image. * [ImageReadBase64arrow-up-right](https://docs.lucee.org/reference/functions/imagereadbase64.html) Creates a image from a Base64 string. * [ImageResizearrow-up-right](https://docs.lucee.org/reference/functions/imageresize.html) Resizes a image. * [ImageRotatearrow-up-right](https://docs.lucee.org/reference/functions/imagerotate.html) Rotates a image at a specified point by a specified angle. * [ImageRotateDrawingAxisarrow-up-right](https://docs.lucee.org/reference/functions/imagerotatedrawingaxis.html) Rotates all subsequent drawing on a image at a specified point by a specified angle. * [ImageScaleToFitarrow-up-right](https://docs.lucee.org/reference/functions/imagescaletofit.html) Creates a resized image with the aspect ratio maintained. * [ImageSetAntialiasingarrow-up-right](https://docs.lucee.org/reference/functions/imagesetantialiasing.html) Switches antialiasing on or off in rendered graphics. * [ImageSetBackgroundColorarrow-up-right](https://docs.lucee.org/reference/functions/imagesetbackgroundcolor.html) Sets the background color for the image. The background color is used for clearing a region. Setting the background color only affects the subsequent ImageClearRect calls * [ImageSetDrawingAlphaarrow-up-right](https://docs.lucee.org/reference/functions/imagesetdrawingalpha.html) Sets the current drawing alpha for images. All subsequent graphics operations use the specified alpha. * [ImageSetDrawingColorarrow-up-right](https://docs.lucee.org/reference/functions/imagesetdrawingcolor.html) Sets the current drawing color for images. All subsequent graphics operations use the specified color. * [ImageSetDrawingStrokearrow-up-right](https://docs.lucee.org/reference/functions/imagesetdrawingstroke.html) Sets the drawing stroke for points and lines in subsequent images. * [ImageSetDrawingTransparencyarrow-up-right](https://docs.lucee.org/reference/functions/imagesetdrawingtransparency.html) Specifies the degree of transparency of drawing functions. * [ImageSharpenarrow-up-right](https://docs.lucee.org/reference/functions/imagesharpen.html) Sharpens a image by using the unsharp mask filter. * [ImageSheararrow-up-right](https://docs.lucee.org/reference/functions/imageshear.html) Shears an image either horizontally or vertically. * [ImageShearDrawingAxisarrow-up-right](https://docs.lucee.org/reference/functions/imagesheardrawingaxis.html) Shears the drawing canvas. * [ImageTranslatearrow-up-right](https://docs.lucee.org/reference/functions/imagetranslate.html) Copies an image to a new location on the plane. * [ImageTranslateDrawingAxisarrow-up-right](https://docs.lucee.org/reference/functions/imagetranslatedrawingaxis.html) Translates the origin of the image context to the point (x,y) in the current coordinate system. * [ImageWritearrow-up-right](https://docs.lucee.org/reference/functions/imagewrite.html) Writes a image to the specified filename or destination. * [ImageWriteBase64arrow-up-right](https://docs.lucee.org/reference/functions/imagewritebase64.html) Writes Base64 images to the specified filename and destination. * [ImageWriteToBrowserarrow-up-right](https://docs.lucee.org/reference/functions/imagewritetobrowser.html) Writes image to browser. * [ImageXORDrawingModearrow-up-right](https://docs.lucee.org/reference/functions/imagexordrawingmode.html) Sets the paint mode of the image to alternate between the image's current color and the new specified color. * [IsImagearrow-up-right](https://docs.lucee.org/reference/functions/isimage.html) Determines whether a variable returns a image. * [IsImageFilearrow-up-right](https://docs.lucee.org/reference/functions/isimagefile.html) Verifies whether an image file is valid. [PreviousFile Handlingchevron-left](https://modern-cfml.ortusbooks.com/beyond-the-100/file-handling) [NextHTTP/S Callschevron-right](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls) Last updated 2 years ago Was this helpful? Was this helpful? --- # Security Guide | Learn Modern ColdFusion in 100 Minutes Safeguarding your applications and data from attack requires addressing several important factors including server security, network security and code security. You can find all you need to know about securing your ColdFusion engines in the ColdFusion Security Guide at the most excellent [**cfdocs**arrow-up-right](https://cfdocs.org/security) website. Please visit it, follow it, live it! * [https://cfdocs.org/securityarrow-up-right](https://cfdocs.org/security) * [https://cfdocs.org/security-encryptionarrow-up-right](https://cfdocs.org/security%2Dencryption) * [https://cfdocs.org/security-obfuscationarrow-up-right](https://cfdocs.org/security%2Dobfuscation) * [https://cfdocs.org/security-session-managementarrow-up-right](https://cfdocs.org/security%2Dsession%2Dmanagement) [PreviousDependency Injectionchevron-left](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection) Last updated 2 years ago Was this helpful? Was this helpful? --- # Sending Emails | Learn Modern ColdFusion in 100 Minutes CFML gives you the `cfmail` tag/construct to easily send email in text or HTML format without any ceremony. Just register your mail servers in the administrators or the `Application.cfc` and you are ready to start sending emails in a jiffy! Copy cfmail( subject="Your Order", from="[email protected]", to="[email protected],[email protected]", bcc="[email protected]" type="HTML" ){ // body of the email. writeOutput( 'Hi there,' ); writeOutput( 'This mail is sent to confirm that we have received your order.' ); }; The `cfmail` tag/construct has tons of attributes, so check them out in the docs [https://cfdocs.org/cfmailarrow-up-right](https://cfdocs.org/cfmail) ### [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/sending-emails#query-binding) Query Binding You can even bind the mail construct with a query, and the engine will send as many emails as rows in the query for you: Copy var qData = userService.getNewUsers(); cfmail( subject="Welcome to FORGEBOX!", from="[email protected]", to="#qData.email#", query=qData ){ writeOutput( " Dear #qData.name#, Welcome to your FORGEBOX account! Play and just do it! ") }; ### [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/sending-emails#sending-attachments) Sending Attachments You can also send attachments to your email destinations very easily using the `mimeattach` attribute or via the child `cfmailparam()` construct, which allows you to send multiple attachments, or headers. circle-check More in-depth information can be found here: [https://helpx.adobe.com/coldfusion/developing-applications/using-external-resources/sending-and-receiving-e-mail/sending-e-mail-messages.htmlarrow-up-right](https://helpx.adobe.com/coldfusion/developing-applications/using-external-resources/sending-and-receiving-e-mail/sending-e-mail-messages.html) [PreviousHTTP/S Callschevron-left](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls) [NextAsynchronous Programmingchevron-right](https://modern-cfml.ortusbooks.com/beyond-the-100/asynchronous-programming) Last updated 2 years ago Was this helpful? * [Query Binding](https://modern-cfml.ortusbooks.com/beyond-the-100/sending-emails#query-binding) * [Sending Attachments](https://modern-cfml.ortusbooks.com/beyond-the-100/sending-emails#sending-attachments) Was this helpful? Copy cfmail( subject="Your Order", from="[email protected]", to="[email protected],[email protected]", bcc="[email protected]" mimeattach=expandPath( "/my/path/attach.pdf" ); ){ // body of the email. writeOutput( 'Hi there,' ); writeOutput( 'This mail is sent to confirm that we have received your order.' ); }; cfmail( subject="Attachments", to="[email protected]", from="[email protected]" ) { cfmailparam( name="Reply-To", value="[email protected]" ); cfmailparam( file="c:\files\readme.txt" ); cfmailparam( file="c:\files\logo.gif" ); } --- # Asynchronous Programming | Learn Modern ColdFusion in 100 Minutes We already covered basic threading in our core CFML section. In this section we will cover the usage of asynchronous programming via futures and the `runAsync()` function built-in to Adobe ColdFusion 2018+ and Lucee 5.3+. > A Future is an eventual result of an asynchronous operation. [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fdocs.oracle.com%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=2c78b630&sv=2)API reference for Java Platform, Standard Editiondocs.oracle.comchevron-right](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/Future.html) Java Future JDK (Useful Reference) [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fwww.adobe.com%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=40f989eb&sv=2)Asynchronous programminghelpx.adobe.comchevron-right](https://helpx.adobe.com/coldfusion/using/asynchronous-programming.html) Adobe Guide on RunAsync() [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/asynchronous-programming#runasync) runAsync() -------------------------------------------------------------------------------------------------------------- This function returns a **Future** object, which is an eventual result of an asynchronous operation. Basically a representation of what the operation will produce, well, in the future. It takes in two arguments and returns a CFML Future object. * `callback:function` - Closure/Lambda function that returns a result to be resolved * `timeout:numeric` - Timeout for the asynchronous process in milliseconds [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/asynchronous-programming#the-future-object) The Future Object ------------------------------------------------------------------------------------------------------------------------------ The return of the `runAsync()` function is a CFML Future, not a Java Future. The Future Object has the following functions available: Function ReturnType Description `cancel()` Boolean Cancel the operation `complete( value )` value Sets a value to return from the future, usually from an empty future operation. `error( callback, timeout )` Future Register an error callback that will be called if the async operation fails or the timeout is reached `error( callback )` Future Register an error callback that will be called if the async operation fails `get()` Any The value of the async operation once it finalizes. **Caution: This operation blocks until the async operation finalizes.** `get( timeout )` Any The value of the async operation with a timeout in milliseconds. **Caution: This operation blocks until the async operation finalizes.** `isCancelled()` Boolean Verifies if the operation has been cancelled or not `isDone()` Boolean Verifies if the operation has finalized or not `then( callback )` Future Once the first callback operation has finalized, call this secondary callback with the value of the previous operation and return another Future `then( callback, timeout )` Future Once the first callback operation has finalized, call this secondary callback with the value of the previous operation and return another Future but with a timeout circle-info All timeouts are in milliseconds With the future you can now create fluent functional programming constructs to deal with your async operation. You can create different error listeners and even continue processing the value the async operation produced in another asyncronous operation. Much like a pipeline of never ending futures! You can mix and match the callback functions to create a nice asyncronous pipeline. Just note that if you call the `get()` operation immediately that will BLOCK the execution until the async operation finalizes, which kinda defeats the purpose of the async operation. If you do not want to block, then use the `then()` approach, where that callback will be called for you with the result of the async operation and then you can do your post-processing. The alternative is to sit and poll the `isDone()` or `isCancelled()` operations, and YUCK! [PreviousSending Emailschevron-left](https://modern-cfml.ortusbooks.com/beyond-the-100/sending-emails) [NextMVCchevron-right](https://modern-cfml.ortusbooks.com/extra-credit/mvc) Last updated 2 years ago Was this helpful? * [runAsync()](https://modern-cfml.ortusbooks.com/beyond-the-100/asynchronous-programming#runasync) * [The Future Object](https://modern-cfml.ortusbooks.com/beyond-the-100/asynchronous-programming#the-future-object) Was this helpful? Copy future = runAsync( function(){ return "Hello World!"; } ); writeOutput( future.get() ); future = runAsync(function(){ return 5; } ).then( function( input ){ return input + 2; } ); result = future.get( 3 ); // 3 is timeout(in ms) writeOutput(result); Copy future = runAsync( function(){ return 5; }).then( function(input){ return input + 2; }).error( function(){ return "Error occurred."; }); result = future.get(); writeOutput(result); --- # MVC | Learn Modern ColdFusion in 100 Minutes [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#intro-to-mvc) Intro to MVC --------------------------------------------------------------------------------------------- ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFsbDu2J-_4YDdd-fE%252F-LLFsgeo-UspSoQGGkHe%252Fmvc-overview.png%3Falt%3Dmedia%26token%3Dd8bd82d5-f45a-4acc-88a8-cb8e6b74bf60&width=768&dpr=3&quality=100&sign=b5dca429&sv=2) > "A developer often wishes to separate data (model) and user interface (view) concerns, so that changes to the user interface will not affect data handling, and that the data can be reorganized without changing the user interface. The model-view-controller solves this problem by decoupling data access and business logic from data presentation and user interaction, by introducing an intermediate component: the controller." [Wikipediaarrow-up-right](http://en.wikipedia.org/wiki/Model-view-controller) > ​ MVC is a popular design pattern called [Model View Controllerarrow-up-right](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) which seeks to promote good maintainable software design by separating your code into 3 main tiers: * **Model** - Business Logic, Data, Queries, Etc * **View** - Representation of your models, queries, data. * **Controller** - Orchestrator of client request to the appropriate models and views Let's go a little deeper. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#model) Model The Model is the heart of your application. Your business logic should mostly live here in the form of services, beans, entities and DAOs. A dependency injection framework becomes invaluable when dealing with object oriented model layers: [**WireBox**arrow-up-right](https://wirebox.ortusbooks.com/) (Dependency Injection Framework) is the framework of choice for dependency injection and aspect oriented programming. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#views) Views The Views are what the users see and interact with. They are the templates used to render your application out for the web browser. Typically this means cfm/HTML, but it can also be JSON, XML, data views, etc. In modern times, your views can even be pure HTML with a combination of a JavaScript MVC framework. The major players in the MVC front-end world that we would recommend in order of personal preference: * **VueJS** - [https://vuejs.org/arrow-up-right](https://vuejs.org/) * **Angular** - [https://angular.io/arrow-up-right](https://angular.io/) * **ReactJS** - [https://reactjs.org/arrow-up-right](https://reactjs.org/) * **EmberJS** - [https://www.emberjs.com/arrow-up-right](https://www.emberjs.com/) ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#controllers) Controllers Controllers are the traffic cops of your application. They direct flow control, and interface directly without incoming parameters from FORM and URL scopes. It is the controller’s job to communicate with the appropriate models for processing, and set up either a view to display results or return serialized data like JSON, XML, PDF, etc. [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#benefits-of-mvc) Benefits of MVC --------------------------------------------------------------------------------------------------- By implementing an MVC Framework to your applications you will gain several benefits that come inherent to the MVC design pattern. The most important benefit of MVC is that you will be **separating the presentation** from the model. This is a very important heuristic of software development as [**separation of concerns**arrow-up-right](https://en.wikipedia.org/wiki/Separation_of_concerns) is applied and responsibilities are delegated upon the layers. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#separation-of-concerns) Separation of Concerns The model and the view layers have different concerns about their implementations. A view layer is concerned with how to render the data, the type of browser, or remote rendering, etc. While the model is more concerned with the business rules of the application, how to store data and even database operations. You use different development approaches to each layer. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#multiple-guis) Multiple GUI’s Due to this separation, you can easily create multiple views for the same model data without affecting how the model works or is coded. The view layers can adapt to the model by coding their own implementations. This makes it really easy to create multiple GUI’s for applications. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#unit-and-behavioral-testing) Unit and Behavioral Testing Non-visual objects are easier to test than visual objects, in theory. With the introduction of Selenium, integration and visual UI testing has become rather simple. However, the key benefit here is that testing can be done separately. Frameworks like ColdBox even give you the ability to do UI and integration testing within its domain. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#dependency) Dependency The most important benefit that we can arise out of the MVC pattern, is the direction of the dependencies. A view depends on its model data and controller, but the model itself does not depend on the view or controllers. This is how you want to build your business logic, encapsulated and providing a good API. [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#coldbox-mvc) Evolution of MVC Architecture ------------------------------------------------------------------------------------------------------------- There are many types of MVC architectures and hopefully the following diagrams can help you in the progression from spaghetti hell to the most complex MVC architecture using an [`ORM`arrow-up-right](https://en.wikipedia.org/wiki/Object-relational_mapping) or Object Relational Mapper. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#spaghetti-hell) Spaghetti Hell ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFyxr1P-gHw5YuEdQE%252F-LLFwoPuQaSbRv6nGYjH%252Fspaghetti-hell.png%3Falt%3Dmedia%26token%3D10ffe8ca-5eb7-4325-a95d-a6edc8b3b10c&width=768&dpr=3&quality=100&sign=54957486&sv=2) Spaghetti Hell As you can see from the spaghetti hell diagram above, everything is linear and can become extremely convoluted. Tracking bugs are difficult, maintenance suffers and reusability is not efficient. Everything is in the same bowl of soup. \--- ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#mvc) MVC ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFyxr1P-gHw5YuEdQE%252F-LLFx8QnCOoITiTOxayI%252Fmvc.png%3Falt%3Dmedia%26token%3D9958782c-077e-43ba-b6b2-d43c5e945bbf&width=768&dpr=3&quality=100&sign=73994613&sv=2) With the introduction of MVC we can hack away our spaghetti hell and at least have three distinct and separate layers of logic. Ahh much better. However, we can get even more complex. \--- ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#mvc-plus) MVC Plus ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFyxr1P-gHw5YuEdQE%252F-LLFxKz_BZHOeRB-DZeZ%252Fmvc-plus.png%3Falt%3Dmedia%26token%3D4098efb8-0387-4329-8189-147ba0741a37&width=768&dpr=3&quality=100&sign=e262499a&sv=2) MVC Plus MVC Plus shows us how you can further partition your model layer into more layers. We can identify now a layer of service CFCs and data access object CFCs. The main transportation of data between these layers by default is implied to be ColdFusion Query objects. \--- ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#mvc-plus-objects) MVC Plus Objects ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFyxr1P-gHw5YuEdQE%252F-LLFxocpS5dWNTAY6ZIb%252Fmvc-plus-objects.png%3Falt%3Dmedia%26token%3D5d1d3305-fd52-4cd5-8b98-8d8adef9421b&width=768&dpr=3&quality=100&sign=38216b2&sv=2) MVC Plus Objects In this architecture approach, we have replaced (mostly) queries as our data structure of preference and converted to the usage of business objects. We are approaching a more object oriented architectural style. Remember that data is just data, objects are data plus behavior. We can encapsulate more features and abstract more behavior into actual objects now, which we could not do with queries. \--- ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#mvc-plus-orm) MVC Plus ORM ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFyxr1P-gHw5YuEdQE%252F-LLFyAIqhSQ3wYh5xrO7%252Fmvc-plus-orm.png%3Falt%3Dmedia%26token%3D550af705-1002-4f49-b104-33e56de27da2&width=768&dpr=3&quality=100&sign=ac9a7dd2&sv=2) MVC Plus ORM In this architecture approach we have replaced business objects for ORM entities and replaced our data access layer to be controlled now by the ORM. This takes us very deep into object oriented land where the majority of our model is now modeled vi relational objects. triangle-exclamation **Stern Warning:** ORMs are NOT silver bullets. They are an incredible tool that must be used for the right reasons and at the right time. Do not be confused in that you must ONLY use the ORM. No, you can still use DAOs and queries for certain things that matter. You do not need to retrieve entire object graph collections if NOT needed. We have even build a companion package for ColdBox called [**cborm**arrow-up-right](https://github.com/coldbox-modules/cbox-cborm) that will help you build more pragmatic and enjoyable ORM applications. \--- [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#coldbox-mvc-1) MVC Frameworks for ColdFusion (CFML) ---------------------------------------------------------------------------------------------------------------------- Here are our recommendations: * **ColdBox MVC** - [https://www.coldbox.org/arrow-up-right](https://www.coldbox.org/) * **fw/1** - [https://github.com/framework-one/fw1arrow-up-right](https://github.com/framework-one/fw1) * **CFWheels** - [https://cfwheels.org/arrow-up-right](https://cfwheels.org/) ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#coldbox-mvc-2) ColdBox MVC ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFsbDu2J-_4YDdd-fE%252F-LLFwQp5Gv_MeuxHTjdp%252FColdBox.png%3Falt%3Dmedia%26token%3D47f06aa3-51c1-4092-9a6b-d697e19f7f4e&width=768&dpr=3&quality=100&sign=c1bcef1a&sv=2) ColdBox MVC Platform circle-info ColdBox has become the defacto platform for developing modern MVC ColdFusion applications and we are partial to it because we wrote it :) The ColdBox HMVC Platform is the de-facto enterprise-level HMVC framework for CFML developers. It's professionally backed, highly extensible, and productive. Getting started with ColdBox is quick and painless. The only thing you need to begin is [CommandBoxarrow-up-right](http://www.ortussolutions.com/products/commandbox) , a command line tool for CFML developers. You can check out our quick learning guides below: * **Quick Start Guide:** [https://coldbox.ortusbooks.com/getting-started/getting-started-guidearrow-up-right](https://coldbox.ortusbooks.com/getting-started/getting-started-guide) * **60 Minute Guide:** [https://coldbox.ortusbooks.com/for-newbies/60-minute-quick-startarrow-up-right](https://coldbox.ortusbooks.com/for-newbies/60-minute-quick-start) [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/mvc#resources) More Resources -------------------------------------------------------------------------------------------- * ​[http://en.wikipedia.org/wiki/Domain\_modelarrow-up-right](http://en.wikipedia.org/wiki/Domain_model) ​ * ​[http://domaindrivendesign.org/arrow-up-right](http://domaindrivendesign.org/) ​ * ​[http://martinfowler.com/eaaCatalog/domainModel.htmlarrow-up-right](http://martinfowler.com/eaaCatalog/domainModel.html) ​ [PreviousAsynchronous Programmingchevron-left](https://modern-cfml.ortusbooks.com/beyond-the-100/asynchronous-programming) [NextDependency Injectionchevron-right](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection) Last updated 2 years ago Was this helpful? * [Intro to MVC](https://modern-cfml.ortusbooks.com/extra-credit/mvc#intro-to-mvc) * [Model](https://modern-cfml.ortusbooks.com/extra-credit/mvc#model) * [Views](https://modern-cfml.ortusbooks.com/extra-credit/mvc#views) * [Controllers](https://modern-cfml.ortusbooks.com/extra-credit/mvc#controllers) * [Benefits of MVC](https://modern-cfml.ortusbooks.com/extra-credit/mvc#benefits-of-mvc) * [Separation of Concerns](https://modern-cfml.ortusbooks.com/extra-credit/mvc#separation-of-concerns) * [Multiple GUI’s](https://modern-cfml.ortusbooks.com/extra-credit/mvc#multiple-guis) * [Unit and Behavioral Testing](https://modern-cfml.ortusbooks.com/extra-credit/mvc#unit-and-behavioral-testing) * [Dependency](https://modern-cfml.ortusbooks.com/extra-credit/mvc#dependency) * [Evolution of MVC Architecture](https://modern-cfml.ortusbooks.com/extra-credit/mvc#coldbox-mvc) * [Spaghetti Hell](https://modern-cfml.ortusbooks.com/extra-credit/mvc#spaghetti-hell) * [MVC](https://modern-cfml.ortusbooks.com/extra-credit/mvc#mvc) * [MVC Plus](https://modern-cfml.ortusbooks.com/extra-credit/mvc#mvc-plus) * [MVC Plus Objects](https://modern-cfml.ortusbooks.com/extra-credit/mvc#mvc-plus-objects) * [MVC Plus ORM](https://modern-cfml.ortusbooks.com/extra-credit/mvc#mvc-plus-orm) * [MVC Frameworks for ColdFusion (CFML)](https://modern-cfml.ortusbooks.com/extra-credit/mvc#coldbox-mvc-1) * [ColdBox MVC](https://modern-cfml.ortusbooks.com/extra-credit/mvc#coldbox-mvc-2) * [More Resources](https://modern-cfml.ortusbooks.com/extra-credit/mvc#resources) Was this helpful? --- # HTTP/S Calls | Learn Modern ColdFusion in 100 Minutes CFML makes it really **easy** to interact with **any** HTTP/S endpoint via the `cfhttp` tag/construct ([https://cfdocs.org/cfhttparrow-up-right](https://cfdocs.org/cfhttp) ). The `cfhttp` call will generate an HTTP/S request and parse the response into a nice CFML structure. Copy cfhttp( url="https://www.google.com/", result="result" ){ cfhttpparam( name="q", type="formfield", value="cfml" ) } writeDump( result ) circle-info You can use ANY http method in the `cfhttp` calls, the default is a `GET` operation. As you can see from the example above, you can pass parameters to the HTTP request by using the child `cfhttpparam` construct. This parameter can be of many different types: `header, body, xml, cgi, file, url, formfield, cookie` depending on the requirements of the http endpoint. [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#the-result-structure) The Result Structure ---------------------------------------------------------------------------------------------------------------------- The result structure will contain the following keys: Key Description `statusCode` The HTTP response code and reason string. `fileContent` The body of the HTTP response. Usually a string, but could also be a Byte Array. `responseHeader` A structure of response headers, the keys are header names and the values are either the header value or an array of values if multiple headers with the same name exist. `errorDetail` An error message if applicable. `mimeType` The mime type returned in the Content-Type response header. `text` A boolean indicateing if the response body is text or binary `charset` The character set returned in the Content-Type header. `header` All the http response headers as a single string. [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#cfhttp-arguments) CFHTTP Arguments -------------------------------------------------------------------------------------------------------------- This construct accepts many arguments with different features you can use when executing http/s calls, below we list just the most common ones, you can find them all here: [https://cfdocs.org/cfhttparrow-up-right](https://cfdocs.org/cfhttp) Argument Type Default Description `url` URL The http/s endpoint to hit `port` numeric 80/443 The port of the endpoint to hit. 80 for http and 443 for https `method` string GET The http method to use. `username` string An optional server username `password` string An optional server password `useragent` string ColdFusion The user agent to simulate for the request `charset` string utf-8 The encoding to use `resolveUrl` boolean false No does not resolve URLs in the response body. As a result, any relative URL links in the response body do not work. Yes resolves URLs in the response body to absolute URLs, including the port number, so that links in a retrieved page remain functional. `redirect` boolean true If the response header includes a [Locationarrow-up-right](https://cfdocs.org/location) field, determines whether to redirect execution to the URL specified in the field. `timeout` numeric unlimited A value in seconds of the max time to take for the request. `getAsBinary` string auto If **yes**, convert to CFML binary type, **No** keep as text, **auto** let CFML detect and convert as necessary `result` string cfhttp The name of the variable you want the result structured returned into `multipart` boolean false Tells ColdFusion to send all data specified by [cfhttpparamarrow-up-right](https://cfdocs.org/cfhttpparam) type="formField" tags as multipart form data, with a Content-Type of multipart/form-data. Basically, you can do any type of http/s calls and consume any type of RESTFul webservices with a nice CFML syntax! [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#cfhttpparam) CFHTTPParam ---------------------------------------------------------------------------------------------------- As mentioned before in our example we can use the `cfhttpparam` construct to pass parameters to the http/s endpoint. The parameters can be of different types as we can see in the following table. ### [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#param-types) Param Types Type Description `header` Specifies an HTTP header. Does not URL encode the value `body` Specifies that the `value` is the body of the HTTP request. `xml` Identifies the request as having a content-type of `text/xml` and specifies that the `value` attribute contains the body of the HTTP request. `cgi` Same as `header` but URL encodes the `value` by default. `file` Tells CFML to send the contents of the specified file. `url` Specifies a URL query string name-value pair to append to the [cfhttparrow-up-right](https://cfdocs.org/cfhttp) url attribute. URL encodes the value. `formfield` Specifies a form field to send. URL encodes the value by default. `cookie` Specifies a cookie to send as an HTTP header. URL encodes the value. ### [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#param-arguments) Param Arguments The available param arguments to the cfhttpparam construct are: Argument Type Default Description `type` string The type of data from the available types above `name` string The variable name for the data `value` string The value of the variable `file` path Applies to `file` type; ignored for all other types. The absolute path to the file that is sent with the request. `encoded` boolean false Applies to `formfield` and `cgi` types; ignored for all other types. Specifies whether to [URLEncodearrow-up-right](https://cfdocs.org/urlencode) the form field or header. `mimetype` string Applies to `file` type; invalid for all other types. Specifies the MIME media type of the file contents. The content type can include an identifier for the character encoding of the file; for example, text/html; charset=ISO-8859-1 indicates that the file is HTML text in the ISO Latin-1 character encoding. Here is another example for you: [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#hyper-http-builder) Hyper : HTTP Builder -------------------------------------------------------------------------------------------------------------------- Leveraging `cfhttp` is very very easy to use. However, it can be cumbersome and not necessarily fluent or object oriented. For this, we have provided a module called [Hyperarrow-up-right](https://forgebox.io/view/hyper) which can help you build fluent and amazing HTTP Builders ([https://forgebox.io/view/hyperarrow-up-right](https://forgebox.io/view/hyper) ) Hyper was built after coding several API SDK's for various platforms — [S3SDKarrow-up-right](https://github.com/coldbox-modules/s3sdk) , [cbstripearrow-up-right](https://github.com/coldbox-modules/cbox-stripe) , and [cbgithubarrow-up-right](https://github.com/elpete/cbgithub) , to name a few. I noticed that I spent a lot of time setting up the plumbing for the requests and a wrapper around `cfhttp`. Each implementation was mostly the same but slightly different. It was additionally frustrating because I really only needed to tweak a few values, usually just the `Authorization` header. It would be nice to create an HTTP client pre-configured for each of these SDK's. It seemed the perfect fit for a module. ### [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#the-problem-it-solves) The problem it solves Hyper exists to provide a fluent builder experience for HTTP requests and responses. It also provides a powerful way to create clients, Bulider objects with pre-configured defaults like a base URL or certain headers. ### [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#hyperbuilder) HyperBuilder The component you will most likely inject is the `HyperBuilder`. This is commonly aliased as `hyper`. The `HyperBuilder` creates new requests. This can be done in one of two ways: 1. Calling the `new` method will create a new request with the configured defaults. 2. Calling any method on `HyperRequest` on the `HyperBuilder` instance will create a new request and forward on the method call. Using the `HyperBuilder` lets you easily create requests with defaults while also avoiding having to deal with providers directly. ### [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#hyperrequest) HyperRequest Though the `HyperBuilder` is the component you will most likely inject, `HyperRequest` is the component will you interact with the most. `HyperRequest` provides a fluent interface to configure your HTTP call. **Example:** ### [hashtag](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#request-defaults) Request Defaults Hyper allows you to configure defaults for your requests. This is particularly useful for reducing boilerplate in your application. Defaults are set on the `HyperBuilder` instance. The easiest way to do this is to configure it in WireBox: Now, you can inject this pre-configured builder wherever you need in your application: You can even create multiple clients using this approach: You can also set or change the defaults by either passing the key / value pairs in to the `init` method or by calling the appropriate `HyperRequest` method on the `HyperBuilder.defaults` property. [PreviousImage Manipulationchevron-left](https://modern-cfml.ortusbooks.com/beyond-the-100/image-manipulation) [NextSending Emailschevron-right](https://modern-cfml.ortusbooks.com/beyond-the-100/sending-emails) Last updated 2 years ago Was this helpful? * [The Result Structure](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#the-result-structure) * [CFHTTP Arguments](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#cfhttp-arguments) * [CFHTTPParam](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#cfhttpparam) * [Param Types](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#param-types) * [Param Arguments](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#param-arguments) * [Hyper : HTTP Builder](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#hyper-http-builder) * [The problem it solves](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#the-problem-it-solves) * [HyperBuilder](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#hyperbuilder) * [HyperRequest](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#hyperrequest) * [Request Defaults](https://modern-cfml.ortusbooks.com/beyond-the-100/http-calls#request-defaults) Was this helpful? Copy cfhttpParam( type="", name="", value="", file="", encoded="", mimetype="" ); Copy cfhttp( url="https://myrestapp.com/user", result="local.result", method="post" ){ cfhttpparam( name="x-api-token", type="header", value="123" ) cfhttpparam( type="body", value=serializeJson( '{ name : "luis", age : 2 }' ) ) } writeDump( result ) Copy component { property name="hyper" inject="HyperBuilder@Hyper"; } Copy hyper.get( "https//api.github.com/users" ); hyper.setMethod( "PUT" ) .withHeaders( { "Authorization" = "Bearer #token#" } ) .setUrl( "https://jsonplaceholder.typicode.com/posts/1" ) .setBody( { title: "New Title" } ) .send(); Copy // config/WireBox.cfc component { function configure() { map( "StarWarsClient" ) .to( "hyper.models.HyperBuilder" ) .asSingleton() .initWith( baseUrl = "https://swapi.co/api" ); } } Copy component { property name="StarWarsClient" inject="id"; function findUser( id ) { return StarWarsClient.get( "/people/#id#" ); } } Copy // config/WireBox.cfc component { function configure() { map( "SWAPIClient" ) .to( "hyper.models.HyperBuilder" ) .asSingleton() .initWith( baseUrl = "https://swapi.co/api" ); map( "GitHubClient" ) .to( "hyper.models.HyperBuilder" ) .asSingleton() .initWith( baseUrl = "https://api.github.com", headers = { "Authorization" = getSetting( "SWAPI_TOKEN" ) } ); } } Copy var hyper = new Hyper.models.HyperBuilder( baseUrl = "https://api.github.com" ); hyper.defaults.withHeaders( { "Authorization" = token } ); --- # Dependency Injection | Learn Modern ColdFusion in 100 Minutes > Dependency injection is the art of making work come home to you. Dhanji R. Prasanna **In ColdFusion, WireBox is the standard when it comes to Dependency Injection and Aspect Oriented Programming (AOP).** ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LgITV5QGVZ7QzTIxEEv%252F-LgIULB5RA_cLjZK7o5m%252Fassets_-LA-UVvsc-e1GVkiaPQ-_-LA-Ud03e_n2SeqLC9Ls_-LA-UrvQwgjVsSA_J5pT_WireBox.png%3Falt%3Dmedia%26token%3D70616df6-28f5-474d-843a-3427b4b714c8&width=768&dpr=3&quality=100&sign=af0f5368&sv=2) WireBox alleviates the need for custom object factories or manual object creation in your ColdFusion (CFML) applications. It provides a **standardized** approach to object **construction** and **assembling** that will make your code easier to adapt to changes, easier to [test, mockarrow-up-right](https://testbox.ortusbooks.com/) and extend. circle-info You can read all about WireBox here: [https://wirebox.ortusbooks.com/arrow-up-right](https://wirebox.ortusbooks.com/) As software developers we are always challenged with maintenance and one ever occurring annoyance, **change**. Therefore, the more sustainable and maintainable our software, the more we can concentrate on real problems and make our lives more productive. WireBox leverages an array of metadata annotations to make your object assembling, storage and creation easy as pie! We have leveraged the power of event driven architecture via object listeners or interceptors so you can extend not only WireBox but the way objects are analyzed, created, wired and much more. To the extent that our [AOP arrow-up-right](https://wirebox.ortusbooks.com/aspect-oriented-programming/aop-intro) capabilities are all driven by our AOP listener which decouples itself from WireBox code and makes it extremely flexible. [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#dependency-injection-explained) Dependency Injection Explained -------------------------------------------------------------------------------------------------------------------------------------------------- We have released one of our chapters from our [CBOX202: Dependency Injectionarrow-up-right](https://www.ortussolutions.com/learn) course that deals with getting started with Dependency Injection, the problem, the benefits and the solutions. We encourage you to download it, print it, share it, digest it and learn it: [http://ortus-public.s3.amazonaws.com/cbox202-unit1-3.pdfarrow-up-right](http://ortus-public.s3.amazonaws.com/cbox202-unit1-3.pdf) circle-check If you require any training please [contact usarrow-up-right](https://www.ortussolutions.com/learn) . [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#advantages-of-a-di-framework) Advantages of a DI Framework ---------------------------------------------------------------------------------------------------------------------------------------------- Compared to manual Dependency Injection (DI), using WireBox can lead to the following advantages: * You will write less boilerplate code. * By giving WireBox DI responsibilities, you will stop creating objects manually or using custom object factories. * You can leverage object persistence scopes for performance and scalability. Even create time persisted objects. * You will not have any object creation or wiring code in your application, but have it abstracted via WireBox. Which will lead to more cohesive code that is not plagued with boilerplate code or factory code. * Objects will become more testable and easier to mock, which in turn can accelerate your development by using a TDD (Test Driven Development), BDD (Behavior Driven Development) approach. * Once WireBox leverages your objects you can take advantage of AOP or other event life cycle processes to really get funky with Object Orientation. [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#features-at-a-glance) Features at a Glance ------------------------------------------------------------------------------------------------------------------------------ Here are a simple listing of features WireBox brings to the table: * Annotation driven dependency injection * 0 configuration mode or a programmatic binder configuration approach via ColdFusion (No XML!) * Creation and Wiring of or by: * ColdFusion Components * Java Classes * RSS Feeds * WebService objects * Constant values * DSL string building * Factory Methods * Providers * Multiple Injection Styles: Property, Setter, Method, Constructor * Automatic Package/Directory object scanning and registration * Multiple object life cycle persistence scopes: * No Scope (Transients) * Singletons * Request Scoped * Session Scoped * Application Scoped * Server Scoped * CacheBox Scoped * Integrated caching via [CacheBoxarrow-up-right](https://cachebox.ortusbooks.com/) , scale your objects and metadata * Integrated logging via [LogBoxarrow-up-right](https://logbox.ortusbooks.com/) , never try to figure out what in the world the DI engine is doing * Parent Factories * Factory Method Object Creations * Object life cycle events via WireBox Listeners/Interceptors * Customizable injection DSL * WireBox object providers to avoid scope-widening issues on time/volatile persisted objects * [Aspect Oriented Programmingarrow-up-right](https://wirebox.ortusbooks.com/aspect-oriented-programming/aop-intro) [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#di-basics) DI Basics -------------------------------------------------------------------------------------------------------- ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#injection-styles) Injection Styles There are three ways that DI frameworks can inject dependencies into object references: 1. Constructor Arguments 2. Setter Methods 3. Property Injections Each has it's own set of pros and cons. However, the important aspect of the injection types is the order it happens. Please refer back to the list above for order reference. Here is a component leveraging all three styles, what similarities do you notice in all of them? ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#injection-annotation) Injection Annotation All the injection styles have a marker called `inject` which can contain a value, this value is called the [Injection DSLarrow-up-right](https://wirebox.ortusbooks.com/usage/injection-dsl) . This basically tells WireBox what alias to inject into the component. The value of the injection DSL can mean different things to WireBox depending on the environment, registered custom dsl's and so much more. However, at the end of the day, it means, inject something here!! circle-info Please note that we have shown you the easiest approach to DI by leveraging annotations. If you do not like annotating your code and prefer a configuration approach; No Problem. WireBox offers a [configuration Binderarrow-up-right](https://wirebox.ortusbooks.com/configuration/configuring-wirebox) where you can declare all your objects explicitly with all their dependencies and persistence. Let's digest a few examples: The `inject="UserService"` will look for an object with that alias if it doesn't find it with the alias, it treats is like a CFC path and tries to create, inject and return that object. This inject DSL is spaced by colons (:) and tells WireBox the following: * Look for the `logbox` DSL * Ask for a `logger` * Map it to `{this}` class As you are starting to see, the injection DSL can be very powerful. The `@myservice.inject` annotation for the constructor argument tells WireBox to look for the `id` of `MyAwesomeService` and pass it as the argument. Again, the colon is the separator of choice for DSLs. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#persistence) Persistence WireBox by default treats all objects it creates as transient objects. Meaning it will create it, inject it and return it. After usage it get's destroyed automatically by the JVM. If you want longer persistence for the objects you can [annotate them with a scopearrow-up-right](https://wirebox.ortusbooks.com/configuration/component-annotations/persistence-annotations) or shortcut annotations like the `singleton` annotation. Available scopes are: * `NOSCOPE` : Transient objects * `PROTOTYPE` : Transient objects * `SINGLETON` : Objects constructed only once and stored in the injector * `SESSION` : ColdFusion session scoped based objects * `APPLICATION` : ColdFusion application scope based objects * `REQUEST` : ColdFusion request scope based objects * `SERVER` : ColdFusion server scope based objects * `CACHEBOX` : CacheBox scoped objects ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#usage) Usage Ok, we have seen how to construct our objects according to DI principles, but how do we now use them? There are two modes of operation: * Standalone * ColdBox Application WireBox is part of the ColdBox HMVC framework, so you can leverage DI/AOP out of the box with no configuration or startup code. If you are NOT using ColdBox then you can use WireBox in standalone mode like shown below: triangle-exclamation Please note that by default the WireBox injector once initialized it will be scoped into application scope automatically for you as: `application.wirebox` The main method to retrieve objects is called `getInstance()` and you can see the signature below: That's it! You can now start rolling with dependency injection in your applications. We highly encourage you to visit our [ColdBox documentationarrow-up-right](https://coldbox.ortusbooks.com/the-basics/models) or the standalone [WireBox documentationarrow-up-right](https://wirebox.ortusbooks.com/) for more in-depth analysis of dependency injection. We have only touched the surface. [hashtag](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#useful-resources) Useful Resources ---------------------------------------------------------------------------------------------------------------------- * [http://code.google.com/p/google-guicearrow-up-right](http://code.google.com/p/google-guice) * [http://www.manning.com/prasanna/arrow-up-right](http://www.manning.com/prasanna/) * [http://en.wikipedia.org/wiki/Aspect-oriented\_programmingarrow-up-right](http://en.wikipedia.org/wiki/Aspect-oriented_programming) * [http://en.wikipedia.org/wiki/Dependency\_injectionarrow-up-right](http://en.wikipedia.org/wiki/Dependency_injection) * [http://en.wikipedia.org/wiki/Inversion\_of\_controlarrow-up-right](http://en.wikipedia.org/wiki/Inversion_of_control) * [http://martinfowler.com/articles/injection.htmlarrow-up-right](http://martinfowler.com/articles/injection.html) * [http://www.theserverside.com/news/1321158/A-beginners-guide-to-Dependency-Injectionarrow-up-right](http://www.theserverside.com/news/1321158/A-beginners-guide-to-Dependency-Injection) * [http://www.developer.com/net/net/article.php/3636501arrow-up-right](http://www.developer.com/net/net/article.php/3636501) * [http://code.google.com/p/google-guice/arrow-up-right](http://code.google.com/p/google-guice/) [PreviousMVCchevron-left](https://modern-cfml.ortusbooks.com/extra-credit/mvc) [NextSecurity Guidechevron-right](https://modern-cfml.ortusbooks.com/extra-credit/security-guide) Last updated 2 years ago Was this helpful? * [Dependency Injection Explained](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#dependency-injection-explained) * [Advantages of a DI Framework](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#advantages-of-a-di-framework) * [Features at a Glance](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#features-at-a-glance) * [DI Basics](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#di-basics) * [Injection Styles](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#injection-styles) * [Injection Annotation](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#injection-annotation) * [Persistence](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#persistence) * [Usage](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#usage) * [Useful Resources](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection#useful-resources) Was this helpful? Copy component singleton{ // Property injection property name="userService" inject="UserService"; property name="log" inject="logbox:logger:{this}"; /** * Constructor Injection * * @myService.inject id:MyAwesomeService * */ function init( required myService ){ variables.myService = arguments.myService; return this; } function setMySecurityService( required service ) inject="SecurityService@api"{ varaiables.securityService = arguments.service; return this; } } Copy property name="userService" inject="UserService"; Copy property name="log" inject="logbox:logger:{this}"; Copy /** * Constructor Injection * * @myService.inject id:MyAwesomeService * */ function init( required myService ){ } Copy // Transient component{} // Singleton component singleton{} // Core or Custom Scope component scope="cachebox" Copy // Create the WireBox Main injector wirebox = new wirebox.system.ioc.Injector(); // Create it with a configuration Binder wirebox = new wirebox.system.ioc.Injector( "myBinderPath" ); // Get an object wirebox.getInstance( "MyService" ); wirebox.getInstance( "my.path.to.Service" ); Copy /** * Locates, Creates, Injects and Configures an object model instance * * @name The mapping name or CFC instance path to try to build up * @dsl The dsl string to use to retrieve the instance model object, mutually exclusive with 'name * @initArguments The constructor structure of arguments to passthrough when initializing the instance * @initArguments.doc_generic struct * @targetObject The object requesting the dependency, usually only used by DSL lookups **/ function getInstance( name, dsl, struct initArguments = structNew(), targetObject="" ) --- # Welcome | Learn Modern ColdFusion in 100 Minutes Welcome to the wonderful world of dynamic programming with ColdFusion (CFML). This book aims to jump-start developers into the ColdFusion (CFML) programming language from a modern perspective and focus on best practices, object orientation, and tooling. ColdFusion is not the same as it was 20 years ago; yes, it's more than 20 years old! It's dynamic, vibrant, modern, fluent, and functional! Let's begin our adventure into the world of MODERN ColdFusion (CFML). circle-info This book is inspired by the original [Ruby in 100 minutesarrow-up-right](http://tutorials.jumpstartlab.com/projects/ruby_in_100_minutes.html) , [Mike Henke's work on CFML in 100 minutesarrow-up-right](https://github.com/mhenke/CFML-in-100-minutes/wiki) , and [Learn CF in a week seriesarrow-up-right](http://www.learncfinaweek.com/) . [hashtag](https://modern-cfml.ortusbooks.com/intro#coldfusion-vs.-cfml) ColdFusion vs. CFML ------------------------------------------------------------------------------------------------ Let's get this ambiguity out of the way. **ColdFusion** is the server product, and **CFML** is the language, short for **C**old**F**usion **M**arkup **L**anguage. In turn, ColdFusion is actually the platform or framework in which CFML scripts are executed. It is similar to the relationship between HTML and a web browser like IE, Firefox, or Safari. More information at: [http://www.differencebetween.net/technology/communication-technology/difference-between-cfml-and-coldfusion/arrow-up-right](http://www.differencebetween.net/technology/communication-technology/difference-between-cfml-and-coldfusion/) CFML will execute in a ColdFusion engine. [PreviousIntroductionchevron-left](https://modern-cfml.ortusbooks.com/) [NextAuthorchevron-right](https://modern-cfml.ortusbooks.com/intro/intro/author) Last updated 1 year ago Was this helpful? --- # Syntax | Learn Modern ColdFusion in 100 Minutes There are two ways to write CFML code: in **tags** or in **script** syntax. Modern CFML will dictate that your view or presentation layers will utilize the **tag** syntax in `cfm` files, and the model or business layers will all be done in **script** syntax in `cfc` files. (MVC comes later). There are no differences in functionality between them; it's pure syntax. * CFScript Syntax Guide - [https://cfdocs.org/scriptarrow-up-right](https://cfdocs.org/script) [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#syntax-files) Syntax Files ------------------------------------------------------------------------------------------ CFML includes a set of instructions you use on pages (`.cfm`) or components (classes -`cfc`). You will write one or more instructions in a file (`.cfm,.cfc`) then run the file through a CFML engine or Command Line Interpreter like CommandBox. * `cfm` - ColdFusion markup file, tag syntax is the default and used for views * `cfc` - The default is the ColdFusion Component file (Class or Object), script syntax. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#implicit-behavior) Implicit Behavior ---------------------------------------------------------------------------------------------------- CFML also gives you a pre-set of defined [tagsarrow-up-right](https://cfdocs.org/tags) and [functionsarrow-up-right](https://cfdocs.org/functions) available to you in any file you write your code in. These tags and functions allow you to extend the typical language constructs with many modern capabilities, from database interaction to PDF generation. They are basically automatic imports. circle-check **Tip:** Please note that the CFML built-in functions are also **first-class functions** so that they can be passed around as arguments to other functions or closures or saved as variables. [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#exploring-behavior) Exploring Behavior ------------------------------------------------------------------------------------------------------ Three CFML instructions we will use in this section are `cfset`, `cfoutput`, and `cfdump`. * `cfset` is used to create a variable and assign it a value. * `cfoutput` displays a variable's value to the output stream. * `cfdump` is used to display the contents of simple and complex variables, objects, components, user-defined functions, and other elements to the output stream. We might have a file named _myprogram.cfm_ and _Sample.cfc_ like this: ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#tag-syntax) Tag Syntax myprogram.cfm Copy #s.hello()# ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#script-syntax) Script Syntax myprogram.cfm Copy s = new Sample(); writeOutput( s.hello() ); circle-check **Tip:** Please note that if you want to write in script in a tag-based file, you must use an opening and closing `` tag. Sample.cfc Copy component{ function hello(){ return "Hello, World!"; } } Please note that no types and not even any visibility scopes you might be used to are present. CFML can also infer variable types on more distinct variables like dates, booleans, or numbers. However, please note that you can fully leverage types if you like: Sample.cfc Copy component{ public string function hello(){ return "Hello, World!"; } } circle-check By default, the return type of every function and/or argument is **any**. Thus, it can be determined at runtime as a dynamic variable. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#semi-colons) Semi-Colons Please note that semi-colons are used to demarcate line endings in CFML `;`. However, the Lucee Server engine and Adobe ColdFusion 2018+ treat semi-colons as optional, while Adobe ColdFusion 2016 or below does not. Also, note the CommandBox REPL does NOT require semi-colons. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#tags-in-script) Tags In Script Lucee and Adobe ColdFusion 11+ will allow you to write your CFML tags in script syntax. You basically eliminate the starting `<` and ending `>` enclosures and create a block by using the `{` and `}` mustaches. Copy cfhttp(method="GET", charset="utf-8", url="https://www.google.com/", result="result") { cfhttpparam(name="q", type="formfield", value="cfml"); } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#polyglot-references) Polyglot References -------------------------------------------------------------------------------------------------------- As we now live in a world of polyglot developers, we have added references below to other languages to see the differences and similarities between CFML and other major languages in usage today. Please note that this section is merely academic and to help developers from other language backgrounds to understand the intricacies of the ColdFusion (CFML) syntax. ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#php-syntax) PHP Syntax myprogram.php Copy hello(); ?> Sample.php Copy ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#ruby-syntax) Ruby Syntax myprogram.rb Copy class Sample def hello "Hello, World!" end end s = Sample.new puts s.hello ### [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#java-syntax) Java Syntax MyProgram.java Copy public class MyProgram { public String hello(){ return "Hello, world!"; } public static void main(String[] args) { System.out.println( new MyProgram().hello() ); } } [hashtag](https://modern-cfml.ortusbooks.com/cfml-language#coding-standards) Coding Standards -------------------------------------------------------------------------------------------------- At [Ortus Solutionsarrow-up-right](https://www.ortussolutions.com/) , we have developed a set of development standards for many languages. You can find our standards here: [https://github.com/Ortus-Solutions/coding-standardsarrow-up-right](https://github.com/Ortus-Solutions/coding-standards) . [PreviousInstructions & Interpreterschevron-left](https://modern-cfml.ortusbooks.com/intro/instructions-and-interpreters) [NextCommentschevron-right](https://modern-cfml.ortusbooks.com/cfml-language/comments) Last updated 2 years ago Was this helpful? --- # Beyond The 100 | Learn Modern ColdFusion in 100 Minutes We cannot possibly cover all the features of the ColdFusion Engines in this book as our focus was more on the core CFML language. However, please note that the engines offer a tremendous middle-ware capabilities that extend beyond normal language features. There are many areas that make ColdFusion one of the most (if not the most) **rapid application development (RAD)** languages around. circle-check Check out the [cfdocsarrow-up-right](https://cfdocs.org/) and the engine documentation sites for all the different capabilities they can offer. In our **Beyond The 100** section you will find more in-depth topics of how CFML can be used for web applications, database interactions, Java integration, RESTFul services_,_ Image manipulation and much more. Here is a simple listing of going beyond with CFML: * PDF Creation * PDF Manipulation * Database Introspection * Object Relational Manager via Hibernate/JPA * Stored Procedures Support * Multiple JDBC Connectors * Job Scheduling * Server Monitoring * API Monitoring, Caching, Gateway * Exchange Support * LDAP Support * Spreadsheet Support * Open Office Support * Mathematical Functions * OSGI Bundle Support * Distributed Caching Support * Much More! [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fdocs.lucee.org%2Fassets%2Fimages%2Ffavicon.png&width=20&dpr=3&quality=100&sign=51451920&sv=2)Lucee Documentationlucee\_serverchevron-right](https://docs.lucee.org/index.html) [![Logo](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2Fwww.adobe.com%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=40f989eb&sv=2)Adobe ColdFusion Learn & Supporthelpx.adobe.comchevron-right](https://helpx.adobe.com/support/coldfusion.html) [PreviousJava Integrationchevron-left](https://modern-cfml.ortusbooks.com/cfml-language/java-integration) [NextApplication.cfcchevron-right](https://modern-cfml.ortusbooks.com/beyond-the-100/applicationcfc) Last updated 2 years ago Was this helpful? --- # MVC | Learn Modern ColdFusion in 100 Minutes [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#intro-to-mvc) Intro to MVC ----------------------------------------------------------------------------------------- ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFsbDu2J-_4YDdd-fE%252F-LLFsgeo-UspSoQGGkHe%252Fmvc-overview.png%3Falt%3Dmedia%26token%3Dd8bd82d5-f45a-4acc-88a8-cb8e6b74bf60&width=768&dpr=3&quality=100&sign=b5dca429&sv=2) > "A developer often wishes to separate data (model) and user interface (view) concerns, so that changes to the user interface will not affect data handling, and that the data can be reorganized without changing the user interface. The model-view-controller solves this problem by decoupling data access and business logic from data presentation and user interaction, by introducing an intermediate component: the controller." [Wikipediaarrow-up-right](http://en.wikipedia.org/wiki/Model-view-controller) > ​ MVC is a popular design pattern called [Model View Controllerarrow-up-right](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) which seeks to promote good maintainable software design by separating your code into 3 main tiers: * **Model** - Business Logic, Data, Queries, Etc * **View** - Representation of your models, queries, data. * **Controller** - Orchestrator of client request to the appropriate models and views Let's go a little deeper. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#model) Model The Model is the heart of your application. Your business logic should mostly live here in the form of services, beans, entities and DAOs. A dependency injection framework becomes invaluable when dealing with object oriented model layers: [**WireBox**arrow-up-right](https://wirebox.ortusbooks.com/) (Dependency Injection Framework) is the framework of choice for dependency injection and aspect oriented programming. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#views) Views The Views are what the users see and interact with. They are the templates used to render your application out for the web browser. Typically this means cfm/HTML, but it can also be JSON, XML, data views, etc. In modern times, your views can even be pure HTML with a combination of a JavaScript MVC framework. The major players in the MVC front-end world that we would recommend in order of personal preference: * **VueJS** - [https://vuejs.org/arrow-up-right](https://vuejs.org/) * **Angular** - [https://angular.io/arrow-up-right](https://angular.io/) * **ReactJS** - [https://reactjs.org/arrow-up-right](https://reactjs.org/) * **EmberJS** - [https://www.emberjs.com/arrow-up-right](https://www.emberjs.com/) ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#controllers) Controllers Controllers are the traffic cops of your application. They direct flow control, and interface directly without incoming parameters from FORM and URL scopes. It is the controller’s job to communicate with the appropriate models for processing, and set up either a view to display results or return serialized data like JSON, XML, PDF, etc. [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#benefits-of-mvc) Benefits of MVC ----------------------------------------------------------------------------------------------- By implementing an MVC Framework to your applications you will gain several benefits that come inherent to the MVC design pattern. The most important benefit of MVC is that you will be **separating the presentation** from the model. This is a very important heuristic of software development as [**separation of concerns**arrow-up-right](https://en.wikipedia.org/wiki/Separation_of_concerns) is applied and responsibilities are delegated upon the layers. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#separation-of-concerns) Separation of Concerns The model and the view layers have different concerns about their implementations. A view layer is concerned with how to render the data, the type of browser, or remote rendering, etc. While the model is more concerned with the business rules of the application, how to store data and even database operations. You use different development approaches to each layer. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#multiple-guis) Multiple GUI’s Due to this separation, you can easily create multiple views for the same model data without affecting how the model works or is coded. The view layers can adapt to the model by coding their own implementations. This makes it really easy to create multiple GUI’s for applications. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#unit-and-behavioral-testing) Unit and Behavioral Testing Non-visual objects are easier to test than visual objects, in theory. With the introduction of Selenium, integration and visual UI testing has become rather simple. However, the key benefit here is that testing can be done separately. Frameworks like ColdBox even give you the ability to do UI and integration testing within its domain. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#dependency) Dependency The most important benefit that we can arise out of the MVC pattern, is the direction of the dependencies. A view depends on its model data and controller, but the model itself does not depend on the view or controllers. This is how you want to build your business logic, encapsulated and providing a good API. [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#coldbox-mvc) Evolution of MVC Architecture --------------------------------------------------------------------------------------------------------- There are many types of MVC architectures and hopefully the following diagrams can help you in the progression from spaghetti hell to the most complex MVC architecture using an [`ORM`arrow-up-right](https://en.wikipedia.org/wiki/Object-relational_mapping) or Object Relational Mapper. ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#spaghetti-hell) Spaghetti Hell ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFyxr1P-gHw5YuEdQE%252F-LLFwoPuQaSbRv6nGYjH%252Fspaghetti-hell.png%3Falt%3Dmedia%26token%3D10ffe8ca-5eb7-4325-a95d-a6edc8b3b10c&width=768&dpr=3&quality=100&sign=54957486&sv=2) Spaghetti Hell As you can see from the spaghetti hell diagram above, everything is linear and can become extremely convoluted. Tracking bugs are difficult, maintenance suffers and reusability is not efficient. Everything is in the same bowl of soup. \--- ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#mvc) MVC ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFyxr1P-gHw5YuEdQE%252F-LLFx8QnCOoITiTOxayI%252Fmvc.png%3Falt%3Dmedia%26token%3D9958782c-077e-43ba-b6b2-d43c5e945bbf&width=768&dpr=3&quality=100&sign=73994613&sv=2) With the introduction of MVC we can hack away our spaghetti hell and at least have three distinct and separate layers of logic. Ahh much better. However, we can get even more complex. \--- ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#mvc-plus) MVC Plus ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFyxr1P-gHw5YuEdQE%252F-LLFxKz_BZHOeRB-DZeZ%252Fmvc-plus.png%3Falt%3Dmedia%26token%3D4098efb8-0387-4329-8189-147ba0741a37&width=768&dpr=3&quality=100&sign=e262499a&sv=2) MVC Plus MVC Plus shows us how you can further partition your model layer into more layers. We can identify now a layer of service CFCs and data access object CFCs. The main transportation of data between these layers by default is implied to be ColdFusion Query objects. \--- ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#mvc-plus-objects) MVC Plus Objects ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFyxr1P-gHw5YuEdQE%252F-LLFxocpS5dWNTAY6ZIb%252Fmvc-plus-objects.png%3Falt%3Dmedia%26token%3D5d1d3305-fd52-4cd5-8b98-8d8adef9421b&width=768&dpr=3&quality=100&sign=38216b2&sv=2) MVC Plus Objects In this architecture approach, we have replaced (mostly) queries as our data structure of preference and converted to the usage of business objects. We are approaching a more object oriented architectural style. Remember that data is just data, objects are data plus behavior. We can encapsulate more features and abstract more behavior into actual objects now, which we could not do with queries. \--- ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#mvc-plus-orm) MVC Plus ORM ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFyxr1P-gHw5YuEdQE%252F-LLFyAIqhSQ3wYh5xrO7%252Fmvc-plus-orm.png%3Falt%3Dmedia%26token%3D550af705-1002-4f49-b104-33e56de27da2&width=768&dpr=3&quality=100&sign=ac9a7dd2&sv=2) MVC Plus ORM In this architecture approach we have replaced business objects for ORM entities and replaced our data access layer to be controlled now by the ORM. This takes us very deep into object oriented land where the majority of our model is now modeled vi relational objects. triangle-exclamation **Stern Warning:** ORMs are NOT silver bullets. They are an incredible tool that must be used for the right reasons and at the right time. Do not be confused in that you must ONLY use the ORM. No, you can still use DAOs and queries for certain things that matter. You do not need to retrieve entire object graph collections if NOT needed. We have even build a companion package for ColdBox called [**cborm**arrow-up-right](https://github.com/coldbox-modules/cbox-cborm) that will help you build more pragmatic and enjoyable ORM applications. \--- [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#coldbox-mvc-1) MVC Frameworks for ColdFusion (CFML) ------------------------------------------------------------------------------------------------------------------ Here are our recommendations: * **ColdBox MVC** - [https://www.coldbox.org/arrow-up-right](https://www.coldbox.org/) * **fw/1** - [https://github.com/framework-one/fw1arrow-up-right](https://github.com/framework-one/fw1) * **CFWheels** - [https://cfwheels.org/arrow-up-right](https://cfwheels.org/) ### [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#coldbox-mvc-2) ColdBox MVC ![](https://modern-cfml.ortusbooks.com/~gitbook/image?url=https%3A%2F%2F1963028932-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-legacy-files%2Fo%2Fassets%252F-LA-UVvdhvPQ4iTxu_CD%252F-LLFsbDu2J-_4YDdd-fE%252F-LLFwQp5Gv_MeuxHTjdp%252FColdBox.png%3Falt%3Dmedia%26token%3D47f06aa3-51c1-4092-9a6b-d697e19f7f4e&width=768&dpr=3&quality=100&sign=c1bcef1a&sv=2) ColdBox MVC Platform circle-info ColdBox has become the defacto platform for developing modern MVC ColdFusion applications and we are partial to it because we wrote it :) The ColdBox HMVC Platform is the de-facto enterprise-level HMVC framework for CFML developers. It's professionally backed, highly extensible, and productive. Getting started with ColdBox is quick and painless. The only thing you need to begin is [CommandBoxarrow-up-right](http://www.ortussolutions.com/products/commandbox) , a command line tool for CFML developers. You can check out our quick learning guides below: * **Quick Start Guide:** [https://coldbox.ortusbooks.com/getting-started/getting-started-guidearrow-up-right](https://coldbox.ortusbooks.com/getting-started/getting-started-guide) * **60 Minute Guide:** [https://coldbox.ortusbooks.com/for-newbies/60-minute-quick-startarrow-up-right](https://coldbox.ortusbooks.com/for-newbies/60-minute-quick-start) [hashtag](https://modern-cfml.ortusbooks.com/extra-credit#resources) More Resources ---------------------------------------------------------------------------------------- * ​[http://en.wikipedia.org/wiki/Domain\_modelarrow-up-right](http://en.wikipedia.org/wiki/Domain_model) ​ * ​[http://domaindrivendesign.org/arrow-up-right](http://domaindrivendesign.org/) ​ * ​[http://martinfowler.com/eaaCatalog/domainModel.htmlarrow-up-right](http://martinfowler.com/eaaCatalog/domainModel.html) ​ [PreviousAsynchronous Programmingchevron-left](https://modern-cfml.ortusbooks.com/beyond-the-100/asynchronous-programming) [NextDependency Injectionchevron-right](https://modern-cfml.ortusbooks.com/extra-credit/dependency-injection) Last updated 2 years ago Was this helpful? --- # Email Protection | Cloudflare Please enable cookies. Email Protection ================ You are unable to access this email address gitbook.io ------------------------------------------------------ The website from which you got to this page is protected by Cloudflare. Email addresses on that page have been hidden in order to keep them from being accessed by malicious bots. **You must enable Javascript in your browser in order to decode the e-mail address**. If you have a website and are interested in protecting it in a similar way, you can [sign up for Cloudflare](https://www.cloudflare.com/sign-up?utm_source=email_protection) . * [How does Cloudflare protect email addresses on website from spammers?](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/) * [Can I sign up for Cloudflare?](https://developers.cloudflare.com/fundamentals/setup/account/create-account/) Cloudflare Ray ID: **9e94c603ab45064c** • Your IP: Click to reveal 54.237.218.47 • Performance & security by [Cloudflare](https://www.cloudflare.com/5xx-error-landing) ---