Global Object Decoration (string,array,struct,function)

what is the ‘best practice’ way to implement this in an application, or an instance? (string,array,struct,list,function)

for example: if I wanted to create string.inflect(string) method on the string object or date.random(start,end) on the date object… or function.hasErrors or whatever…

also is there anyway to overload functions in lucee? what is the ‘best practice’ on this also.

I cannot (choose not to) speak about best practices. I went down that path at the beginning of my career and nobody has fully resolved tabs or spaces no matter the language.

My initial reaction is “no”. Not in the traditional sense (that I’m aware of).

You can leave arguments undefined and use structKeyExists(arguments, "myArg") to determine which variation was intended … of default to a value you check against. Not quite the same as overloading though.

To borrow from another technology community, I’m pretty sure everyone in the JavaScript world regrets that some of the popular JavaScript libraries worked by overloading the native objects. It has made backwards compatibility a huge stumbling block for the W3C. See SmooshGate for more details on that. But, the tl;dr is that it made it harder for the language to add new methods if they knew it was going to break popular – albeit non-standard – overloads of the same name.

Not that this is necessarily relevant to what you are doing, since you are likely building something for internal use. I only bring this up to say that others have gone down that path and lived to regret it.

What I do in scenarios like this is just wrap it up in a utility component and inject that component into whatever context needs it. It’s less “fun” that just calling native methods; but, in my experience, makes the code easier to understand in the long run.

5 Likes

With all that said, I will point out that in Lucee CFML, you can create your own globally available extensions: Extensions in Lucee 5 :: Lucee Documentation – this isn’t overloading a particular method; but, it does alter what is generally considered “built in”.

I guess looking more to add extra functionality in extra methods / properties, than to replace existing functionality.

I’m aware of the ways to expand lucee, and sit with keen eyes on what happens to web-inf in lucee 6.x when it’s moved out of webroot, moving access to a range of files that devs look at to directories their admin may not have given them access to. (another topic for another day)

I’m actually a big fan overloading native objects in Javascript when done ‘thoughtfully’, I guess as I primarily use extjs which does this well by using smarts and testing for existence of native functionality. It adds a ‘smart’ layer to the language until it catches up with the framework. Never regretted it, but can’t say the same for other frameworks that might not have put as much care into how they implemented.

At the end of the day you need to test for existance, or you need to uniquely name objects. that said languages can make as much of a dogs breakfast of naming as frameworks. (not going to expand, I think we all know who I’m talking about)

IMHO this removes hacks that frameworks have had to do to get metadata from functions, or hold secondary metadata instead of just inserting a property into the object meta so it’s self contained.

These limitations are already causing work-arounds with code.

Yes exactly, I guess subcomponents coming soon might address this in some way (we’ll see), but it’s messy just for a single property or method that just should be there as an object or member-function in a language that prides itself on being faster and has a culture of clever abstraction.

The short answer is no. CFML has neither prototypal inheritance like JS where you can add methods to a object’s prototype, nor do native CFML datatypes (string, array, struct) have an extendable class system where you can create a CustomStruct class that extends Struct, etc in the same way a Java BradMap could extend HashMap

The closest you could come would be to create CFC wrapper for the data structure that exposed its member functions as well as its own, but there would be several drawbacks to that in CFML, not the least of which being performance.

Despite the slippery slopes, I think this would be cool in CFML, but I’d opt for the inheritance based approach Java takes. However, CFML was always created as a rather simple language and never exposed any of the object definitions in the language in an extendable way.

3 Likes

ColdFusion is an abstracted language true, but until there’s enough time and money to add all the member functions and alike that builds on the whole ‘concept’ of lucee vs the monolithic CF, and functionality that is popular in ‘one or two’ circles of devs or with specific frameworks… I can see that as a ‘must’ based on the ‘concept’ of lucee being as modular…

Of course this goes against the whole concept of lucee extensions does it not, and in some ways augments cf culture by adding helper functions and properties to make coding easier and more modern? Aka to extend the language with a ‘chosen’ set of extensions. I see no problem with doing this through an extension as it would be only added by those contexts that need it.

Would be great to have a ‘pure cfml’ extension that fixed the positioning of attributes and made the output of inbuilt functions consistent between all methods also, but from what you’re saying that would be a fork of lucee, rather than an extension.

Just sick of seeing hacks, even coldbox, fw/1, cfwheels as well as my (20+ year old) framework ‘DiiMES’ are all using hacks to pass data around due to limitations on metadata ‘updating’ missing with custom functions and alike. sure you can set meta on creation, but why cant you change that metadata and inspect it as a member function… my 2c…

What is a simplified use case of your current hack/code and what’s your ideal/goal? I feel like I’m missing context that could be useful here.

Show some current code and expected, maybe we can help.

1 Like

adding common modifications of objects, and also adding some additional helper functions…

eg: queryObj.isEmpty() or queryObj.hasOne or dateObj.isWeekend() or dateObj.getFirstDayOfMonth()

Ideally would love to see a ‘errors’ property as meta on a function that would be written to so you can hit results.haserrors() or results. kind of how you can get query.columndata(‘bla’) off a query…

These are things that I might want that others might not, there is a whole list of items that other languages/frameworks have that lucee does not (even preside and commandbox have util libs for some of these)…

would be just good to be able to roll this as a lucee extension, so you could choose to add them or not on a server.

1 Like