I'm a big fan of ColdFusion, but it is sorely missing some dynamic capabilities that I, for one, would love to see. How often have you seen a new user to CF ask something like, "if I store code in the database, how can I get it to run?" That's some pretty advanced thought, in my eyes. But the standard response is, "you have to write it to a file, and then cfinclude it." Similarly, Sean Corfield's Closures for CFMX
accomplishes its feat by writing to the file system.
take a string of code and execute it?
I'd also like to see the ability to create methods dynamically. Why should I need to write a file to generate individual getters and setters for an object (or any other function for that matter)? Well, I could do something like
, the generic getter and setter
that Peter Bell (and certainly countless others) used in his iterating business object
. But what happens when I want some more complex functionality? Wouldn't it be cool to be able to loop over your properties and create methods for each of them? Not only that, if the property hasn't been loaded yet (for instance, its a relationship and you want to load it lazily), you could easily do that too!
What if I want to load some data from the database, but I don't know which data -- only the function name will tell me that? Then, you have to either write out to a file or alias that function to a function that throws an error, examines the line, and figures out what the function was called (hat tip, Per Djurner -- I still love that solution =) ). Even that gets iffy if there are two on one line. Let's take it even further - in the previous case you already know the function name. But why can't I just let the user type what they want for a function, and I figure out what its supposed to do? I'd love to be able to do that.
The point here is that I'm not the only one running into roadblocks when it comes to doing dynamic stuff. Smart people who've been using ColdFusion for many years are having to run workarounds. And not only that, newcomers as well!
So three things I'd like to see (which are all somewhat related) in ColdFusion:
- Evalute a string of code
- A method_missing handler, to figure out what to do if a user calls a non-existent method on a class.
- A way to dynamically write functions (which would probably be about the same as item 1)
And, if there is some capability which exists and I have said it doesn't, please
let me know!
I suppose if I really
wanted to, I could write a CF interpreter in CF (or drop down into Java). Anyone want to join me on that endeavor? =)
Hey! Why don't you make your life easier and subscribe to the full post
or short blurb RSS feed? I'm so confident you'll love my smelly pasta plate
wisdom that I'm offering a no-strings-attached, lifetime money back guarantee!
Leave a comment
I'm with you on all of this, but I'm not convinced this is the right functionality for CF's core audience - they'd be better served with some more cool cf_whatever tags for doing more things quickly.
The method_missing handler would be lovely, but I'm not sure that Java supports that so I don't know an easy way of implementing. If there *was* an easy solution, this would be a great drop in for the language. As for evals and def's for functions, I'm just not convinced it is worth adding to CF as I'm not sure most CF coders are really into that kind of metaprogramming.
The one other thing I miss is everything being an object. The cost of object instantiation in CF means that there is no way I can create custom data types and assign properties to them with custom validate and transform and display and fielddisplay methods so I have to use a hacky service layer approach to custom data types, but again not convinced it would be either feasible or worthwhile.
That said, if you figure out a way to add support for any of the language features . . .
Posted by Peter Bell
on Feb 12, 2007 at 11:03 AM UTC - 5 hrs
Another thing that would be nice is if attributes were also methods (don't know what to call it in proper OO terms). What I mean is if you call product.price you should be able to override this in your class with a cffunction called price (without using getter/setters).
But I have to agree with Peter, it would just be "nice" it should not be made a priority to add.
Posted by Per Djurner
on Feb 12, 2007 at 01:16 PM UTC - 5 hrs
People already abuse evaluate() - which *interprets* code at runtime - so I wouldn't want to encourage any additional abuse. My Concurrency library caches requests so that the same closure code is *compiled* just once to Java bytecode and executed. That's the big difference between evaluate() and including a file - the latter sounds like more work but the result is compiled code and improved speed.
Posted by Sean Corfield
on Feb 12, 2007 at 04:31 PM UTC - 5 hrs
Aww Sean, we're not prematurely optimizing now, are we?! :->
I always prefer dynamic programming over code generation until simplifying patterns, better performance or language limitations force me to actually generate code. I think it is good for languages to support Macros - even if programmers may need to refactor to code gen if it they become bottlenecks.
Posted by Peter Bell
on Feb 12, 2007 at 04:47 PM UTC - 5 hrs
Leave a comment
@Peter - "I'm not convinced this is the right functionality for CF's core audience."
I can see the dynamic method naming/writing as something that not that many people would use, but as far as evaluate() taking code from your DB and running it - I used to participate a lot on ExpertsExchange, and I saw the question often, so I would think that may be something the "core" audience would be into (more on that in response to Sean below).
You also mentioned "I'm not sure that Java supports that so I don't know an easy way of implementing." I haven't used JRuby, but I would assume it has this, and of course, it runs on Java. I would think it would be quite easy to implement, in fact. Basically, they could add the missing method handler as a method to the base class WEB-INF.cftags.component, and instead of throwing an exception when a method cannot be found, call that method (which would be implemented to throw the exception). Any base classes would be free to override that functionality. They could do something similar with functions not contained in CFCs.
Implementing a full interpreter for CF, well that might be a bit harder.
"The one other thing I miss is everything being an object" - I wouldn't mind that either, although not having it doesn't bug me that much. I often find myself doing things like "string".findnocase(...) and then having to back out of it. =)
@Per- "if attributes were also methods" We spoke about that yesterday, and both sort of came to the conclusion that would happen... never =)
@Sean- "People already abuse evaluate() - which *interprets* code at runtime..." That is true. Maybe a full-on intepreter is not what is needed. They may be able to hash the code and store it as a file, compiled and what-not as well. I haven't checked out the concurrency thing, but I will be sure to do so. It should be noted that your closures package provides pretty much the same thing I'm asking for (aside from method missing).
Posted by Sam
on Feb 13, 2007 at 06:03 AM UTC - 5 hrs