Variable Scopes
They gotta exist somewhere!
In the BoxLang language, many persistence and visibility scopes exist for variables to be placed in. These are differentiated by context: in a class, function, tag module, thread, or template. These scopes are Java maps but enhanced to provide case-insensitivity, member functions and more.
All BoxLang scopes are implemented as BoxLang structures, basically case-insensitive concurrent hash maps behind the scenes.
This idea that the variables you declare in templates, classes, and functions are stored in a structure makes your code highly flexible since you can interact with the entire scope fluently and with many different BIFs available. You can also bind them to function calls, attributes, etc. Thus, it capitulates on BoxLang being a dynamic language.
The only language keyword that can be used to tell the variable to store in a function's local scope is called var
. However, you can also just use the local
scope directly or none at all. However, we do recommend being explicit on some occasions to avoid ambiguity.
It's a good idea to scope variables to avoid scope lookups, which could in turn create issues or even leaks.
Scripts & Template Scopes (bxm,bxs)
All scripts and templates have the following scopes available to them. Please note that the variables
scope can also be implicit. You don't have to declare it.
variables
- The default or implicit scope to which all variables are assigned.
Class Scopes (bx)
All classes in BoxLang follow Object-oriented patterns and have the following scopes available. Another critical aspect of classes is that all declared functions will be placed in a visibility scope.
variables
- Private scope, visible internally to the class onlythis
- Public scope, visible from the outside worldstatic
- Store variables in the classes blueprint and not the instancesuper
- Only available if you use inheritance
Class Function Scopes
Depending on the function's visibility, BoxLang places a pointer for the function in the different scopes below. Why? Because BoxLang is a dynamic language. Meaning at runtime, you can add/remove/modify functions if you want to.
Private
Functionvariables
Public or Remote
Functionsvariables
this
Templates/Scripts Function Scopes
All user-defined functions declared in templates or scripts will have the following scopes available:
variables
- Has access to private variables within a Class or Pagelocal
- Function-scoped variables only exist within the function execution. Referred to asvar
scoping. The default assignment scope in a function.arguments
- Incoming variables to a function
Closure Scopes
All closures are context-aware. Meaning they know about their birthplace and surrounding scopes. If closures are used in side classes, then they will have access to the class' variables
and this
scope.
variables
- Has access to private variables from where they were created (Classes, scripts or templates)this
- Has access to public variables from where they were created (Classes)local
- Function-scoped variables only exist within the function execution. Referred to asvar
scoping. The default assignment scope in a function.arguments
- Incoming variables to a function
Lambdas (Pure Function) Scopes
Lambdas are pure functions in BoxLang, they do not carry their surrounding or birth context. They are simpler and faster.
local
- Function-scoped variables only exist within the function execution. Referred to asvar
scoping. The default assignment scope in a function.arguments
- Incoming variables to a function
The following will throw an exception as it will try to reach outside of itself:
Custom Component Scopes
In BoxLang, you can extend the language and create your own custom components that can be used in script or templating syntaxes. They allow you to encapsulate behavior that can wrap up anything.
attributes
- Incoming component attributesvariables
- The default scope for variable assignments inside the componentcaller
- Used within a custom component to set or read variables within the template that called it.
Here is the component:
We highly discourage peeking out of your component using the caller
scope, but it can sometimes be beneficial. Use with caution.
Thread Scopes
When you create threads with the thread
component, you will have these scopes:
attributes
- Passed variables via a threadthread
- A thread-specific scope that can be used for storage and retrieval. Only the owning thread can write to this scope. All other threads and the main thread can read the variables.local
- Variables local to the thread contextvariables
- The surrounding declared template or classvariables
scopethis
- The surrounding declared class scope
Evaluating Unscoped Variables
If you use a variable name without a scope prefix, BoxLang checks the scopes in the following order to find the variable:
Local (function-local, UDFs and Classes only)
Arguments
Thread local (inside threads only)
Query (not a true scope; variables in query loops)
Thread
Variables
CGI
CFFILE
URL
Form
Cookie
Client
IMPORTANT: Because BoxLang 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.
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 visitorclient
- stored in cookies, databases, or external storages (simple values only)application
- stored in server RAM or external storage tracked by the running BoxLang applicationcookie
- stored in a visitor's browserserver
- stored in server RAM for ANY application for that BoxLang instancerequest
- stored in RAM for a specific user request ONLYcgi
- read only scope provided by the servlet container and BoxLangform
- Variables submitted via HTTP postsURL
- Variables incoming via HTTP GET operations or the incoming URL
Last updated
Was this helpful?