Saturday, 9 April 2022

CFML: revisit import aliasing

G'day:

I'm writing this here cos it's getting a bit long for a comment on the CFML Slack channel, and perhaps it might get a different set of eyes on it here anyhow.

I wanna revisit the discussion about import aliasing in CFML. ie this:

import com.vendor.app.package.Date as VendorDate
import org.project.lib.Date as LibDate

vendorDate = new VendorDate(now())
LibDate = new LibDate(now())

This has not been implemented in CFML because - I suspect - the various devs working on the CFML engines are primarily Java devs, and Java does not support this for (IMO) pretty bogus reasons (see the answer to Change Name of Import in Java, or import two classes with the same name, its commments and link within for the "reasoning").

However it's pretty common around the place in other languages, especially ones that occupy overlapping space as CFML, eg:

(It's important to consider that both Groovy and Kotlin are JVM languages with the remit of making Java easier, similar - in a way? - to CFML).

I've got by without this mostly, but just had a real world situation where the absence of it is a pain in the butt:

import logbox.system.logging.config.LogBoxConfig
import logbox.system.logging.LogBox
import services.logging.Config

// ...

config = new Config()
logboxConfig = new LogBoxConfig(config)

logbox = new LogBox(logboxConfig)

This is from a CFC, I've just elided the not relevant bits. Now whilst there are only 10 lines of code between where Config is imported and I use it, I still just went "what config is this? Oh right, my one". Bear in mind the CFC itself is nothing to do with logging, it's an IoC factory method. In context, "Config" suggests it's something to do with the IoC factory (this is the basis of my next article… the one I was working on when this situation presented itself). The code is just not as clear as it could be.

I know I can do this:

import services.logging.*

//...

config = new logging.Config()

But there's cross-over in the "logging" concept here with LogBox's logging any my own logging. Also it's a bit of shit work around because to me a * import indicates there's a bunch of stuff from that package being used, whereas there isn't; I'm just using that one class here. So def a work-around, not how one would naturally solve this.

Then I figured actually there was legit call to use import logbox.system.logging.* as I'm using multiple things from there, but that then conflicts with import services.logging.*

What would be good to do here would be:
import services.logging.Config as LoggingConfig

// ...

config = new LoggingConfig()

That is the clearest representation of what's going on, I think.

Anyway, just wondering what other CFMLers think. Maybe Java's right? Maybe all the other languages including the ones trying to improve on Java are... ;-)

Righto.

--
Adam