This is a follow-on from yesterday’s post that showed how BoxLang now allows you to perform functional static binding to BIFs (built in functions) like so:
[ "luis", "brad", "jon" ].map( ::uCase ) // [ "BRAD","LUIS","JON" ]
Another type of method reference you may want to bind to is a member method on an object. Member methods could be
order.submit() // method on a class
companyName.uCase() // BoxLang string member method
companyName.getBytes() // Java String member method
So, historically we can declare a closure to call these methods for us like so:
pendingOrders.each( order => order.submit() )
This new feature allows us to create a first-class function that points to that method reference, but is not bound to a specific instance.
.methodName
You’ll note we precede the method name with a period (.
) just like a method call, but there is no instance in front of it. We can also omit the parenthesis if there are no arguments. This is a bit of syntactic sugar, so we can keep it as brief as possible.
Here’s the final version of our example using our functional member method binding:
pendingOrders.each( .submit )
The end result is the submit
member method will be called on each order in the array. This removes all the extra boilerplate, but works just like the version above that uses a closure to call the method.
What if our member methods require args? No worries, you can use the syntax
.methodName( arg1, arg2 )
to provide the arguments you’d like passed to each member method call. That looks like this:
[ "brad", "luis", "jon" ].map( .left( 1 ) ); // [ "b", "l", "j" ]
In this example we call the left()
string member method on each name to strip 1 character.
The arguments will not be evaluated until the function reference is invoked, and the argument expressions will be re-evaluated for every invocation. The argument evaluation will also have lexical binding to the declaring context just like a closure.
For more information and examples, check out the ticket: [BL-351] - Welcome