Created
August 17, 2019 14:23
-
-
Save bennadel/e5052a2b72be9fd0ac9e2c1454482487 to your computer and use it in GitHub Desktop.
Upgrading A Built-In Function To A First-Class Citizen In Lucee 5.3.2.77
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfscript> | |
values = values.map( trim ); | |
</cfscript> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfscript> | |
operator = ( doUppercase ) | |
? ucase | |
: lcase | |
; | |
echo( operator( "I said Good-Day, sir." ) ); | |
</cfscript> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<cfscript> | |
values = [ "oLLeH", "Ym", "dOOg", "DnEiRf" ]; | |
// NOTE: The .map() operations in the following calls will pass-in several arguments | |
// to the provided operator ("reverse", "ucase", "lcase"); however, these Functions | |
// can only accept one argument. As such, our proxy function will pare down the | |
// arguments based on built-in function's native arity. | |
values = values.map( upgradeBIF( "reverse" ) ); | |
// Randomly choose an operator for our next .map() call. | |
operator = randRange( 0, 1 ) | |
? upgradeBIF( "ucase" ) | |
: upgradeBIF( "lcase" ) | |
; | |
dump( values.map( operator ) ); | |
// ------------------------------------------------------------------------------- // | |
// ------------------------------------------------------------------------------- // | |
/** | |
* I attempt to upgrade the given built-in function (BIF) such that it can be passed- | |
* around like a first-class Function reference. | |
* | |
* @name I am the name of the BIF to upgrade. | |
*/ | |
public Function function upgradeBIF( required string name ) | |
cachedWithin = "request" | |
{ | |
var bifMetadata = getFunctionData( name ); | |
// The getFunctionData() function returns meta-data about the built-in function | |
// with the given name. This includes the array of arguments that it expects, | |
// which can use to determine the arity of the function (ie, how many arguments | |
// it expects). | |
var bifArity = bifMetadata.arguments.len(); | |
return( | |
() => { | |
// If there are no arguments - the Built-In Function (BIF) doesn't expect | |
// arguments - pass-through an empty set of arguments. | |
if ( ! bifArity || ! arguments.len() ) { | |
var argumentList = ""; | |
// If the arguments passed to the proxy function are provided as an | |
// ordered list of values, then we have to pare down the collection to | |
// just those expected by the Built-In Function's (BIF) native arity (or | |
// ColdFuison will throw an error). | |
// -- | |
// NOTE: We are loosely determining argument-type by seeing if an index- | |
// oriented argument key exists. | |
} else if ( arguments.keyExists( "1" ) ) { | |
var argumentList = arguments | |
.keyArray() | |
.slice( 1, min( bifArity, arguments.len() ) ) | |
.map( ( index ) => "arguments[ #index# ]" ) | |
.toList( "," ) | |
; | |
// If the arguments passed to the proxy function are provided as a set of | |
// key-value pairs, then we need to pass them through to the Built-In | |
// Function (BIF) in the same manner. | |
// -- | |
// CAUTION: While some BIFs support argumentCollection (those that are | |
// implemented in CFML), the vast majority of BIFs do not support this | |
// type of invocation. As such, we have to explicitly create a listed of | |
// named arguments. | |
} else { | |
var argumentList = arguments | |
.keyArray() | |
.map( ( key ) => "#key# = arguments.#key#" ) | |
.toList( "," ) | |
; | |
} | |
return( evaluate( "#name#( #argumentList# )" ) ); | |
} | |
); | |
} | |
</cfscript> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment