How many jobs are available for Enter programming language here?

Monday, July 27, 2009

This was the simple question I wanted to answer. The impetus behind this is to know where best to focus my learning energy. As a programmer, technologist, etc., and, as the plethora of languages that all appear to have similar goals and do the same things pervades the landscape, I feel I need to periodically look up from the microscope and peep the rest of the world from 30,000 feet, especially today. Historically, maybe I could enter a field, a craft, and be happy there until I am old and gray, updating my skills every so often. But, the reality is that as programmers all this is changing very fast, and it takes agility and the ability to learn quickly to keep up with it. I would even go so far as to say it also takes a strong desire to adapt. Bottom line, though I have personal tastes and a few distastes for programming languages, I need to put food on the table. I'm sorry, but the "I love the simple elegance of brainf*ck" doesn't ensure that my family's medical bills are paid. For me, it's much easier to adapt my own skills to a rapidly changing market than to attempt to change the market to my personal preferences. So, this is what I did. I simply entered various arbitrary programming languages into the main search at Dice and Monster. I specified no other search criteria, so, the term exists either in the title or other meta data about the job. I'm sure this creates some noise, but if we can suspend and accept the concept of random sampling, this provides some interesting results. Note that the results here are from Dice, but Monster's results were similar.
Keyword Hits
Java 8817
.NET 5205
C# 4265
HTML 4138
C++ 4121
JavaScript 3889
Perl 3066
VB 1877
Python 1118
SAS 1099
Flex 853
Ruby 607
Cobol 477
ColdFusion 346
Fortran 84
Groovy 69
Haskel 15
Obviously, I am not a statistician and I certainly do not have the resources to pay for a Gartner consultation - I barely have the time to update my resume. However, based on my naive searches and lack of any domain context, is it fair to conclude that if I know Java reasonably well, I am more employable? Of course, this is the demand side of the equation. What about the supply? Addendum (August 4, 2009): My friend Raj sent me this insightful excerpt from Chad Fowler's The Passionate Programmer: Creating a Remarkable Career in Software Development: http://media.pragprog.com/titles/cfcar2/intelligence.pdf

Timesavers: Launchy for Delicious Bookmarks

Saturday, July 18, 2009

This is part of an ongoing series on Timesavers. The goal is simple: short, easily-digestible posts designed to help developers get faster and more productive


I Love Launchy. It’s not as powerful as other keyboard launchers like FARR, but it suits me just fine. I’ve been using Delicious for bookmark management for a long time now, and today, as I was looking for some articles I had bookmarked at work the other day, my “meta” self was thinking “Hey, slow-ass, why are you Clicking the bookmark icon, searching for a filter, and then clicking on the link? That’s, like, too much mousing”.


For me, automation has become a habit. It’s like I’ve spawned a thread that sits behind me, watching to see when I’m doing stuff slowly, and it pokes me when it observes un-optimized behavior. It’s a cruel master. I wouldn’t have it any other way.


Consequently, I decided it was worth investigating whether Launchy could easily fire up delicious bookmarks. After a bit of Googlin’, I found it in a comment.


Here’s how to configure it:


Options, Plugin tab, Weby, add +

Name: delicious

URL: http://delilcious.com/

Query: search?p=%s&u=yourUsername


To launch:

  1. alt-space to pop up launchy
  2. type “delicious”. You can probably get away with just typing “de” or “del”
  3. hit the TAB key
  4. type your query
  5. Hit enter

 

Here’s what it looks like when you follow steps 1-4:

deliciouslaunchy

Word Wrap in ColdFusion Builder

Tuesday, July 14, 2009

You may have noticed that ColdFusion Builder does not have Word Wrap – like FlashBuilder and Zend Studio and Aptana and all the other Eclipse derivatives out there. The reason is that it’s not in Eclipse itself. I know, I know… notepad has it, why doesn’t Eclipse? If you’re interested in the gory details, you can read the bug and its comments: https://bugs.eclipse.org/bugs/show_bug.cgi?id=35779

One of the reasons for not supporting word wrap natively is that line numbering is a tricky thing to contend with, particularly with respect to breakpoints and debugging. If you don’t really care about that stuff but just want a word wrap that’s “good enough”, you’re in luck.

A Word Wrap Plugin

Ahti Kitsik wrote a word wrap plugin a long time ago: http://ahtik.com/blog/eclipse-word-wrap/. This is the update site: http://ahtik.com/eclipse-update/

Once installed, you enable virtual word wrapping by right clicking in the editor and selecting “Virtual Word Wrap” in the context menu. You turn it off in the same manner.

It works “good enough”. The major downside is in how it deals with line numbers. Let’s look at a picture of some code without line wrapping turned on:

nowordwrap

Notice each line gets a single line number.

Now, let’s look at it with Virtual Word Wrap turned on:

wordwrap

See the problem? Up there in the top, each “virtual line” gets its own line number. This is clearly incorrect and it’ll cause problems if you’re trying to do step-through debugging.

Lighten up

That last problem, though, is more of an inconvenience than a problem. If you need to do step-through debugging and the line numbering thing is tripping you up, just right click and turn it off for a bit. Or hit the “enter” key in your text and get rid of your long lines (they’re annoying, anyway. Trust me).

Should Eclipse have word wrap? Absolutely. Will it any time soon? Don’t hold your breath.

Update

Terry Ryan has posted the "correct" way to enable word wrapping here: http://www.terrenceryan.com/blog/index.cfm/2009/7/14/Word-Wrap-in-ColdFusion-Builder. I, for one, am not a fan of this method of line wrapping at all. I want to be able to easily toggle it on and off. My 2 cents.

ColdFusion Builder: Maximizing Screen Real Estate


I'm not a toolbar guy, and I'm not a fan of wasted space in an IDE. Here's what I do in ColdFusion Builder to maximize screen real estate.

The Problem

First, I don’t like how the “Perspective” icons by default are hanging out on the left hand side, in their own “row” in the toolbar. Big waste.

Second, I don’t use the “editor toolbars”. Virtually all of their functionality can be accessed via the keyboard, which is a far more productive way to work.

Here’s a screenshot to show you what I’m talking about:

wastedspace

The Solution

I want to get a leaner UI. To do so:

For the “Perspective” icons, simply right click beside them and select “Dock On – Top right”.

To get rid of the “editor toolbars”:

  1. Window – Preferences
  2. ColdFusion – Editor Profiles – Editor
  3. Uncheck the “Display CFML Toolbar”

That preference page looks like this:

editorprefs

This gets you a screen that looks like this:

notwastedspace

I figure this gives me back close to an inch of vertical space.

The Sledgehammer

Often, for me, that’s not enough. I want lots and lots of space. It’s not that I have overly long functions or anything… I just like my IDE to feel “roomy”. What I often want is a Full Screen Mode. For those of you familiar with CFStudio or HomeSite, you may think fondly of Full Screen Mode.

Fortunately, there’s a plugin for this, and here’s how to install it:

  1. Go here: http://code.google.com/p/eclipse-fullscreen/
  2. There doesn’t appear to be an update site, so click on the Downloads link and download the zip file
  3. PAY ATTENTION: Since Eclipse 3.4 (on which CFB is built), the preferred method for installing “dropin” plugins is to put them in the “dropins” folder. So, Drill into the zip, and drag the jar file into [bolt install root]/dropins/. 
  4. Restart Eclipse

Once restarted, the “Window” menu will now have a “Full Screen” option, which you can toggle with ctrl-alt-z.

Here’s what it looks like:

fullscreen

Important: I didn’t crop that picture. That’s what your desktop will look like in full screen mode. Yes… it covers up all your other toolbars, too. For me, this is a blessing: those a’cursed IM windows go away and I can work in peace. And remember… ctrl-alt-z gets you out of full screen mode.

Happy Coding!

Speeding up ColdFusion Builder

Monday, July 13, 2009

A while back, I wrote a post on Speeding up Eclipse. All of that applies to ColdFusion Builder as well. One thing I wanted to point out though, which isn't mentioned in the body of that post, is how you can control the Java virtual machine settings for your ColdFusion Builder install. I noticed today when I fired up the CFB public beta that I was getting "java.lang.OutOfMemoryError: PermGen space". I do not think this is a CFB problem per se, but instead attributable to another plugin. This isn't unheard of and is simply what happens when you add more and more plugins to Eclipse. This is NOT heap space.... PermGen is the space reserved for class files. So... more plugins, more classes the classloader has to load. The good folks at Eclipse realized this problem a long time ago, and you can see this evidenced in the default settings in [eclipse_install_root]/eclipse.ini (at least for the latest Eclipse release). They've set the default permgen size to 256M. However, it appears that ColdFusion Builder does not have this setting. To remedy that, simply: Go to your [cfb_install_root]\CFBuilder.ini and open it in Notepad (or any text editor) At the bottom, add this line: -XX:MaxPermSize=256m If you want to tweak the VM even more, you can add all kinds of mysterious options. For example, Here's how I start ColdFusion Builder in a .bat file: CFBuilder.bat: "C:\Program Files\Adobe\Adobe ColdFusion Builder\CFBuilder.exe" -showlocation -vm "C:\Program Files\Java\jdk1.6.0_14\bin\javaw.exe" -vmargs -Xmx512M -XX:MaxPermSize=256m -XX:+AggressiveOpts -XX:+UseParallelOldGC -XX:ParallelGCThreads=2 -XX:ThreadPriorityPolicy=1 -Xverify:none Many of those later settings come from an article by Mike Henke in FAQU some months back. Enjoy!

Installing Mylyn into ColdFusion Builder


To Install Mylyn Into ColdFusion Builder, which is as of this writing built on top of Eclipse 3.4, do the following: Help -- Software Updates Click "Available Software" tab Click "Add Site" and use "http://download.eclipse.org/tools/mylyn/update/e3.4" for the main Mylyn install Click "Add Site" and use "http://download.eclipse.org/tools/mylyn/update/extras/" to get the other connectors (Like the Jira and Trac connectors) Click "Install" and do the normal install process. If you've already installed Subclipse but hadn't yet installed Mylyn, you can also now select the Subclipse Mylyn Integration and it'll install, too. Don't forget: you can type "Mylyn" into the "type filter text" box to make all of this easier to "see".

A Generic ColdFusion Struct Visitor

Friday, July 10, 2009

Warning: No unit tests accompany this code.

Recently, I mentioned on Twitter that I wish CF had a regex version of StructFindValue, and this started a conversation between me, Ben Nadel, and Nathan Mische. Ben and Nathan, both of whom I swear are code factories, had code out there within hours to do what I was looking for. Bless their hearts. While I normally try to hold to the “Twitter is not a Chat” maxim, in this case, I ran with it and it yielded fruit.

During our conversation, what I came to realize was that I didn’t want just a reStructFindValue, what I wanted was a generic means of looping over structures and then “doing stuff” with each key that it encountered, as it walked recursively through a structure, no matter how deep/nested.

Some of you may recognize this as the Visitor pattern. I tweeted thusly:

@bennadel what ColdFusion really needs is a StructVisitor. With that, a man could do great things.

2:12 PM Jul 7th from TweetDeck in reply to bennadel

Inspired by our conversation, and by the quick contributions of these two fine gents, I decided to take a quick stab at a basic implementation of some code, which I’ll call “StructEach.cfc” (Nathan called his version StructEach, and I liked it). It should behave like so:

  • Take a Struct and a Visitor object as arguments to an “each()” function
  • Loop over all keys in the input Struct, recursing as it went
  • For all keys in the struct, pass the key and struct value into the “visit()” function of the Visitor object
  • The visit function of the Visitor must return a boolean indicating whether the code should continue looping over the struct
  • The visit function of the Visitor can do whatever the hell it wants to do.

Before showing the code for StructEach.cfc, let’s look at why you’d want to use something like this, and then how you would use it.

Why? What are the use cases for this?

  • Perhaps you’d like to take a structure and convert it to XML
  • Perhaps you’d like to do really weird or granular searching of the stuff inside the structure, even if the structure has arrays in it, queries, etc.
  • Perhaps you’d like to “dump” the values of a struct, but you want them in textareas b/c you need to see exactly what the strings look like, whitespace and all
  • Perhaps you’d like to do a deep comparison of two structures and report the differences in a way that’s easy to read

That last one, by the way, is my own personal use case for MXUnit.

What Kind of Structures should it take?

For me, I wanted this thing to be able to handle nastiness, not just simple structures. At the very least, it should take a struct that was this ugly:

startstruct

How do you use it?

First off, you’d write a CFC that implemented the “visit” function. Here’s a really simple visitor that just outputs anything passed into it, along with the full path to the value’s key in the structure

OutputVisitor.cfc

<cfcomponent hint="" output="false">
	<cffunction name="visit" output="true" access="public" returntype="boolean" hint="">
		<cfargument name="key" type="string" required="true"/>
		<cfargument name="value" type="any" required="true"/>
		
		<cfif isSimpleValue(value)>
			<cfoutput>#key# = #value# <br></cfoutput>
		<cfelse>
			<cfdump var="#value#" label="#key#" expand="true">
		</cfif>
		
		<cfreturn true>
	</cffunction>
</cfcomponent>

You’d then use this visitor like so:

<cfset outputVisitor = createObject("component","OutputVisitor")>
<cfset runner = createObject("component","StructEach")>
<cfset runner.each(struct,outputVisitor)>

In the case of the sample struct shown above, you’d get this output:

outputvisitor

Where it gets interesting

That’s not very useful, is it? But it demonstrates how you’d use it. What you can trust in your visitor is that for every key in the structure, your visit function will get called. That’s the sweetness of this approach… you’re free to do whatever you wish with the data coming in.

This gets interesting when you start to consider how this is all implemented: you’re passing an object into the StructEach… think about that. Objects can contain state. This means that you can “remember” things through the iterations of the struct, as your visit function is repeatedly hit.

Let’s look at an example that implements “regex find” functionality over a structure. My implementation will

  • provide an init() function for taking in searchString and scope arguments
  • return a struct containing keys “found”, “path”, and “value” as soon as it finds something that matches the regular expression, and it will return false so that the StructEach will stop searching. Consider this a findOneOf() >
  • return an array containing multiple structs if scope is set to “all”. Consider this a findAll() >

You’d call it like this:

<!--- a RegExFindVisitor that searches for 'even'; as soon as one is found, it'll stop searching --->
<cfset regexFindVisitor = createObject("component","RegExFindVisitor").init("even","one")>
<!--- a RegExFindVisitor that searches for 'even' or 'ix'; it will search every key in the struct --->
<cfset regexFindAllVisitor = createObject("component","RegExFindVisitor").init("even|ix","all")>

<cfset runner.each(struct,regexFindVisitor)>
<cfset runner.each(struct,regexFindAllVisitor)>

<cfdump var="#regexFindVisitor.getFound()#" label="regexFindVisitor">
<cfdump var="#regexFindAllVisitor.getFound()#" label="regexFindAllVisitor">

And here’s what you’d see:

regexfindvisitors

This is all made possible because the Visitor object can provide any other functions that it wants to… as long as it has a “visit()”, nothing else matters. In addition, the object can retain state. Thus, as visit is called, it can store stuff inside of itself for later computation and retrieval.

RegExFindVisitor.cfc

<cfcomponent hint="" output="false">	
	
	<cffunction name="init" output="false" access="public" returntype="any" hint="">
		<cfargument name="searchString" type="string" required="true"/>
		<cfargument name="scope" type="string" required="false" default="one" hint="'one' or 'all'. If scope is 'all', returns an array; otherwise, returns a struct"/>
		<cfset StructAppend(variables,arguments)>
		<cfset variables.instance.found = []>
		<cfreturn this>
	</cffunction>
	
	<cffunction name="visit" output="true" access="public" returntype="boolean" hint="">
		<cfargument name="key" type="string" required="true"/>
		<cfargument name="value" type="any" required="true"/>
		<cfset var tmp = "">
		
		<cfif isSimpleValue(value) && reFind(variables.searchString,value)>
			<cfset tmp = {path=key,value=value,found="true"}>
			<cfset ArrayAppend(variables.instance.found , tmp)>
			<cfif variables.scope eq "one">
				<cfset variables.instance.found = variables.instance.found[1]>
				<cfreturn false>			
			</cfif>
		</cfif>
		
		<cfreturn true>
	</cffunction>
	
	<cffunction name="getFound" returntype="any">
		<cfreturn variables.instance.found>
	</cffunction>
</cfcomponent>

Note that our source structure contains keys that have arrays and queries in them, but we’re only concerned with the keys that have simple values (and any nested structs that have simple values). Consequently, I’ve wrapped the chunk of code that does the work in an “isSimpleValue()” check.

But imagine… what if you wanted to also search through the arrays or queries that are passed into this thing? You could do that by implementing some additional searches inside of here.

Here’s another one I whipped up: Imagine you had a big ugly struct with various and sundry data in it, and you wanted to get just the queries.

Here's how you'd call it:

<cfset queryHarvester = createObject("component","QueryHarvester")>
<cfset runner.each(struct,queryHarvester)>
<cfdump var="#queryHarvester.getQueries()#">

And here's its implementation:

QueryHarvester.cfc

<cfcomponent hint="" output="false">
	<cfset queries = {}>
	<cffunction name="visit" output="true" access="public" returntype="boolean" hint="">
		<cfargument name="key" type="string" required="true"/>
		<cfargument name="value" type="any" required="true"/>
		
		<cfif isQuery(value)>
			<cfset queries[key] = value>			
		</cfif>
		
		<cfreturn true>
	</cffunction>
	
	<cffunction name="getQueries" returntype="struct">
		<cfreturn queries>
	</cffunction>
	
</cfcomponent>

And here’s what you’d get

queryharvestingvisitor

How does it work?

This is not sexy code, and it’s certainly not a) optimized or b) complete (for example, I’d like it to loop through arrays of structs as well). But it’s a start, and it’s very simple:

StructEach.cfc

<cfcomponent>
	<cffunction name="each" output="true" access="public" returntype="any" hint="">
		<cfargument name="struct" type="struct" required="true"/>
		<cfargument name="visitor" type="any" required="true"/>
		<cfargument name="path" type="string" required="false" default="" hint="don't touch this, suckers">
		<cfscript>
		var loopkey = "";
		var thisPath = arguments.path;
			
		for(loopkey in struct){
			thisPath &= "[ ""#loopkey#"" ]";
			if(isStruct(struct[loopkey])){
				each(struct[loopkey],visitor,thisPath);
			}else if(!visitor.visit(thisPath,struct[loopkey])){
				return;
			}			
			thisPath = arguments.path;
		}
		</cfscript>
	</cffunction>
</cfcomponent>

Final Thoughts

This code, and even this approach, is purposely simple. There is nothing clever about it. I believe the value in an approach like this is in thinking about tasks in a more generic sense. Think of all the code out there in the world that does this: loops over keys in a structure recursively, and does stuff with the values it encounters. I imagine if you compared all of this code, it’d look remarkably similar in its recursion, but the details in the “else if” clause would be different.

Thus, in this approach, we’re extracting the common stuff into StructEach and providing hooks for implementations to get plugged into that “else if” part, in the form of a Visitor. Code gets much simpler and easier to understand; and code gets much easier to unit test because you’d be testing just your “visit” function, not the looping/recursion.

The downside is where you have recursion conditions that themselves require state external to the visitor; in this case, the StructEach approach wouldn’t work well, and there’s danger in trying to shoehorn an approach just to avoid a few lines of code. So, as with most things OO, you use this approach when it’s warranted, not just when it’s easy.

When you start thinking in more generic terms, you start to see opportunities for code reuse. For example, how much code is out there in the world, do you think, that loops over directories and "does stuff" to the directories and files in those directories? Imagine the dozen or so lines of boilerplate recursion code required to do the looping part, and the one line of code to delete the file. Multiply that by a gazillion. How much code in your own codebase does this looping, with the only difference being "what I do when I hit each file"?

If you think generically, you see there's a better way to do this: you create a DirectoryWalker type of deal that handles the looping, and then you provide a FileVisitor type of implementation that acts on each file it hits. So if you have code that deletes certain files in directories, or "touches" them to make them current, or archives certain files, or makes jpg thumbnails of pdfs that don’t already have thumbnails... you can separate that out into really small, easy-to-test Visitor implementations and just use DirectoryWalker to handle the boilerplate.

Consider the unit test for that last example, the one that generates thumbs. If you were to write a “generateThumbsForDirectory"()” function, that’s hard to test! Seriously… think about what would be required in a unit test to test it. You’re testing two things: 1) your recursion and 2) your thumbnail generation. But the recursion is boilerplate, and testing boilerplate sucks. What you really want to test is your thumb generation. So if you extract that out into a simple function that takes an existing File path, your job is simple: look for an existing thumb for that file, and if one doesn’t exist, create it. That’s a really small unit test comprising two functions: makeThumbnail_should_GenerateThumbnails_When_ThumbnailDoesNotExist() and makethumbnail_shouldNot_GenerateThumbnails_When_ThumbnailDoesExist(). You could write that in maybe 15 lines of code. You trust that the StructEach works because it’s been tested separately, and you can now trust your code because you’ve proven, with your tests, that your code works.

Fewer lines of code + easier-to-test functions = fewer bugs.