I started with Allaire ColdFusion way back in '97 so yeah I’m 99% certain (or 97%? lol) that I wrote my custom function before the runonce
argument existed. At least I like that story much better than the one where I neglected to fully read all of the documentation of each upgrade. 
I still like my includeOnce()
function for code readability, but I have updated it to be simply a wrapper for the native function.
While doing that I tested and confirmed what I found to be unexpected behavior of the native function. I thought it should include again when inside a component method due to its separate scope, but this test shows that runonce applies to the entire request.
This observation is mostly for theoretical purposes since including a file in a component is not a common use case, but it’s interesting to know!
include-once.cfm (in two parts to maintain syntax highlighting)
<cfscript>
Request.includeOnce = includeOnce;
Request.includeOnceCustom = includeOnceCustom;
objIncludeOnceTest = new includeOnceTest();
echo('TESTING NATIVE cfinclude with runonce=true<br>')
cfinclude(template="include-once-native.cfm", runonce=true);
cfinclude(template="include-once-native.cfm", runonce=true);
objIncludeOnceTest.testNative();
echo('<br>');
echo('TESTING WRAPPER includeOnce()<br>')
includeOnce("include-once-wrapper.cfm");
includeOnce("include-once-wrapper.cfm");
includeOnce("include-once-wrapper.cfm");
objIncludeOnceTest.testWrapper();
echo('<br>');
echo('TESTING CUSTOM includeOnceCustom()<br>')
includeOnceCustom("include-once-custom.cfm");
includeOnceCustom("include-once-custom.cfm");
objIncludeOnceTest.testCustom();
echo('<br>(The hellos from the methods are just to prove they are called.)');
function includeOnce(required string pathToInclude) {
cfinclude(template=Arguments.pathToInclude, runonce=true);
}
function includeOnceCustom(required string pathToInclude) {
if (isNull(Request.sIncluded)) Request.sIncluded = {};
if (isNull(Request.sIncluded[Arguments.pathToInclude])) {
Request.sIncluded[Arguments.pathToInclude] = true;
include Arguments.pathToInclude;
}
}
</cfscript>
includeOnceTest.cfc
component {
private function hello(required string method) {
echo('hello from includeOnceTest method: test#Arguments.method#<br>');
}
function testNative() {
this.hello('Native');
cfinclude(template="include-once-native.cfm", runonce=true);
}
function testWrapper() {
this.hello('Wrapper');
Request.includeOnce("include-once-wrapper.cfm");
}
function testCustom() {
this.hello('Custom');
Request.includeOnceCustom("include-once-custom.cfm");
}
}
include-once-native.cfm
<cfscript>
echo('hello from include-once-native.cfm<br>');
</cfscript>
include-once-wrapper.cfm
<cfscript>
echo('hello from include-once-wrapper.cfm<br>');
</cfscript>
include-once-custom.cfm
<cfscript>
echo('hello from include-once-custom.cfm<br>');
</cfscript>
RESULT
TESTING NATIVE cfinclude with runonce=true
hello from include-once-native.cfm
hello from includeOnceTest method: testNative()
TESTING WRAPPER includeOnce()
hello from include-once-wrapper.cfm
hello from includeOnceTest method: testWrapper()
TESTING CUSTOM includeOnceCustom()
hello from include-once-custom.cfm
hello from includeOnceTest method: testCustom()
(The hellos from the methods are just to prove they are called.)