My Secret Life as a Spaghetti Coder
home | about | contact | privacy statement
I never thought to do this before today, but all of the sudden I had this idea that it would be nice to have a variety of utility methods for every object. I'm talking about things like respondsTo(methodName), to see if a component has a certain method public, or inspect() as an object oriented way to do getMetaData(object), and just things in general that all objects should be able to do to or for themselves.

Rather than creating a class which would be the equivalent of BaseClassToBeExtendedManuallyByAllOtherClasses, I decided I'd like to just replace component.cfc in the CF7 install. As it happened, the component.cfc that was there (CFusionMX7/wwwroot/WEB-INF/cftags) was a 0 byte file. I just added my code for respondsTo(methodName):

<cfcomponent>
   <cffunction name="respondsTo" access="public">
      <cfargument name="methodName">
      <cfset var result = false>
      <cfif structKeyExists(this, methodName) and isCustomFunction(this[methodName])>
         <cfset result = true>
      </cfif>
      <cfreturn result>
   </cffunction>
</cfcomponent>

And it worked. No fuss or anything.

Is anyone else doing this? What sorts of object methods have you added? What would you find useful if you had the stomach to do this?

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!


Comments
Leave a comment

I've been doing this for a while, adding a _dump and some basic introspection methods - obviously, I have to watch for portability issues, and should probably have a script do this, but I seem to remember to comment out the offending method calls before deployment.
stigg

Posted by stigg on Jun 15, 2007 at 07:06 PM UTC - 6 hrs

Scorpio brings a great new function, GetComponentMetaData() that will take in a string:path to component. You do not need to instantiate the component and it will give you a bunch of useful information about that component including a list of functions! Just an FYI.

Posted by Dan Vega on Jun 15, 2007 at 07:35 PM UTC - 6 hrs

I've been doing this for quite a while; it's one of the reasons I'm interested in ScriptaGulous (at least *cfc's* can have a full implementation of CFScript!)

Lately, I've added Hal Helm's BaseComponent.cfc (http://halhelms.com/webresources/BaseComponent.cfc...; more thoughts at http://halhelms.com/index.cfm?fuseaction=newslette...

Note that his isInstanceOf() method conflicts with a similar method in CF 8; you'll need to comment-out or rename it.

Posted by Tracy Logan on Jun 17, 2007 at 11:05 AM UTC - 6 hrs

Hi Sam,

You have to be careful of the "kitchen sink base class" risk where you throw all kinds of stuff in. That said I have a dump() method for cfdumping in the middle of my scripts and a throw() method to make it easy for me to vary how I handle my throws across the application. I also often throw methods into my base class to get things up and running quickly and then refactor them later.

Main thing to look out for is putting lots of cross cutting business concerns in the base class (even in a parameterized manner). Those are better done using AOP (which I think I'm finally going to get round to adding to LightWire some time soon). The base class is best for utility "plumbing" features to extend ColdFusion a little.

Bear in mind that this only works if you're building a framework (even if in-house) as it means your beans won't work without those base classes so you're creating tight coupling between all of your beans and the underlying base class.

In short, I think it is an advanced technique that can allow you to do certain things, but should be a last resort. Lots of people have gotten into a mess going down this route!

Posted by Peter Bell on Jun 17, 2007 at 12:41 PM UTC - 6 hrs

Thanks for the comments everyone.

@Dan - the inspect method I was talking about was simply as an example. That said, unless the new method you are talking about is per object, I'd probably still like to have an inspection method (which would most likely just refer to the existing one, but one which I could call on an object, rather than passing it one).

@Tracy - When I saw "BaseComponent.cfc" written, I thought "oh yeah!" I thought I had seen it somewhere. I had a look at it, and indeed most of that component from Hal Helms is the type of stuff I was talking about.

@Peter - of course, it would be foolish of me to put business concerns, or any concerns into something like this, other than those that belong to objects, all objects, and only objects.

This isn't something I could do and use in any code that would be distributed to the outside world, but I was glad to see it possible. It's a step toward open classes in some small regard. More importantly to my case, almost all of our work is stuff where we host the application, so this is of great value to me personally, and I imagine it is valuable to anyone who wants richer base objects who is in a similar situation. It is easy enough (and safer in some senses) to just create a base and extend it for every object, but that can get messy that way too.

All that said, I doubt I'll do anything with it actually, but it's something I'll consider and toy with for a little while. I think I'd rather go the messy but safe route and just extend a different component. I just thought it was cool that we could change it so easily.

Posted by Sam on Jun 17, 2007 at 04:47 PM UTC - 6 hrs

@Tracy - one more thing I just picked up on. If you are using scriptaGulous, be sure and let us know if you have any problems, and I'll fix it and put the code in the repository immediately.

I haven't used many of the tags (well, functions I guess) in my code yet because I haven't been working on a CF project aside from small changes in the last week or so.

Posted by Sam on Jun 17, 2007 at 08:13 PM UTC - 6 hrs

In addition to the dump methods mentioned above, I also have getMemento/setMemento in my baseClass cfc, and a method I call "blend" which takes a struct (usually form struct) and updates the object's data, if any of the struct's keys match a setter method in the object.

This blend method works great if for example, you have a class with 20 properties but you are only updating 10 properties from your form.

This way on form post you can do:

obj.init(form.id)
objDAO.read(obj)
obj.blend(form)
objDAO.save(obj)

...without all the silly
setid(form.id)
setname(form.name)
setaddress(form.address)
etc.

Posted by Josh Nathanson on Jun 19, 2007 at 04:39 PM UTC - 6 hrs

@Josh: Cool. I use that concept but I never thought of a good name for it. I like blend, so thanks for that.

Posted by Sam on Jun 19, 2007 at 04:57 PM UTC - 6 hrs

Interesting. Best I ever came up with was the more utilitarian "loadStruct()". Blend is kinda cool . . .

Posted by Peter Bell on Jun 19, 2007 at 05:24 PM UTC - 6 hrs

Yeah...blend seemed to make sense when I visualized it. Good to know others are doing the same thing.

I dig the idea of using component.cfc to hold baseClass methods; unfortunately I am often in a shared hosting environment so that's a "no-go" for me. Luckily my main application only has 5 or 6 classes so it's not too much trouble to extend the baseClass in each of them.

Posted by Josh Nathanson on Jun 19, 2007 at 05:44 PM UTC - 6 hrs

Leave a comment

Leave this field empty
Your Name
Email (not displayed, more info?)
Website

Comment:

Subcribe to this comment thread
Remember my details
Google
Web CodeOdor.com

Me
Picture of me

Topics
.NET (19)
AI/Machine Learning (14)
Answers To 100 Interview Questions (10)
Bioinformatics (2)
Business (1)
C and C++ (6)
cfrails (22)
ColdFusion (78)
Customer Relations (15)
Databases (3)
DRY (18)
DSLs (11)
Future Tech (5)
Games (5)
Groovy/Grails (8)
Hardware (1)
IDEs (9)
Java (38)
JavaScript (4)
Linux (2)
Lisp (1)
Mac OS (4)
Management (15)
MediaServerX (1)
Miscellany (76)
OOAD (37)
Productivity (11)
Programming (168)
Programming Quotables (9)
Rails (31)
Ruby (67)
Save Your Job (58)
scriptaGulous (4)
Software Development Process (23)
TDD (41)
TDDing xorblog (6)
Tools (5)
Web Development (8)
Windows (1)
With (1)
YAGNI (10)

Resources
Agile Manifesto & Principles
Principles Of OOD
ColdFusion
CFUnit
Ruby
Ruby on Rails
JUnit



RSS 2.0: Full Post | Short Blurb
Subscribe by email:

Delivered by FeedBurner