The Dopefly Tech Blog

« The Dopefly Tech Blog Main page

Fun with Functions and CFCs X - Summary, links and closing words

posted under category: ColdFusion on December 21, 2007 by Nathan

I hope you all enjoyed reading this little series on the strange and interesting things you can do with ColdFusion's components and functions. Here's a quick summary.

Part I, I introduced the subject and gave a basic intro to the public (this.*) and private (variables.*) scopes of a CFC.
Part II, we discussed violent encapsulation intrusion.
Part III, we talked about adding, changing and removing methods in a CFC instance.
Part IV, I gave you the bad idea of having the same method alias run different functions, depending on where you called it from.
Part V, I left the weekend with an actual good idea, safe API updates via function aliasing.
Part VI, we talked about the different ways to inject functions into a component.
Part VII, I discussed duck typing and how others have done it.
Part VIII, there was a fascinating example on functional programming with CF.
Part IX, yesterday, I showed off inverting a CFC, making the private interface public.
Part X, today, is this summary.

I wish I'd had the time to make one on some of CF8's new toys, but those will just have to wait :)

Again, I hope you enjoyed this series and I hope someone out there learned a lot. Have a great holiday, Merry Christmas and God bless, from my family to yours.

(Discuss with Disqus!)

Fun with Functions and CFCs IX - Inverting a CFC

posted under category: ColdFusion on December 20, 2007 by Nathan

Here's something I toyed with years ago, revisited. In CF, you can turn your objects inside-out, making all the private variables and methods public. Just take a dash of part II and a little ingenuity and you get this:

myCFC = myCFC.getVariables();

Or, from within the CFC itself, or via a injected/attached method, you can do this:

this = variables;

This will replace the public interface with the private one. Hmm. I would never recommend doing that in real life, though maybe for debugging in a development environment.

(Discuss with Disqus!)

Fun with Functions and CFCs VIII - Functions as Variables and Functional Programming

posted under category: ColdFusion on December 19, 2007 by Nathan

CFML acts a lot like Javascript, really. In this series, I've been throwing around functions like they were candy. Indeed, ColdFusion and CFML let you do that. So let's have some fun with it.

function add(n1,n2) {return n1+n2;}
function subtract(n1,n2) {return n1-n2;}

function doSomethingWith2Numbers(thingToDo, n1,n2) { return thingToDo(n1,n2);}

writeOutput( doSomethingWith2Numbers( add, 5, 5) );
writeOutput( doSomethingWith2Numbers( subtract, 5, 5) );


Just the fact that you can is awesome.

The best benefit I can see right now for tossing around functions as arguments is for late-binding actions. You compile a handful of things to do, then execute them at the last possible moment. I like this approach for generating UI elements from OO systems in particular. We set a bunch of preferences, then, when you call render(), the system spits it out based on different code generation methods that were previously defined. That's one of my favorite things: instead of asking if a switch is on or off, just execute the method resting in a function reference.

(Discuss with Disqus!)

Fun with Functions and CFCs VII - Dynamic interfaces and better duck-typing

posted under category: ColdFusion on December 18, 2007 by Nathan

I actually found another good use for all this fun I've been having with CF's dynamic nature.

What if you want a component to implement another interface when your application is running? What if you are trying to do duck typing and want to make sure your component really is what it is supposed to be?

In my previous post about mixin methods, I touched on a method of mixing an entire component into another, essentially merging the two. This is great for a lot of reasons.

For duck typing, if you're attempting to pass one type of object into another, no matter what type of object it is, just so long as it has the required functions, this is both a way to make one object quack like that other object, and to validate that it should quack alike.

If you are keeping a typed system and you want to pass one type of object into a system that is expecting another, you can make an object of that type, inject the current state and methods into that object and return that object in place of the other. Wow, yeah, I can't actually imagine doing that, but it's great that it's possible.

Robin Hillard had the same idea, but in reverse (and also 3 years ago), where you pass your component to the component you want to duck/quack/emulate. This makes more sense actually, that way you don't have to cheat and introspect the private variables scope, it's available, but all Robin's methods are only set on the public scope of the original object. But it's six or half a dozen.

Even still, this isn't the best way. Joe Rinehart came to the same conclusion I do (but almost 2 years ago), and that is to use ColdSpring to set your CFC via mixin method. He makes some good points, too, and it is a solid sounding solution.

(jump break)


One thing Joe brings to light is the thought of what a mixin consists of. Is it just functions, or does it include properties (public or private)? I would argue both, but that one mixin should never overwrite anything in the resulting (aka more important, aka duck typing, not the duck typed) object. Joe thinks it should be just the functions.

Here's a bad idea! Go typeless, then mix all your components together into one super-everything beast. Mix in your DAOs with your services, with your business objects. Wow. it can do everything. Then you only have one object in memory. Yeah, no idea why you would do that either. BTW, watch out for identical methods that do different things. Maybe it would be nice if you have a handful of service objects, like a UserService, a PreferencesService, etc., you can mix those types all together, then you would have a single, unified service layer.

Yeah, still not a good idea, but I could almost envision doing that.

But not quite.

(Discuss with Disqus!)

Fun with Functions and CFCs VI - Mixin Method Methods

posted under category: ColdFusion on December 17, 2007 by Nathan

We have been playing with the concept of mixing in methods, or injecting them into CFCs voluntarily or not. Here is a list of ways you can dynamically assign methods to components.

Include method The easiest way to get common functions into multiple CFCs is to place them into a .cfm file and simply cfinclude the file. Place the cfinclude basically anywhere within your cfcomponent tags. The constructor area (anywhere not in a function) is the best place.

The greatness of the cfinclude mix-in method is that you set it basically in stone when you code it. It's a concrete thing and it doesn't change as it is executed, just like typing the functions into the CFCs themselves. I have used this for common setters, like a setUtilities method, where I wanted to inject it on a number of different unrelated objects, but didn't want to type it more than once, and it didn't make sense to extend a common component.

Cheap injection method This is one I covered previously - you can just set another function onto the public interface of a CFC. That function will now have access to the private variables of the CFC. You can, for example, make a getter for an internal variable that shouldn't have a getter. It's a cheap hack, and works great.

Sneaky injection I call this one private scope injection. Much like the above method, but you create a getVariables method and inject the function into the private scope.

The greatness of these two methods is that they are dynamic ways to hack into components. It feels dirty to me, but it's possible.

Single function mixin() method Somewhat more of an official way to do it would be to create a mixin function inside a CFC that takes a function name and function as arguments. The method will then set the function into the appropriate scopes. This is pretty clean, and hey, you can somehow inject the mixin() function itself.

Entire component mixin() method This is where mixins actually start to become useful. You can merge one CFC into another. Make a function that accepts a component as the argument, set the public "this" struct items to the current "this"scope and force some introspection to set the private variables into the current "variables" scope.

We'll talk more about this last one next time.

(Discuss with Disqus!)

Fun with Functions and CFCs V - Method Copying / API Updates, Practical Uses

posted under category: ColdFusion on December 14, 2007 by Nathan

Here's something I did a few months ago. What happens when the names in your exposed API are too confusing? It's been published, now it's too late to take it back, and now millions of other developers (ok, a handful, if we're lucky) who depend on our object would cry foul if we changed it. What to do, what to do?

Well, why not just rename the method? Ok, rename is too strong a word. How about copying a pointer? Oh yeah, that's easy.

<cfset variables.getMethodWithStandardName = variables.getMethodWithFunnyName />
<cfset this.getMethodWithStandardName = this.getMethodWithFunnyName />

There we go, now you can go about using an updated API while leaving the old API in place and not breaking any backward compatibility!

(Discuss with Disqus!)

Fun with Functions and CFCs IV - Public Method, Different from the Private Method

posted under category: ColdFusion on December 13, 2007 by Nathan

Here's an interesting idea. Probably not a good one, but check it out. What if external calls to a CFC method execute something different than when you call that method from within the CFC? It's easy. Here's the code:

<cfcomponent>

  <cffunction name="init" access="public">
    <cfreturn this>
  </cffunction>

  <cffunction name="privateMethod" access="private">
    <cfreturn "This is a Private Method!">
  </cffunction>

  <cffunction name="publicMethod" access="public">
    <cfreturn "This is a Public Method!">
  </cffunction>

  <cfset this.genericMethod = publicMethod />
  <cfset variables.genericMethod = privateMethod />

</cfcomponent>


Now private calls to genericMethod() will give you the private method message, and public calls to myCFC.genericMethod() will return the public method message.

I honestly can not think of a use case for this one. Got any? leave a comment.

(Discuss with Disqus!)

Fun with Functions and CFCs III - Method Injection

posted under category: ColdFusion on December 12, 2007 by Nathan

Using the code from the previous entry in this series, Fun with Functions and CFCs II, we can take the example further and inject a new method into a CFC:

<cfscript>
  function methodToInject() {return "This method was Injected";}
  myCFC.getVariables ().injectedMethod = methodToInject; // inject a method into CFC "variables" scope
  myCFC.getVariables().this.injectedMethod = methodToInject; // also into public "this" scope
  writeOutput( myCFC.getVariables ().privateMethod() ); // call private method from test.cfc
  writeOutput( myCFC.injectedMethod() ); // call injected method
</cfscript>


We injected the method into both variables and this scopes so it would be available internally and externally.

Even more useful, you can replace existing functions:

<cfscript>
  function h4x0r3d() {return "This method has been hacked!"} // create a 'hacked' message function
  myCFC.getVariables().privateMethod = h4x0r3d; // replace privateMethod() with this function
</cfscript>

The next time anyone makes a call to privateMethod(), they will get "This method has been hacked!"

And deleting:
<cfscript>
  structDelete(myCFC.getVariables(), "publicMethod"); // delete publicMethod from internal variables scope
  structDelete(myCFC, "publicMethod"); // delete publicMethod from internal variables scope
</cfscript>

We had to delete it out of the public and private scopes (this and variables, respectively) - each scope had a pointer to the publicMethod() function.

Now, with a persistent component, like an application-scoped object, this can have long-lasting effects, but there could be many good uses for it, for example with an application lifecycle altering event such as a database crash, you could switch out calls to the database to instead return empty queries or a message.

Truthfully, it would probably be smarter to replace the entire component such as with a strategy pattern.

(Discuss with Disqus!)

Fun with Functions and CFCs II - Object Hacking, There Is No Privacy

posted under category: ColdFusion on December 11, 2007 by Nathan

There are a lot of fun and interesting things you can do with ColdFusion components that languages like Java just don't let you. This is part 2 in my series to explore the interesting things that you can do with ColdFusion components and functions.

Before we begin, let's make a test CFC - here's the one I'm using; Test.cfc:
<cfcomponent>

  <cffunction name="init" access="public">
    <cfreturn this />
  </cffunction>

  <cffunction name="privateMethod" access="private">
    <cfreturn "This is a Private Method!" />
  </cffunction>

  <cffunction name="publicMethod" access="public">
    <cfreturn "This is a Public Method!" />
  </cffunction>

</cfcomponent>

Now we'll make an instance of it in a plain-jane .cfm file:
<cfset myCFC = createObject("component","Test").init()>

Now here comes the fun part. I want to get and execute the private method from the .cfm page. Not allowed, right? Not exactly. let's make a free-floating function in my .cfm file (this could be done with a cffunction tag, but I like the familiar script syntax):
<cfscript>
  function getCurrentVariables() {return variables;}
</cfscript>

If I call getCurrentVariables() now, it will return the current document's variables scope, which consists of a reference to that function and to my CFC instance's this scope, but what if I put that function onto my test CFC's public interface?

<cfset myCFC.getVariables = getCurrentVariables />

now, myCFC.getVariables() gives me the variables scope of the CFC! if I dump myCFC.getVariables(), I can see everything that's going on inside. Woah, now I can play with the internals all I want.

#myCFC.getVariables().privateMethod()# returns "This is a Private Method!"

(Discuss with Disqus!)

Fun with Functions and CFCs I - Understanding CFC Private Vs Public - this is not Java!

posted under category: ColdFusion on December 10, 2007 by Nathan

I was reminded to blog something I've been thinking about and playing with for a while from the CFTalk List, so I'm starting a blogging series on the fun things you can do with dynamic languages, specifically with ColdFusion. This is part 1. We won't go over anything truly revolutionary in this series, but I do hope to invoke some good brain activity.

Before I get to the really fun stuff, I need to make sure we're on the same playing field, so this first entry is just instructional.

ColdFusion Components (CFCs) Intro CFCs are ColdFusion's answer to object oriented programming. They allow some OO-type syntax borrowed from CF's big brother Java. They allow access modifiers of Private (can be called only from within the current CFC instance), Package (can be called from CFCs in the same directory), Public (can be called from any CF code on the server) and Remote (Provides the entry point for web services, flash remoting, Flex messaging and invoking a CFC directly from a URI).

Public Vs Private - the clever trick When you instantiate a CFC (be it using createObject, <cfobject> or <cfinvoke>), ColdFusion, in the background, creates 2 structures (structure = struct, aka hashtable or map, aka name-value pair object, a collection of in-memory variables and data), one called Variables and one called this.

(jump break)


Variables is the private variables scope - methods and properties that appear here are not publicly available. Just like a .cfm page has a variables scope, shared with any cfincluded files, the variables scope is internal to the CFC, shared with any functions. The danger here is the old var your variables problem - if you don't specify a scope in a CFC, just like in a cfm, your variable will be set in this variables structure and can interfere with other seemingly independent functions that end up sharing the same Variables. All of your public, private, et. al. methods will appear here. Also, any variable you place in the variables scope is recognized as private.

This is the publicly available scope. Any methods you mark as public will appear here as well as in the variables scope. To set a variable here, you have to explicitly set it into This. Conveniently, the Variables struct actually contains the This struct. From within the CFC, This is located at variables.this. Externally, it is the only thing visible. One thing you will see in CF is <cfreturn this /> - this returns the public interface for an object, essentially returning the object itself from a method you called, for chaining methods. It's extremely popular with a CF standard practice, the init() method.

So this is the clever trick. Variables = private, Variables.This = public. I've never heard it done like that before, but it does work nicely.

Tomorrow, the real fun begins.

(Discuss with Disqus!)

Free toy inside! - A debugging tool, CFQuery Reassembler

posted under category: Free Code For You on December 8, 2007 by Nathan

Back a few years ago, before bind parameters were the cool thing to do with your queries (even if they should have been), it was easier to debug your queries in ColdFusion because you could scroll down to the debugging information, copy your SQL statement and paste it into your database tool of choice to run ad-hoc style.

Now that we're more sophisticated, the queries that show up in your debugging output aren't so easy to copy and paste. You get output like this:

insert into users (
  name,
  address1,
  address2,
  city,
  state,
  postal,
  country
) values (
  ?,
  ?,
  ?,
  ?,
  ?,
  ?,
  ?
)

Query Parameter Value(s) -
Parameter #1(cf_sql_varchar) = Nathan
Parameter #2(cf_sql_varchar) = 1234 Main St.
Parameter #3(cf_sql_varchar) =
Parameter #4(cf_sql_varchar) = Phoenix
Parameter #5(cf_sql_varchar) = AZ
Parameter #6(cf_sql_varchar) = 85001
Parameter #7(cf_sql_varchar) = US


How useless is that? You can't copy and paste that into your database query tool. Short of changing your debug template, you're stuck moving those values into the query one at a time to run it again in a controlled environment.

So I made a tool to simplify this. It's a simple .NET desktop application. You paste your debugging output query (like that shown above) and it will fix all the fields and give you something to paste back into your SQL editor, ready to run.

CFQuery Reassembler 1CFQuery Reassembler 2

It's a simple concept, and maybe I'm the only one who will ever use it, which is fine, but let me know if you like it, if you can use it, and what improvements we can make.

Download the CFQuery Reassembler now (requires .NET runtime 2.0). I would call this the 1.0 preview version. If you get any queries that don't come out right, drop a message here or mail me. If you have any useful suggestions, I'm all ears, but please remember I'm not a c# winforms guy, so don't expect any real magic.

PS - I'm releasing this as a BSD-licensed application. You can download the CFQuery Reassembler source code and VS2005 project files, here.

(Discuss with Disqus!)

Using regex in your IDE #2

posted under category: General on December 7, 2007 by Nathan

We had some good responses to yesterday's post, Use regular expressions to be clever in your IDE, so today I'll post another example. This time, it's the exact opposite.

Yesterday, we created code that will end up like this:

querySetCell(myQuery, "first_name", "Nathan");
querySetCell(myQuery, "middle_initial", "J");
querySetCell(myQuery, "last_name", "Strutz");
querySetCell(myQuery, "phone", "480-123-4567");
querySetCell(myQuery, "country", "US");
querySetCell(myQuery, "state_province", "AZ");
querySetCell(myQuery, "city", "Phoenix");


Now, what do you do when you want to get just the column names out of that mess? For me, I would use this search pattern:
querySetCell\(\w+, "([^"]+)",.+

The regex says to find the word "querySetCell", any query name - the actual word myQuery could be put here -, a quote, then save any character that's not a quote up to the next quote, a comma, and then anything until the end of the string (in our case, the line).

With regular expressions and code, always remember to escape special characters in your code, such as parentheses, square brackets, backslashes and so on.

Replace it with this matched text:
$1
Or be creative :)

There you have it, right back to the original list we started with yesterday.


Another thing to remember is that it's the parentheses that define the backreferences ($1 because we have just one). Nothing's stopping you from capturing the content in the column value portion of the querySetCell calls. Something like this would allow you to use that as $2:
querySetCell\(\w+, "([^"]+)", "?([^"\)]+)"?.*

Then replace it with:
myStruct.$1 = "$2";

(Discuss with Disqus!)

Use regular expressions to be clever in your IDE

posted under category: General on December 6, 2007 by Nathan

Here's something I do almost daily it seems. So much so that I take it for granted. A couple months ago a friend was looking over my shoulder and he exclaimed "What the--? You've got to save that and send it to me!" I explained how it was just throw-away code, and I could send it to him if he wanted. The code is long gone but that reaction stuck in my mind, so let's dive in with an example.

You have a list of values on lines and you want to want to apply some code to each:
first_name
middle_initial
last_name
phone
country
state_province
city


Select the lines, and use your IDE's find/replace tool with the regex option. In Eclipse, this is just CTRL+F and check the checkbox. Use this as the search pattern:
^(.+)$

This regex says to select any line with at least one character in it and store it in a character group.

Some code like this would be the replace pattern:
querySetCell(myQuery, "$1", "");

Replace them all and your code will be generated in an instant. The regex will drop each line's content into the $1 backreference.

There are dozens of other types of uses just like this one.

(Discuss with Disqus!)

HTML was so easy, what have we done?

posted under category: General on December 4, 2007 by Nathan

We all remember it. HTML was easy. That's how we all got started. For a beginner, just starting out (over a decade ago for me), it was straight forward and easy to get into. Make (or take) some images, put them on a page, maybe use a table. FTP it to geocities or one of those bargain basement $50/month web hosts. Bam! 300 visitors a month, easy.

Now what have we built for ourselves?

These days, to make a good site, you're pretty much required to have advanced HTML and XHTML skills, CSS mastery including managing floats and positioning, fine tuned event-driven object-oriented javascript abilities, DOM manipulation, command over Photoshop (or whatever you prefer), firm knowledge of AJAX, XML and JSON, and also have a handful of frameworks under your utility belt.

Then your site is useless unless it can connect to a database (SQL knowledge required) and do some neat tricks (knowledge of ColdFusion, PHP, ASP.NET which is the .NET library, the ASP tag library mixed into HTML and a language like c# or VB.NET, or, Java, for which you would know JSP, JSF and/or plain Java servlets, and probably Spring and Hibernate). Use of a server-side language then requires an architect, a business analyst, requirements gathering sessions, high-level and low-level diagrams, usability studies, flowcharts, requirements docs, use cases, test cases, project managers and so on.

Of course you get more traffic now, too, so you probably need dedicated servers, clusters or server farms. Virtualize some of that to save space (and add complexity). Redundant hardware load balancing is a must, along with redundant firewalls, redundant switches, redundant servers and redundant disk arrays with redundant hard drives. And what about disaster recovery? You'll have to get a redundant datacenter in Arizona with redundant power and cooling.

Now what have we built for ourselves? Job security, higher salaries, and a big industry with lots of workers. That's what.

(entry continued after the jump)


It's been amazing to watch it grow from a garage operation in the 90's to what it is today. Amazing. Astounding even.

The first Microsoft.com web site I visited was made by one guy and it ran from a cluster of 4 servers. One day he deleted the home page. Microsoft.com, seriously. The FTP site was far more interesting than the HTTP site. Archive.org's oldest record is from October 1996, by that time they had some real features, and were toting IE 3.0. Now it's multiple data centers with thousands of servers and workers.

This whole thing is amazing, and it's all because we all got into HTML in the 90's. Good job, team. Thanks for employing me. I hope I've helped make it complex as well and helped employ some of you. Of course simplicity is always the goal, sometimes the simplest way to do something requires the most complex solution, but that's another story.

Now, the down side is that it's harder to get into. Much harder. What was simple HTML and leeching images is now a large handful of connected technologies, which you must know to contribute nearly anything more than your myspace page. Try breaking into the world of web development today and I'll ask to see your master's degree. A lot of those ho-hum web guys are ones who got into it late and didn't get those foundational elements.

That's why the smart software companies are opening up easy routes in. Microsoft's free express tools are exactly that. ColdFusion is always there and Adobe Elements is a great effort, but aimed more at those who will never make it all the way into the industry.

The web business is more complex, but it employs us, and I think software companies forget how hard it was to get us here.

(Discuss with Disqus!)

How to customize fusebox 5.5 debugging output

posted under category: Fusebox on November 21, 2007 by Nathan

Recently, I made my first contribution to the Fusebox core files (Previous contributions were in the form of lexicons, which are valuable add-ons but not core files). My change was just an update to the HTML rendered from the Fusebox 5.5 debugging trace output.

The older debugging output had hard-coded styles on the tags, and no identifying overall element. If you wanted to change or fix a style, or even the entire block, there was really no good, reliable way to do it, short of modifying the Fusebox core files. With ColdFusion debugging output, you can use the .cfdebug selector to change the server debugging, but no such luck for Fusebox.

It's a superficial, mild annoyance, at best, but still a spot for improvement, so, I made the change and submitted it in an issue to the Fusebox Trac site.

For this change, I created a small style sheet, removed the inline styles, made some default styles and added an identifiable container for the block.

Now, how can you change the display?

The style sheet I made has a handful of styles that all start with .fuseboxdebug. With CSS, if you make a more specific selector, you can override options in the less specific selectors. A selector and style such as .fuseboxdebug h3 {color:green; background:blue;} will be overwritten by div.fuseboxdebug h3 {color:red}. The resulting h3 style from these examples will have red text on a blue background.

So, if you want to do something like hide the debugging output using CSS (Sean Corfield says you can do it in Fusebox with myFusebox.showDebug = false), the code would be:

div.fuseboxdebug {display:none;}

Some added benefits include the download size of the debugging output, cut in half, and it should stay a little more consistent across different site designs all while being customizable. See, CSS is good all around.

PS - Fusebox 5.5 is due out December 1st, and it's been perfectly stable with my 4.x and 5.x apps.

(Discuss with Disqus!)

Fusebox reload bookmarklet

posted under category: Fusebox on November 18, 2007 by Nathan

Bookmark this link: Fusebox Full Flush.

You can click it on this page, don't worry, you won't hurt my site.

When you select this bookmarklet from your own bookmarks on one of your sites running fusebox, it will prompt you for your fusebox password (you do have one, right?). Type it in and it will send the fusebox magical reloading URL parameters to your site:

fusebox.load=true
fusebox.parse=true
fusebox.loadclean=true
fusebox.password=(your password)

useful!

(Discuss with Disqus!)

The Dopefly family photos application

posted under category: Browsers on November 14, 2007 by Nathan

I'd mentioned a couple years ago an application I wrote in .NET that my wife, Alanda, uses to update the photos on our family photos area. So, after much anticipation, I present the dopefly family photo uploader:

Dopefly uploader with Jude's birthday

This is actually version 3, for the record. I polished this one off early this year, and have made only a few tweaks since.

Not too bad, huh? Thanks to Visual Studio 2005's drag & drop interface, it's got all kinds of standard looking gadgets like menus and a status bar - heh, it looks like a real application. :D   It's not all that well architected, it's not as much MVC as I like to do in a web application, but with hardly any actual desktop application programming experience, I think it's not too bad.

Another thing that VS2k5 did that absolutely astounded me was that when I published my app to our media center PC (where we host our photos, it's always on), it created an installer, which Alanda ran from her tablet. It put shortcuts in the start menu and even made an uninstaller. After she did some first round testing and finding a couple bugs, I fixed them and republished - lo and behold, the next time she started the app, it prompted her to install the newest version. It was shocking how easy it was and how well it worked.

One problem that we had when Dopefly's photo management was strictly a web application was that it took forever to upload a 3+ megapixel image, and I had a form where she could do 10 at a time, so she would basically set-it-and-forget-it for half an hour at a time. This is the main reason why I wrote it, to resize the images on the client-side before they go up to the web, and .NET is especially good at this. This process has sped the process up dramatically.

Follow along for a shot of the admin and another one of the uploader tool...

The tool itself is a drag & drop interface (supports file / open) - Alanda finds a photo on her mapped photo drive and drops it on the main window. She then picks associated tags for the photo, or makes her own in the text field and types up a description if she wants. The program reads the photo date, resizes the image to the appropriate size and uploads to the web service on Dopefly. It's convenient and she can do the whole process in 30 seconds if she's in a hurry.

Now, if you notice the severe lack of completeness - how does Alanda manage all these photos once you put them up on the site? Well our tried and true ColdFusion seemed a much better fit because this data was already on Dopefly.

Dopefly uploader admin back-end

I copied a fair amount of the functionality from the front-end, search by date, by tag name, and display the latest photos, but reformatted into an administrative tool look. When she finds a photo, it gives complete power over editing the data, even a calendar pop-out thanks to the YUI calendar widget. Not so shabby at all.

Back on the uploader application, I put the action controls in a tab control box and added the ability to create a larger thumbnail (is it really a thumbnail at this point?) for emailing photos to friends and family. It uses the same image resizing library as before (but with slightly bigger numbers) and outputs the result onto a specified folder. The combo box on this page has a few presets (desktop, my documents, my photos), but what I thought was cool was that with a few clicks I hooked it up to introspect the file system, so if she types in c:\, it will auto-populate the drop-down with folders on the root of the drive, etc. Seriously, just a few clicks and it worked like a charm.

Dopefly uploader cropping for email

What have I learned?
I learned that Google is the best tool for application development ever created. When I got stuck, I would just google it.
Most of my problems stemmed from my not knowing how to name my problems to know what to google. What's the name of the class that handles such-and-such? Sometimes this would lead me down a series of googling efforts.
Visual Studio 2005 is pretty amazing for desktop applications (Thanks Microsoft for the free copy!).
Have patience with the learning process, it will come together eventually.

(Discuss with Disqus!)

Extends is not a form of include!

posted under category: ColdFusion on October 26, 2007 by Nathan

This is one I never thought I'd see, but unfortunately I have seen it a few times.

Think twice when you extend a class/component! In ColdFusion, that would be with the extends attribute of the cfcomponent tag.

When you extend a component, you are saying that that component, the one you are writing the "extends" text into, is a type of the component you are extending.

Ok, let's have an example.

Let's say we have a logging component. We say: myLoggingService.log(message); and it does it for us. Easy enough.
Also, we have a user component. User.setName(form.name); User.save();, and it saves it somehow. Basic stuff, easy to grasp.
Now, how do you write a log message after you save a user? There are, of course, dozens of ways to do this.

The way you should NOT, EVER under ANY circumstances do, is say that the user extends the logging service. That doesn't make any sense. Is a user a type of logging device? I certainly don't think so. A user doesn't write logs, a user has a name and probably knows what object to call to persist itself. The logging service writes logs. That logging service needs to be its own separate entity. It just doesn't make sense any other way. You can call it from within the user object, or better yet, from some kind of controller or service layer, but don't integrate it too deeply within an object that it doesn't need to be deeply coupled with.

Oh I know, it's a matter of convenience, you can just say log(message);. Oh wow, it saved you 17 characters, but you missed the point entirely.

The correct way is to leave the logging service by itself, then call myLoggingService.log(message). I think it's somewhat a matter of style where you call that from, of course be consistent. The rule is this: Favor composition over inheritance. Your User object can be composed of a logging service (among other things), and you should do this whenever possible.

Now, if you have a database logging service, this is a prime candidate to extend a more generic logging service. Or how about an error logging service? Those are types of logging services. Inherit up from a generic implementation, down to a specific one.

(Discuss with Disqus!)

Pagination.cfc 0.2 release

posted under category: Free Code For You on October 14, 2007 by Nathan

Tonight I'm releasing version 0.2 of my Pagination.cfc. I added a lot of features and functionality and have a bit more to go before a 1.0 RC. Also, I cleaned up the API a lot so if anyone out there is using 0.1, read the notes at the top to see the new usage sample. I think I nearly doubled the file size with this update. No, it's not slower. More to come on this one still, at least until I make a 1.0 final release.

Update: Sorry Nolan, Here's the download link. (it's nice when someone cares)

(Discuss with Disqus!)

Free code: Pagination.cfc

posted under category: Free Code For You on October 10, 2007 by Nathan

Last weekend I updated my family photos area. I have to do something to it every few months so my wife will keep using it.

In the process, I created a cfc for paging through a query. I saw something similar on cflib.org, but I was hoping for something a little more OO and a little more customizable for me to use on any number of other projects.

Some cool things about it is the customizable output and the caching when you call getRenderedHTML() so you can output it at the top and the bottom of the page without any performance hit.

Some room for improvement would be adding a few more convenience methods like getCurrentPageNumber() and the option to leave the <Previous link text up (but no link) when there is no previous page, that kind of thing. More suggestions are definitely welcome. Also I think the API will change somewhat to make it more discoverable, but I'm not sure how, yet.

I created it and licensed it this weekend without a release, then earlier this week, I realized I could use it in a project at work. I downloaded it and dropped it in, and it worked perfectly with nothing to change.

So, this is version 0.1 with a BSD license (free to do what you want with it but leave my © on it). Download Pagination.cfc here.

BTW, before there is any confusion, this is a one-use-only object, you create an instance of it when you need to output pagination and throw it away with the page. Do not put it in your application scope. Coldspring users, singleton=false.

(Discuss with Disqus!)

Farewell Interactive Sites, Hello Boeing

posted under category: Life Events on September 24, 2007 by Nathan

It's sad when the time comes to leave the best job you have ever had, the best team you have ever collaborated with and the most fun projects you have ever worked on. That time comes for me this Thursday, September 27th. My +2 year term at Interactive sites has been just that. Thanks to everyone who made working there great. Future employees, this is a great place to work.

It's not all sad, however. I'm taking a CF developer position at Boeing thanks to a good friend of mine. The money is even more respectable and the travel time should be less than half of before. Deals like this don't come around often. It's a great opportunity for myself, my family, and hopefully for Boeing.

(Discuss with Disqus!)

Jason Delmore wants to know what you want in CF9

posted under category: ColdFusion on September 14, 2007 by Nathan

Jason Delmore, the product manager for ColdFusion, aka the "CF Insider" asks What do YOU want next for ColdFusion?

This topic comes up every couple years. Hmm... yes, always seems to be right after a major version release. Bug reports are trickling in and the team is getting antsy for something new to work on. I've gotta say, it seems like they answered almost everything I could have wanted in CF8, so it's time to dream a little bigger.

I already see some really good comments, get on out there and tell him your opinions!

(Discuss with Disqus!)

Some early thoughts on web application testing

posted under category: ColdFusion on September 12, 2007 by Nathan

Recently I decided to become interested in software quality. Let me assure you, it's not something you gravitate to when you're cowboy coding for thrills or something you decide to pick up because the cool kids are doing it. No, this is something you have to decide to like.

I said I decided this recently, so here are a couple of my early thoughts on the subject.

Web application testing tends to focus on the front-end. If you can see it in a browser, that's what you need to test. Or at least that's what I hear a lot of. Of course this testing is great at revealing missing requirements and catching exceptions, but that's the same testing we used when we tested our HTML pages in the 90's.

Come on now, is this a web site or a web application? Am I making a script or a system? Do I serve pages or programs? I certainly like to charge my clients based on the latter.

So how does testing change when you consider applications opposed to pages? This is the question I've been pondering, and I am still working on my conclusions. One partial answer is the unit test.

A unit test is an automated script that calls methods on an object. It helps to have a unit test framework that can run the tests and tell you the results in a pass/fail style (there are a couple for CF). The framework can run a number of unit tests all at once to give you a view on your overall system.

Something notable from The Pragmatic Programmer, tip # 66, "Find Bugs Once," meaning once a bug makes it past you, the developer, and appears for someone in QA or, worse, a customer, add that bug to your unit test to make sure it never slips by again.

The bright red glaring issue in this space is the lack of testable software. How do you make ColdFusion applications that can be driven by TDD? Is OO the only answer? Can you unit test a .cfm file? How can I unit test a legacy (CFMX6.0) application?

I'd like to hear what people are doing. Comment below or blog your own experiences in reply. Thanks!

More later, like I said, I am now interested in the subject :)

(Discuss with Disqus!)

Hal and Jeff are back | Matt and Peter are back

posted under category: General on September 11, 2007 by Nathan

I've been enjoying my commute the last couple weeks, as it seems Hal Helms and Jeff Peters' podcast "Out Loud" is back in business and Matt Woodward and Peter J. Farrell's ColdFusion Weekly podcast is back from summer vacation.

For Out Loud, the August 16th episode talked about jQuery, which I have subsequently taken up and fallen in love with. The August 31st episode talked about layer separation of your view layer and finding/creating/defining beauty in coding, a couple of subjects that have always interested me. Interesting how different layers of a layered architecture can be broken up.

CF Weekly, I confess, I haven't listened yet. I will have to get to it during tomorrow's commute. Looks like a big welcome back and news party from the show notes.

It's a little difficult to sync my iPod without a video card. Not impossible, just very, very difficult. Dual core due Wednesday. :D

(Discuss with Disqus!)

The Yahoo YUI Theater

posted under category: General on September 5, 2007 by Nathan

Here's something I spotted that should be pretty interesting to all developers who like to learn by way of video. I stumbled upon the YUI Theater.

Now, before you get scared off, if you're not interested in the YUI javascript framework, the YUI Theater isn't about YUI as much as it is about javascript in general.

I'm progressing through Douglas Crockford's segmented presentation "The JavaScript Programming Language". He has an incredible amount of information that comes very quickly. I'm glad they split it up into 4 parts so I can breathe in between.

One that looks great to me is Joe Hewitt presenting on his own project, Firebug. Another is John Resig's javascript framework presentation (John Resig is the creator of jQuery).

There is a serious amount of content on the YUI Theater site, and I recommend that anyone who touches javascript try learning some more via Yahoo.

(Discuss with Disqus!)

Firefox - enable spell checking programmatically

posted under category: General on August 17, 2007 by Nathan

Just playing around with Firebug and I noticed that my form fields have a "spellcheck" field. Of course Firefox doesn't spell check plain text fields normally, so it's set to false except in text areas. The cool part is that this is just a plain attribute. Feel free to turn it on, like this:

document.getElementById("myTextInputField").spellcheck = true;

Then start typing in that text input field and Firefox will spell check it as you type.

(Discuss with Disqus!)

CF8 Eclipse plugins updated for Eclipse 3.3 compatibility

posted under category: CFEclipse on August 17, 2007 by Nathan

I almost missed this myself. Dean Harmon at cfreport.org offers us a compatibility patch for the Adobe ColdFusion plugins for Eclipse that were released a couple weeks ago along with Coldfusion 8. This new version simply fixes the error you get when you try to open a query window with the RDS database tools. I installed it and I'm happy it works now. Thanks Dean!

(Discuss with Disqus!)

ColdFusion 8 Launch Day! Hooray!

posted under category: ColdFusion on July 30, 2007 by Nathan

ColdFusion 8 is available!
I can't wait to start real development with the new CF8 features. And who wouldn't love the huge performance increase, debugging and seemingly magical AJAX tools?

By the way, now is the best time ever to switch to Eclipse, if you haven't already. The ColdFusion 8 Eclipse plugins are a huge help to the already popular CFEclipse plugin.

Big thanks to the teams at Adobe who gave us nearly everything we ever wanted with this one. Now the big question... what could possibly be next?

(Discuss with Disqus!)

CFEclipse and Eclipse 3.3 playing well together

posted under category: CFEclipse on July 9, 2007 by Nathan

Sorry for the late update, and I know this is old news, but Mark Drew, the hardest working CF developer out there, released CFEclipse 1.3.1.5, which brings compatibility to Eclipse 3.3. (Thirty?) Three Cheers for Mark!

P.S., In case it's not handy for you, the CFEclipse auto update URL is: http://www.cfeclipse.org/update/. You can always tell for sure if the remote directory contains a site.xml file ;)

P.P.S., Eclipse 3.3 works great on Vista.

P.P.P.S., Vista doesn't work so great.

(Discuss with Disqus!)

Eclipse 3.3 is out, ColdFusion developers wait...

posted under category: CFEclipse on June 29, 2007 by Nathan

Eclipse 3.3 was released this morning, along with 20 other simultaneous releases from the Eclipse Foundation in an effort titled Eclipse Europa. With lots of new features, hundreds of improvements on tools we have been using over the last year, what's not to love? Well how about backwards compatibility with our favorite editor, CFEclipse.

It appears that Eclipse 3.3 has broken compatibility with a number of plugins, including our own CFEclipse, mostly based on changes to the JavaFileEditorInput. There's actually a lot more to it than just that, as some Eclipse 3.3 features override what the CFEclipse developers have worked so hard to make happen, such as dragging and dropping text.

The only way to get Eclipse 3.3 support with CFEclipse is to get enough people to promise Mark Drew enough beers, Amazon wish list items and airfares to conferences via his paypal link in order to motivate him.

Until then, we will all just have to stick with Eclipse 3.2.

Mark, I think I owe you about a dozen drinks of your preference, any time you're in Phoenix.

Help us Mark, you're our only hope...

(Discuss with Disqus!)

Favorite new features in Eclipse 3.3

posted under category: CFEclipse on June 28, 2007 by Nathan

Here are some of my favorite new features in Eclipse 3.3:

  • Text drag & drop - I know the CFEclipse crew had to bend over bakcwards to make it work just for the CFE editor, I'm so glad it's universal now
  • Show invisible whitespace characters - i couldn't find a button but i can link it to a keyboard shortcut
  • Editor area drag & drop - drag files, even from outside Eclipse onto the editor area (puts in "filename.ext") or the editor title area (tabbed bar, opens the file)
  • Automatic spell checker in text editors
  • Updates to the key shortcut prefs - getting better each time
  • Hiding that darn main toolbar area
  • Vista support, including a WPF rendered interface

(Discuss with Disqus!)

Eclipse Europa Release - Friday, June 29th

posted under category: CFEclipse on June 27, 2007 by Nathan

The annual Eclipse project last year, if you recall, was Callisto - a simultaneous release of 10 Eclipse Foundation projects. This year, the number of projects has more than doubled to 21, including the Eclipse Platform 3.3, the Web Tools Platform 2.0 (including a visual page editor!), the Data Tools Platform Project 1.5 (supports Derby), a Dynamic Languages Toolkit (supports Ruby and Python out of the box, when will it support CF?), and a lot more.

You can download the release candidate today at the Europa site, or wait for Friday afternoon to get the finished and full enchilada.

When I say Friday afternoon, their releases are typically hours after I expect them, so just keep hitting the Europa site until it changes. Last year it was around 4:00 PM PST.

I'm not sure yet how the upgrade cycle will go. I recommend creating a new Eclipse install folder and using your existing workspace. Make a backup of your workspace first, just in case. As a side effect, this will dump your old plugins, so you'll have to reinstall them, which isn't bad - you can reflect on which ones you use and don't use, and make sure you get the latest versions of them all.

Finally, the last I heard, CFEclipse wasn't officially supported on Eclipse 3.3, keep your eyes on Mark Drew's blog for any updates. I'll definitely upgrade when 3.3 final is released, and I'll let you all know.

(Discuss with Disqus!)

Eclipse trouble? This solves 80% of plugin issues.

posted under category: CFEclipse on June 15, 2007 by Nathan

If you're using Eclipse and are having plugin problems, be it you think you installed one and it isn't showing up, or you are having some kind of conflict, or an older version is coming back from the dead, there's one easy fix that will solve it most of the time.

Eclipse.exe -clean

That's all it takes. Eclipse will take a few extra seconds to start up as it cleans its plugin cache.

(Discuss with Disqus!)

No, Thunderbird did not just delete all your email.

posted under category: General on June 15, 2007 by Nathan

I just had a minor freak-out because it looked like Mozilla Thunderbird (my email client of choice) just deleted a ton of email. Years worth. I was moving it to an archive folder, and when I went to check the folder, it was all gone. Just a handful of emails were left. They weren't in my inbox! They weren't in my archive folder!

I left and checked the file system. The new archive folder files were 50 MB, the old inbox was still 150 MB. Something wasn't right.

My next thought was that I didn't have a backup. This is the one place I've found Windows Vista (hey, I got it for free) to shine - Shadow Copy. It's like a constantly running backup on the same disk that reminds me a lot of Eclipse's local file version archiving. I restored my mail folder back a couple days and expected everything to be peachy. Guess what? Nothing changed.

My inbox was noticeably a couple days older, but my older mail was still gone. Ok, this is getting weird. I re-restored to my current-date inbox.

After poking around a minute in the Thunderbird interface, I found the Rebuild Index button, conveniently located on the folder's properties window (right-click on a folder, properties, Rebuild Index button). It took a few seconds and suddenly everything was back.

No, Thunderbird did not just eat all my email. It was still there, safe and sound, but boy did that give me a scare.

(Discuss with Disqus!)

Slipped my radar: Kuler Apollo widget

posted under category: Design on May 31, 2007 by Nathan

I just noticed the Apollo Kuler widget was released through the Kuler site. It umm, works as advertised. I'm a fan of Kuler, if nothing other than I don't have to experiment with color schemes to get one that works. Here's a screenshot of my family photos admin area and the color scheme (kuler scheme?) I used on it. The cool thing is switching it to a new scheme is a no-brainer. Yep, programmers work as hard as they can to be as lazy as possible.





(Discuss with Disqus!)

Fusebox 5.5 - What's coming? Here's 10 great features.

posted under category: Fusebox on May 30, 2007 by Nathan

The list of new features for Fusebox 5.5 is growing. There's a fair amount of chatter on the list surrounding what's going to be in there. Here are some of the things Sean has been talking about.

  • XML files will now be optional.
  • You can use or omit the fusebox.xml file, defaults will be configurable through a simple struct.
  • You can use or omit the circuit.xml files from Fusebox 4 and 5.
  • You can use plain-jane directories and cfm files for the circuits.
  • Fusebox will automatically discover your circuits and fuses, with or without a circuit.xml file, with or without a reference in your fusebox.xml file.
  • You can use CFC files to run your circuit, you just have to implement an interface (no, not literally).
  • Fusebox prefers if you use /model/ /view/ and /controller/ folders and circuits.
  • You can mix and match your preferences within a single Fusebox 6 application - some circuits with CFCs, some with plain files, some with circuit.xml files, etc.
  • There will be a dynamic "do" action, you call myFusebox.do("circuit.fuseaction").
  • Scaffolding for CRUD applications through a plugin or extension.

(Updated 6/8, Renamed Fusebox 6 to Fusebox 5.5)

(Discuss with Disqus!)

I use Google Reader, and I like it.

posted under category: General on May 25, 2007 by Nathan

There was a question posted on the cf-talk list about feed readers. In an effort to make everyone exactly like me, I said I use Google Reader, and here's why I like it.

I find the shortcut keys essential, so much so that I keep trying to hit "j" when reading blogs on other sites to get to the next entry. I typically get a few hundred of entries a day, many of which I can go next, next, next right past, then star the deeper stories for later reading.

There's a "share" button on each story that kicks out a feed of its own here's mine). You can find a little widget on the left side of my blog with my latest shared items. I like the idea of sharing what I find that's cool, so there's fresh content on my blog even if I'm not writing anything.

Then there's the Google Reader tools on the iGoogle homepage - I use the Reader pod and have a few individual RSS feeds directly in their own pods. iGoogle is the first homepage I've used since yahoo circa 1996 - I had about:blank until about a year ago.

Perhaps the most fun and obscure feature of Google Reader is the Wii version. It makes reading my feeds simple and fun from the couch. This very responsive interface has naturally easy controls, which I love.

(Discuss with Disqus!)

Adobe Web Studio CS2 Review

posted under category: General on May 22, 2007 by Nathan

I thought now that CS3 is out, I should probably write up something about my experience with CS2, since Adobe was nice enough to give it to me free (thanks to User group giveaways).

Unboxing.
The box cover was large and colorful. The inside box itself had a black-on-black A for Adobe logo. I put up a couple nice shots of it on Picasa for you to see for yourself.

The installation.
Really, there were 2 parts to the installation - installing Adobe products and installing former Macromedia products. Adobe products included Photoshop, Illustrator, GoLive, Acrobat, and a couple other things I've never used nor plan on using, like Bridge, Version Cue and LiveCycle Designer. There were lots of disks, I hope this ships on one DVD next time around. The Macromedia software installation was as simple as ever, click a couple buttons and it all comes off of one disk. Macromedia software included Dreamweaver, Flash Pro, Fireworks, FlashPaper and Contribute.

Photoshop CS2.
The undisputed king of all computer graphics, Photoshop, is as good as ever, but honestly, it hasn't changed much in the last few versions. There's a lot of people who would debate its bloatedness and complexity, but for those of us who have been using it for 10 years, it couldn't be easier. So it helps to learn a couple hundred keyboard shortcuts, you're smart, you can learn them. So maybe it takes a gigabyte of memory, that's memory well spent. Anyways, all the old favorite features are in here, but I get the sense that the new features were hardly more than putting enough in just to make marketing look good. I'm just saying, it was a little light compared to changes in some of the previous upgrades. Maybe not worth of a full upgrade from CS, in my opinion. Not to say that I don't love Photoshop, and perhaps there are a few big time savers in there that will allow you to justify the cost. In fact, the layer organization features alone may be worth it, but that's your call.

Continue on to read the thrilling conclusion...


Illustrator CS2.
I haven't used a lot of Illustrator, but trying it out a couple times since I installed this version has been a very satisfying and fun experience. Illustrator is just as technical as before, but somehow it works a little better and makes more sense. I hate to say it, but this version of Illustrator makes Freehand look really bad. This is the most fun I've had in a drawing program since Auto-Illustrator. I will be using this one more.

GoLive CS2.
I've used GoLive since it was GoLive CyberStudio for the Mac, though I've never used it much. It's been a fine editor for a long time, but always lacked that pro feel of Dreamweaver. I cracked this version open a few times only to click around, get bored and close it again. I did, however, use it to open an XML file one time, and I've got to say, that was a treat. The collapsing tag view was perfect for browsing and editing XML nodes. This, however, is the only reason I think I would ever use GoLive again.

Dreamweaver 8.
I've used Dreamweaver since the original beta version, so I'm fairly comfortable with it, though I haven't ever committed to it, thanks to HomeSite/CFStudio and CFEclipse. Anyways, this release is better than ever. DW's tried and true "we don't change your code" strategy is always a winner when using the design view, and Dreamweaver remains the best tool out there for visually designing web sites. The code editor still, for no reason whatsoever, feels wrong, like it's not fast enough or instantly gratifying enough. I can't explain it. The greatest thing is the huge list of file types it supports. It gives intellisense and highlighting for almost any web-related file type. It's solid, never once crashing for me, and I believe it opens a fair amount quicker than the previous version. Dreamweaver 8 is a very nice program, and is becoming easier and easier to use, while not forcing developers to give up control.

Fireworks 8.
Again a Macromedia product I've used since it entered beta, and I'm happy to see some of the ideas from fireworks entering Photoshop CS3. Likewise, a lot of the advanced photo editing features that MM "borrowed" from Photoshop are here, but not nearly as well polished. Fireworks is a truly fun web image program that instantly gratifies. It's fun to use, but even as much, I would only use it on the types of projects I worked on, say, 7 years ago - these were tourist sites, simple 6-page brochures, etc., where I did design, graphics, HTML and programming all by myself. Sadly, I personally don't have much use for it today. Ahh when times were simpler. :)

Flash Professional 8.
The program I have used the least of all. I just don't do flash anymore. I never really loved the event/action/keyframe programming model - I know it's better now, but I'm too buried in CF to do any flash. Sadly, I have nothing really to say. I played with it for a couple minutes just to say I had, and I fire it up whenever I have a flash file to edit, but that's so rare these days. It does export to previous versions of the flash player quite well.

The Rest.
Contribute: Never used, probably never will.
Flash Paper: I keep hoping to find a reason to use it.
Bridge, Version Cue: Bloatware, in my opinion.
LiveCycle Designer: Could be cool, if I take time to learn it.

Overall, it's an amazing software package to own for any developer. Thanks to the AZCFUG and Adobe for supplying it, I really do appreciate it a lot!

(Discuss with Disqus!)

Ben Forta - Tonight!

posted under category: ColdFusion on May 2, 2007 by Nathan

This is a final reminder that the Ben Forta Phoenix meeting is tonight! We've got a huge crowd of developers showing up, so it's a great chance to network. Lots of stuff to give away, most everyone will end up with something. Parking is a little limited due to construction, so come early or park at Fry's Electronics across the street.

The event starts at 6:30 at the UAT in Tempe, AZ. Map.

Also, there's a raffle system - you get a ticket for pre-registering at www.azcfug.org, one for filling out a survey when you get there, and then you can give some cash to the CFUG for more, so bring a few dollars and you'll have more chances to win the big prizes.

Last, some of us will probably head to Aunt Chilada's directly afterward to catch the end of the Suns/Lakers game, grab some drinks (lemonade is a drink) and talk about the presentation.

(Discuss with Disqus!)

Forta in Phoenix - May 2nd

posted under category: Browsers on April 26, 2007 by Nathan

If you're anywhere near the Phoenix area, you're going to want to be here for the ColdFusion event of the summer. I sit about 20 feet from the CFUG manager, Alan, so I have a pretty good source of information within yelling distance, and I heard a little talk about the event, and the giveaways we'll be having, including copies of Scorpio and Flex, certification exam passes, Adobe software bundles, expensive tech books, and the usual schwag, t-shirts, pens and so on. Plus I hear Ben's going to give some sort of talk about the future of ColdFusion - not sure about that part :D

If you can make it, register thyself at www.azcfug.org.

You know, I haven't been to an AZCFUG meeting in the last 9 months or so that I haven't won via raffle some kind of thing, be it a USB fan-light or an Adobe t-shirt, a tech book or a software package, free stuff is always cool, and these events are always worth going to. I've won enough cool stuff that my wife even encourages me to go now.

(Discuss with Disqus!)

GParted - Best Utility Ever

posted under category: General on April 24, 2007 by Nathan

I bought a new hard drive last week, along with my new video card. Now I had to figure out how to get all my data off of one drive and onto the other. The only thing I could think about was good old Norton Ghost, which surprisingly is still being made, version 10.0 now, but it's $70! Then there's Partition magic - another Symantec product and another $70! No thanks, when I know that the open source community has to have something better. And, of course, they do.

Free, in every way, the GParted LiveCD is a 40MB ISO Image that you burn to a CD, which then becomes a bootable Linux OS and application all-in-one that manages all your partitions and hard drives. When you boot with the CD in, it starts the GUI and GParted application which allows you to visually manage your drives and partitions. It slices and dices, it visually resizes. I copied and pasted my 2 partitions (I always have 1 for the OS and applications, one for everything else) onto my new drive, and it worked like a charm. It was very stable, very fast, and very easy to use (if you've ever managed partitions before). Plus, it saved me potentially $140.

I'm happy to say that my HDD migration went flawlessly thanks to GParted.

(Discuss with Disqus!)

A calm in the storm...

posted under category: General on April 23, 2007 by Nathan

I had a weekend without phone calls, the first for a little while. I've been very busy, pretty much since November with a little work project. Oy! What a ride, and it's finally close to final production. But it looks like things are finally cooling down, so I'll try to start blogging again :)

Thanks for tuning in, all. I promise to not be too boring.

(Discuss with Disqus!)

CSS Naked

posted under category: Standards on April 5, 2007 by Nathan

Why didn't anyone tell me it was CSS Naked day? Ok, well problem fixed, and for next year as well. I hope you like my web site sans stylesheets and nice designs. The only thing that really stands out on my whole site is the google reader toy I put in my left side area.

(Discuss with Disqus!)

Enabling Unicode for your CF DSN only helps your cfqueryparams

posted under category: ColdFusion on March 28, 2007 by Nathan

Here's a tip - checking the Unicode checkbox in the CF Admin for your datasource only actually works when you have <cfqueryparam> for your variables.

Traditionally, col = '#content#' doesn't work to insert, say, Chinese characters unless you put an 'N' in front of the content: col = N'#content#'.

When you use <cfqueryparam> for your data, you lose the ability to place that 'N' in front, therefore, we have the checkbox, hidden under the advanced settings for your DSN, shown here:



When you check the box, you may expect it to universally work with all your nvarchar and ntext data everywhere, but it only works where you have implemented <cfqueryparam> tags for your content (which probably should be everywhere, anyway).

(Discuss with Disqus!)

Programmatically generated XML makes everything UPPERCASE

posted under category: ColdFusion on March 21, 2007 by Nathan

A little problem I thought I'd share very quickly today. I was modifying an XML file in ColdFusion, adding attributes to some nodes, then later on XMLSearch()ing for nodes with these new attributes. Well, long story short, node.xmlAttributes.code="abc" will output <node CODE="abc"> And, you guessed it, XPath is always case sensitive.

The solution is to either fix your XPath queries (umm, sucks?), or write your xml attributes like so: node.xmlAttributes["code"]="abc"

(Discuss with Disqus!)

Choosing a framework is a big deal

posted under category: ColdFusion on February 26, 2007 by Nathan

There's been a fair amount of talk recently about choosing an application framework for your ColdFusion applications. The general consensus seems to be "Just pick one, already. It doesn't matter!" Well, contrary to popular opinion, picking the best framework is something that needs a lot of thought.

Consider this. The average CF developer came from an HTML background. Maybe, just maybe, a little javascript, but mostly HTML. CFML has a familiar feel and the ease-of-use is just off the scales, especially for making your first apps: feedback forms and basic content management.

This basic CFML developer now knows 2 computing languages.

The choice to learn a framework will push the boundaries of their emerging brain cells. A domain specific language (aka DSL, thx Peter Bell for this great term), such as a Mach-II XML config file, will force a 50% jump in the number of programming languages known. It's much easier than their first and second languages, but still, quite a chore.

Fusebox has 2 DSLs, the fusebox.xml file and circuit.xml files. Model-Glue Unity has 3 because it includes an ORM and an IOC object container.

Further, most frameworks encourage (some strongly) object oriented development practices. This alone can be a nightmare to figure out (much less with practical application) ideas like encapsulation, polymorphism and inheritance.

No. For your basic CFML developer, picking a framework is a big deal. Depending on your framework choice, you could be forced to double your programming language knowledge.

I'm not saying don't do it. Not whatsoever. I'm a huge proponent of frameworks. Everyone should have a few under their toolbelt and know when and how to use them. I'm also a huge proponent of learning as many programming languages as possible, which will be a tremendous help, even just for writing CF. I'm just saying, it's not that easy for first-timers.

(Discuss with Disqus!)

Save your life in subversion

posted under category: General on February 22, 2007 by Nathan

A few years ago, I read a story on Slashdot about a guy who saved his linux home directory in CVS.

Today, John Blayter mentioned someone doing exactly that but only with their Eclipse install.

What an interesting idea, I thought. I could save my plugin configuration and my workspace folder in subversion. I can roll back when things get screwed up, and commit when I make a good change. Ahh, but what about hacking at home versus at work? How about a branch for each? Maybe work will be the main trunk and I would be able to merge changes from home while rebasing changes from work. When I install a plugin, I can make a new branch for it to see if I like it. If I do, I can roll it back into the trunk and rebase with the home branch. If not, I can drop the branch and roll back to the trunk. I can track different eclipse versions and test compatibility with my other plugins. This really could solve a number of problems.

I'm not sure I would do it. I don't currently have a place to hold my entire Eclipse setup, with versions. But the idea is something to think about, for sure.

(Discuss with Disqus!)

Phoenix CFUG, Feb 28 - Desiging the Obvious

posted under category: General on February 21, 2007 by Nathan

Just wanted to echo the word that this month's AZCFUG meeting will be Robert Hoekman, Jr. talking about his excellent book "Designing the Obvious". From what I hear, this is a great book and the subject is something everyone in our field should be aware of.

Also, you can probably guarantee we will be giving away a copy or two, and who knows what other stuff you might score just by showing up. Then there's the social interaction with making contacts in the community, which is good for your career. I'm just saying, there's like a hundred reasons to come to these things, even beyond learning the subject matter.

As usual, the meeting will be held at the UAT in Tempe, AZ at 6:30 PM. Hope to see you there!

(Discuss with Disqus!)

Interactive Sites would like to hire you

posted under category: General on February 16, 2007 by Nathan

Interactive Sites, Scottsdale, AZ.

We're hiring ColdFusion developers. New this round: varying skill levels are OK, and we have training options for promising candidates. Also, PHP/ASP etc. developers will be accepted, providing they have good experience and would like to learn different technologies. To everyone outside of the Phoenix area with stronger ColdFusion skills, consider this position and send in your resume (training may not apply if you're out-of-state). Everything I said last time still applies. Free snacks, great environment and some of the smartest people around.

We've got a lot of other smaller benefits, things that aren't technically benefits, like Alan (my co-worker who manages the CF user group - AZCFUG) shares some Adobe freebies like Flex posters and the like. Also, Alan's server in the office hosts dopefly and other employees' personal sites, so it's free. Sign up, send in your resume!

http://interactivesites.com/hire/cf2/apply.cfm

(Discuss with Disqus!)

Googlebot is not a fully supported GMail browser

posted under category: Browsers on February 15, 2007 by Nathan

Using the excellent Firefox User Agent Switcher extension by Chris Pedrick (of the Web Developer Toolbar fame), to test my plan to keep search engines from indexing some of my development sites.

I forgotten that I had my http_user_agent still set to Googlebot and logged into GMail to check the lists. To my surprise, I was set directly into the non-ajax mode with a little message about how my browser wasn't compatible.

Does that mean Googlebot can't index AJAX sites properly? I noticed the other day that it can read flash movies (well, flashpaper), but I wonder if it can handle remoting calls.

(Discuss with Disqus!)

Photo: Adobe Acrobat Connect works on Nintendo Wii

posted under category: General on January 25, 2007 by Nathan

I connected to the AZCFUG (Arizona ColdFusion User's Group) presentation last night with my Wii's browser, and I felt my geekieness factor hit the roof, so I snapped a handful of pics.


Click for a larger view and a couple thumbnails.

The one shown is a couple together because I couldn't get the lighting right.


(Discuss with Disqus!)

Bragging: English to English Translator

posted under category: ColdFusion on January 17, 2007 by Nathan

I just have to share. It's closed source for a project I probably can't mention, but I needed to blog this. I wrote an English to English translator. That's right. I, Nathan Strutz, being of sound mind, have programmatically translated US English to GB English. I hope I'm the first, at least the first to do it with CF. Thank you. That will be all.

(Discuss with Disqus!)

Need a PS3?

posted under category: General on January 16, 2007 by Nathan

I saw this stack of 60 Gb PS3 systems at BestBuy yesterday on my way to pick up a game for my Wii (WarioWare). Are these things really just not selling?


This was in the BestBuy at Raintree and Northsight in Scottsdale, AZ.

(Discuss with Disqus!)

Brushing off the dust

posted under category: General on January 9, 2007 by Nathan

Ahh what an incredibly busy holiday season. It's just now starting to wind down, and I'm starting to feel more rested, even though I've been staying up late the past few nights.

In November, I went on my first client trip, across the country to NJ, and even hit up the Big Apple for an evening. Came back and stood in line for the Wii with successful results. Then thanksgiving left us with 16 turkey eaters in our home. We spent Christmas, my 28th birthday and New Year's up in Alaska with my (numerically) huge family. Kids played in snow for the first time. All the while, my gigantic project, the reason for going to NJ, was due on Jan 4th. We made that deadline, just barely, but now have a lot left to make it right. And I'm talking huge project. Like, you may hear about it in the general public huge.

Anyways, I'm back in the saddle, for the most part. Work's still busy, but not THAT busy. I think the AZCFUG has some news in the near future about summer events, and I promise to not leave the blog so long next year. I've got a couple more cob webs to clear and some mice to kick out, so I'll see you all around.

(Discuss with Disqus!)
Nathan is a software developer at The Boeing Company in Charleston, SC. He is essentially a big programming nerd. Really, you could say that makes him a nerd among nerds. Aside from making software for the web, he plays with tech toys and likes to think about programming's big picture while speaking at conferences and generally impressing people with massive nerdiness and straight-faced sarcastic humor. Nathan got his programming start writing batch files in DOS. It should go without saying, but these thought and opinions have nothing to do with Boeing in any way.
This blog is also available as an RSS 2.0 feed. Click your heels together and click here to contact Nathan.