Skip to content

Instantly share code, notes, and snippets.

@jsteinshouer
Created December 8, 2023 17:55
Show Gist options
  • Save jsteinshouer/048c9ebc9a93d3f390d60e7136bbcc0f to your computer and use it in GitHub Desktop.
Save jsteinshouer/048c9ebc9a93d3f390d60e7136bbcc0f to your computer and use it in GitHub Desktop.
Variable Scope Demo
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# CFML Component Variable Scope Demo\n",
"\n",
"This is meant to demonstrate the side effect of not properly scoping a variable in a CFML component.\n",
"\n",
"\n",
"\n",
"For this demo we have created a component named `MyService.cfc`. Here is what it looks like.\n",
"\n",
"```javascript\n",
"component {\n",
"\n",
" function saveRecord( required firstName, required lastName) {\n",
" \n",
" // intentionally left out the var keyword to demonstrate\n",
" record = {\n",
" firstName = arguments.firstName,\n",
" lastName = arguments.lastName\n",
" };\n",
"\n",
" // simulate load on the system\n",
" sleep( randRange(1,250) );\n",
"\n",
" return \"\n",
"Record Saved!\n",
"#serializeJSON(record)#\";\n",
" }\n",
"\n",
"}\n",
"```\n",
"\n",
"I added a brief random pause in there to try and simulate system load.\n",
"\n",
"We first create an instance of the component and assign it to the `myService` variable."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "cfml"
}
},
"outputs": [],
"source": [
"myService = new MyService();"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The call to the `saveRecord` method behaves as expected when called once."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"vscode": {
"languageId": "cfml"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Record Saved!\n",
"{\"LASTNAME\":\"Elf\",\"FIRSTNAME\":\"Buddy\"}\n"
]
}
],
"source": [
"myService.saveRecord(\n",
" firstName = \"Buddy\",\n",
" lastName = \"Elf\"\n",
");"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"vscode": {
"languageId": "cfml"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Record Saved!\n",
"{\"LASTNAME\":\"Elf\",\"FIRSTNAME\":\"Papa\"}\n"
]
}
],
"source": [
"myService.saveRecord(\n",
" firstName = \"Papa\",\n",
" lastName = \"Elf\"\n",
");"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"But if we use `runAsync` to simulate 3 simulatneous requests we see the results are unexpected and inconsitent."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"vscode": {
"languageId": "cfml"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[java.lang.Class]\n",
"[java.lang.Class]\n",
"[java.lang.Class]\n",
"\n",
"Record Saved!\n",
"{\"LASTNAME\":\"Elf\",\"FIRSTNAME\":\"Papa\"}\n",
"\n",
"Record Saved!\n",
"{\"LASTNAME\":\"Hobbs\",\"FIRSTNAME\":\"Walter\"}\n",
"\n",
"Record Saved!\n",
"{\"LASTNAME\":\"Hobbs\",\"FIRSTNAME\":\"Walter\"}\n"
]
}
],
"source": [
"request1 = runAsync(() => {\n",
" return myService.saveRecord(\n",
" firstName = \"Buddy\",\n",
" lastName = \"Elf\"\n",
" );\n",
"});\n",
"request2 = runAsync(() => {\n",
" return myService.saveRecord(\n",
" firstName = \"Papa\",\n",
" lastName = \"Elf\"\n",
" );\n",
"});\n",
"request3 = runAsync(() => {\n",
" return myService.saveRecord(\n",
" firstName = \"Walter\",\n",
" lastName = \"Hobbs\"\n",
" );\n",
"});\n",
"request1.get();\n",
"request2.get();\n",
"request3.get();"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "CFML (Script)",
"language": "CFML",
"name": "cfscript"
},
"language_info": {
"file_extension": ".cfm",
"mimetype": "text/x-javascript",
"name": "CFScript"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
component {
function saveRecord( required firstName, required lastName) {
record = {
firstName = arguments.firstName,
lastName = arguments.lastName
};
//simulate load on the system
sleep( randRange(1,250) );
return "
Record Saved!
#serializeJSON(record)#";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment