I am cross posting this for Aaron. Scriptalizer is a GREAT project that needs a home. If you have a server, VPS, etc running a CFML engine (Railo, OpenBlueDragon, or ColdFusion), and wouldn’t mind adding another site to your server, I am sure Aaron would be grateful.
For details contact Aaron in the comments of this post.
As of this first week of 2011, we will be permanently turning off the lights at InstantSpot. I felt that it was fitting to give it at least some type of obituary, and share my reflections of what has been a 4-and-a-half year story of the process. We have learned much through the process, and hopefully we can share some of what we learned with others.
Starting in 2006, Aaron Lynch and I started on modest plan to revolutionize the blogging world. OK, so that isn’t really true – it happened like this…
In the beginning… a simple CMS
In 2005, Aaron was making a career change and after years of being friends through the Jeep and 4×4 community we found ourselves in the same line of work as ColdFusion developers. Around the beginning of 2006, he joined my company which gave us way too much time to discuss and conspire on how we might take over the world. We decided to begin by making a simple no-database CMS in ColdFusion that we could distribute and sell for a nominal fee. Of the ones that we deployed, we found that no one was really interested in hosting it themselves and we ended up putting a few instances on our server.
A network was born
Once a small handful of them were running, we created a single directory page that listed and linked to all of the individual sites. Even though it was exceptionally simple and rudimentary, we realized that in essence we had a “network”. Given the fact that no one really had an interest in hosting themselves, we quickly realized the fallacy of duplicating the code base for each new site and set out to more effectively externalize the settings and make the configuration centrally persisted in a shared database and run all of the sites from a single set of code. We quickly developed methods of skinning individual sites, and using subdomain URLs. The methods we came up with are almost exactly the same methods that we would end up using the next 4 years moving forward.
The addition of blogs
Almost immediately we decided that we needed to add blogs to the sites. In a move that would haunt us to some degree for a long time to come, we chose to implement the open source BlogCFC application created and maintained by Raymond Camden. While there was nothing inherently wrong with BlogCFC itself, it was just a poor choice on our part for several reasons:
- We already had a functioning CMS build using the Mach-II framework using its own database. Adding in multi-site support to the blogs (which I don’t think it had at the time, if I recall correctly) and tying that into our existing application proved to be a ton of work and felt like such a goofy solution.
- Combining the two databases into a single one, and the vastly different approaches of data persistence (naming schemes, UUID vs integer keys, etc…) made our code base look schizophrenic.
- We actually had two complete applications and had to manage session replication between them.
- We ended up using a really a small portion of the actual BlogCFC code base. If we would have just created the functionality on our own from scratch, we would have spent far less time and ended up with something that seemed like far less of a hodgepodge.
Eventually we got it working, and did so somewhat successfully, but it really felt like a hodgepodge of methodologies. However, we started growing our user base, got some great community feedback and support, and had a relatively well performing blogging network.
The dirty secret
One of the seriously embarrassing dirty secrets that we had was the original hardware/server architecture of InstantSpot. When Aaron and I both started out writing the code, we were not the Linux nerds that we grew into being later. We were both Windows developers and had never paid as close of attention to casing issues as we grew to later. Unfortunately the first time that we tried to run Spot under Linux, it blew up severely. We started trying to work through issue by issue, but decided we would do a temporary fix by throwing it into a Windows VM on our co-located Linux server. However, this temporary work-around ended up sticking around much longer than we anticipated. So, for the first year or so, InstantSpot chugged along on a single PC that was little more than a common desktop, running Ubuntu Server, with a Windows VM in VirtualBox! The fact that it supported as much traffic as it did was always just a little bit comical to us.
The inevitable rewrite
As we continued working to bring in a continual array of new enhancements – many of which were implemented but never even seen by our users! – we found more and more that our architecture sucked badly enough that we would actually have to do something about it. In addition goofy hardware/OS issue, the maintenance of dealing with the two separate applications became this growing elephant in the room. As our user base and our exposure continued to grow, we decided it would be worth a complete re-write from the ground up. When we first started slapping stuff together in the befinning, we didn’t have a defined target in mind, so surely a rewrite would be less time consuming since we actually had a goal now right?! We set out about mid-2007 to find out. Around that time, Railo had hit RC 2.0 and Aaron and I were both enamored by the idea of a completely open source version of InstantSpot. We busted our asses the last quarter of the year and were finally ready to roll right at the turn of the year in 2008. I will never forget how many people scoffed at us using Railo. I mean seriously, given the enormous growth of it in 2010, you wouldn’t believe all the snickering we put up with about it early on. However, we found huge performance increases over ColdFusion and felt like we were really breaking new ground.
Disaster strikes
In January 2008, we rolled out the newly rewritten InstantSpot with HUGE expectations. As soon as we flipped the switch at 1:00am CST on January 13, we immediately started seeing very strange errors. Some of these errors were coming in the fashion of ColdSpring returning improper service object bean types, Mach-II throwing errors that made absolutely NO sense at all, and errors in code that was too simple to fail! Often when someone would visit a blog, someone else’s content would show up. (not cool!) It began looking like we had some serious threading issues. Immediately we discovered one issue in which the getBean() method of ColdSpring (1.x?) was not thread safe! (Here is an email thread discussing it). We also realized that we were using getBean() in a few inappropriate places, and moved code around so that the only place this was being used was in the bootstrapping process and we made those processes threadsafe on our own. Even then, however, we continued to see things spiraling out of control in what became increasingly clear as a concurrency issue within Railo itself. Gert Franz actually contacted us as soon as we brought the issue to light and wanted to help us resolve it by us sending him our application. Given the complexity of the application, however, we felt that we didn’t have the option to spend time going down that road without knowing that we would see a solution come out of it quickly. We made a snap decision to purchase a license of ColdFusion 8, and cut over as soon as we could. Two nights later we made the cut-over to CF8 and all of our threading issues completely disappeared. (blog entry from January 2008 discussing this in detail)
Immediately we breathed easier knowing that our months worth of work was actually paying off, but unfortunately this gave some “I told you so” ammo to all the previously mentioned skeptics of our use of Railo, and we were eating crow. As it turned out, Railo put out a patch within the week that would have completely fixed the problem we had, and in hindsight, I really wish that we had the foresight to hold out and continue down that path.
Easy days
So there we were… we had our new codebase running… and running… and running… with almost zero time spent on maintenance issues. Before too long we had amassed somewhere around 1000 blogs, with less than 5% of them being relatively active. We couldn’t have been more pleased with the results of the rewrite as it made our lives so easy. This period, for better or worse, allowed Aaron and I to put a huge focus on client work in our moonlighting hours. While this was a temporarily lucrative venture, the focus was definitely off of InstantSpot since it really didn’t demand any of our attention on a daily basis. One result of this that we essentially quit marketing the network. Aaron and I are both really cheap dudes… I mean really… ask our wives. Subsequently we never spent money to push InstantSpot beyond word of mouth. We had this idea that if we made it an obvious tool, that an organic growth was inevitable. While this was true to some extent, the flaw of this was the real industry giants that we were up against. I mean, what had we made really? A blogging network that from a feature perspective was a competitor against services like Google, WordPress, etc. These giants that obviously had no idea that we even existed and were only competitors in our wildest imaginations and only on paper from a feature-by-feature perspective, rather than a true competition of any kind. We had an obvious niche in the CFML development community, but the fact is that many developers want a more hands-on solution than what an out-of-the box solution such as a blogging network would provide.
What about revenue?
So we have never really talked publicly about InstantSpot revenue. We spent a lot of time trying to figure out how to make money of it, but never really got it worked out right. I mean, it paid for itself (until recently), but it never really made any money at all. In periods of our largest traffic, we were still only making about $20.00/day. So, with our colo fees of about 160/month, we were netting somewhere around 440.00/month. For those that wondered why we didn’t bust our asses a little more, perhaps you understand our lack of motivation for doing so now! It was kind of frustrating to have worked so hard, and to put so much time and effort in, for such a small monetary reward. The thing that was really frustrating was that about 75% or more of that revenue was being generated from one very spammy blog that was set up with keywords all driving around prepaid wireless. It felt kind of dirty, but it was the one consistent blog that kept us in the black. Although technical blogs like mine, Aaron’s Sam Farmer’s, and others certainly brought more traffic, the click-through and click-rates on that stuff was dismal.
The decline
Over 2010, we have really seen a solid decline of anything positive from InstantSpot. What was initially one of the HUGE benefits that we created with InstantSpot ultimately turned into a negative against us. Our users enjoyed really ridiculous search engine exposure. A brand new blog could be created and with a relatively well crafted title and content could easily hit page 1 of Google on a wide array of subjects. This was due in large part to the fact that we started off with a few blogs that already had PR5 ranks, and then we used what we felt was a really smart way of linking pieces together so that new blogs made more relevant by being tied do solidly ranked blogs as they came in. If you think I am overstating this, here are a couple of examples I can think of…
- When Saddam Hussein was executed, we had a blogger that put up a youtube video of it ( yeah, the appropriateness of that was definitely discussed, but we really never established a TOC that restricted specific content ). This blog entry made page one of Google, and was picked up by El Tiempo, which is a huge latin news source, and linked as the first blog to carry the info. We hit somewhere around 100K impressions by mid morning and our sever absolutely croaked.
- We had a blogger that posted about State Farm Life Insurance and for a period, that blog link was higher in Google search results than statefarm.com with the search “state farm life insurance”. That one was mind blowing to me!
There were a lot more anecdotal examples like this and we were continually shocked by what we were seeing in the way of search relevance. Unfortunately we were not the only ones that noticed it. We ended up with a couple of worthless spam sites that capitalized on this. They would create a blog and then generate scores of blog entries every day with complete bullshit content stuffed with keywords and links to various products. Over time, our valid content was overshadowed by our spam content as more and more (and more… and more… and MORE) spam sites were created. Along with them came thousands upon thousands of spam comments. We were pretty effective at blocking the bots, but there were a surprising number of manually typed spam comments, which were much more difficult to stop. Eventually when you looked at our recent entries across the network, it was just shameful. The more spam issues that came up, the more performance issues we had as well. Unfortunately both Aaron and I were so tied up with our families and our jobs that neither one of us could deal with effectively and things just spiraled negatively.
Realization
At some point it really became quite clear that we were either going to have to invest much more effort and certainly much more money to make a real run at it, or we could just continue sailing along as long as it would go and see what happened. It became clear to us that the kind of traffic that we would need to actually make InstantSpot something that could support us was so far beyond reality that we didn’t even know what to do about it. Considering that both Aaron and I have full time jobs and each supports a family of 5, quitting our jobs, taking loans and going full bore never seemed like the right decision. “And who knows… maybe someday it will just take off!“. Obviously, we never made that jump or commitment and both feel that we have hit “… as long as it would go”. With the drop in revenue we have seen, we are actually spending money on InstantSpot to keep it up now. We have experienced more and more performance issues that we don’t have the available time – and to be honest, the will – to keep things on track and at a level they should be. After some discussions, we have decided that it’s time to pull the plug.
But, it’s not all bad
It really has been a great experience, and we have learned so much about so many things. It has given us not only a great tool that has boosted our education and skill set, but gave us a great reason to be passionate about what we do and strive to do it well. Hopefully we can find another project on the near horizon that gives us the same opportunity.
Thanks!
In closing, I would like to say thanks… Thanks first and foremost to my family that were supportive day in and day out, and believed in what we were trying to do simply because we believed in it. Thanks to all of the early adopters and people who stuck with us even when things were less than ideal with our system. Thanks to many in the ColdFusion community that gave us really great support. This has been a really great run, and I am happy to have been a part of it.
This is my first post after moving my blog over to WordPress. Considering that the new feed isn’t in the Adobe Feeds, ColdFusion Bloggers, FullAsAGoog, etc., this will effectively be a tree falling in the forest with no one around. Quite honestly, I am not even sure that I will request the update to the aggs. When I am not listed in tech feeds, I can have stupid meaningless posts like this.
I am running a BER version of Railo to experiment with the Hibernate ORM functionality for a new project. I set up a Mach-II app from the 1.8 skeleton using Mach-II 1.8.1 on Railo under Tomcat6 on Ubuntu… whew! That’s a mouthful huh?
The simple skeleton came up just fine, but after a little bit of customization, I ran across a strange issue. I had created an event, in which a listener pulled a new entity from a ColdSpring bean, and persisted it using EntitySave(). Somewhere in that process, I started getting exceptions related to sun.awt.X11.XToolkit.
The first time the error would occur, I would see this:
Can’t connect to X11 window server using ‘:0.0′ as the value of the DISPLAY variable.
/var/lib/tomcat6/webapps/railo-orm/MachII/properties/HtmlHelperProperty.cfc: line 142
140: <!--- Configure auto-dimensions for addImage() --->
141: <cfif StructKeyExists(serverInfo, "productLevel") AND serverInfo.productLevel NEQ "Google App Engine">
142: <cfset variables.AWT_TOOLKIT = CreateObject("java", "java.awt.Toolkit").getDefaultToolkit() />
143: <cfelse>
144: <!--- Some hosts (such as GAE) do not support java.awt.* package so replace with mock function --->
On subsequent requests, I would get the following:
Could not initialize class sun.awt.X11.XToolkit again with the specitic exception pointed to HtmlHelperProperty.cfc: line 142.
After some Googling I came across a similar sounding issue in which a guy had added params to his app server. I added it to mine, and the error went away. If you come across this yourself, try adding: -Djava.awt.headless=true to the JAVA_OPTS (in catalina.sh for Tomcat).
About 9 years ago I bought a Confer roof rack for a CJ7 I had at the time. I ended up modifying the rear and replaced the stock tail lights with slim LEDs and there wasn’t enough sheet metal left in the rear to use the Confer brackets.
Along with a few other projects that never came to be, I just stuck the kit along the side wall in my garage and figured I would put it up on craigslist eventually. This past year I picked up a CJ5 which I am driving a lot more than I ever guessed that I would. I want to be able to throw my backpack, tent, and canoe up on top and go with ease, so I decided I would mod the CJ7 rack to fit on the CJ5 and install it. To be perfectly honest, I am a little on the fence about how I feel about roof racks on open-top Jeeps, but functionality wins over form with me for the most part.
The first immediate problem was that the rear brackets are designed to mount flush up against the tub sandwiched by the tail lights. On my CJ5, there is no tailgate, and instead there is a support that is raised out from the tub about an 1″ that was creating interference. If I were to cut that support to make it fit, I still had an issue that it would block the bottom of the soft top slot and I would have a hell of a time getting the rear of the top fastened like that. I opted to space the tail lights back 1″ using some square tube like this:
(All pics click to larger resolutions)
The next problem was the somewhat obvious one in that the lengths of the CJ7 and CJ5 are about 10-ish inches different. The lateral tubes are round, but flattened on each end where the bolts go through. I initially thought about taking out a section in the middle, leaving both ends intact, but I decided I would just try cutting off an end, and crushing the open end flat using my vice. Here is the first piece that I cut off.
After flattening the open end on the longer piece using the vice, drilling the, hole and doing a test fit, I confirmed that my mod was going to work perfectly. Here is a shot of a couple of the flattened ends.
Overall, the finished product came out pretty well, although I am still not sure how I feel about racks on CJs in general! Here are some pics:
I was just delivered a new laptop from my company. It is a smoking smoking Dell E6500 duo core processor with a sweet solid stated drive and…. Windows XP (booo!).
While it is a very stable system, I can’t help but have flashbacks to the early 2000′s when I look at the XP windows manager. It just looks so dated by today’s standards. After about 20 minutes I just couldn’t take it any more and had to modify the look. I came across a great looking Mac theme for XP and I have to say that overall I am pretty pleased with the look and feel now. Here is a screenshot of what it looks like now:
If you want your Windows XP machine to look like that, then do the following. First you will need to run a patch utility that allows you to install non-Microsoft approved themes such as this. Given the restrictive nature of Microsoft software, this is surprisingly easy to do. Download the UXtheme Multi-patcher for free from softpedia.com. Inside the zip file you will find a single executable file. Run it and follow the instructions.
When that step is complete, you have now freed yourself to be able to install any theme you like. You can find lots of themes at places like deviantArt and WinCustomize.com. The former is where I found the Mac Panther theme that we will be using. Download that theme and unzip the contained “Panther” folder to C:\WINDOWS\Resources\Themes. Once you do this, go into that folder and double-click the file Panther.msstyles. With this step, you have now installed the theme. To finish the look though, I took a few other steps.
First, I moved my start bar to the top of the screen. If you can’t drag yours, you may need to right-click on the task bar and un-check “Lock the Taskbar”. After I moved it, I found that it left an undesirable border line on the bottom of the bar that I corrected by rechecking “Lock the Taskbar”.
So what about that background? I found a pretty nice looking version of that Mac inspired wallpaper here.
And lastly, it is time to create that launcher that you see at the bottom of the screen. RocketDock is an really clean (and free!) application launcher for windows. Download RocketDock from here and install. Customize the options as you see fit and you are done!
So here is the bottom line… Is this whole idea a little bit goofy? Perhaps. However, it is far less goofy than a default XP theme for damn sure. It gives it a really clean feel and I am no longer quite as bitter about having XP.
One of the broadly welcomed features of ColdFusion 9 has been the addition of implicit getters and setters to CFCs. What this means is that you no longer have to hand code the repetitive boiler plate getXXX() and setXXX() methods for each property in your model objects. However, you don’t need ColdFusion 9, (or even ColdFusion for that matter) to enjoy the benefits of the new implicit accessors with the version 9 release. Since ColdFusion 8, developers have had access to the OnMissingMethod() method which makes tasks like this very simple to implement on your own. The OnMissingMethod is also available in current versions of OpenBlueDragon and Railo.
For my implementation of this, I use a standard BaseBean class in a number of my projects which is extended by all of my model class objects. By leveraging the OnMissingMethod() in this BaseBean, I create these implicit accessors, in addition to an implicit constructor init() method as well.
There are multiple examples on the internet that show how you can use OnMissingMethod(), but for the most part, the examples that I have come across do not protect the class from being having infinite previously undefined properties added to it from the outside. For instance, I could have a class named Person.cfc with define properties of “firstName” and “lastName”, but nothing would stop someone from doing Person.setThisIsNotAProperty(true) and that value would be dynamically added to the Person instance. While some might argue that the flexibility that this approach offers is a positive thing, I prefer to lock my classes down just a bit more. For instance I like the fact that I can open up a model class and see exactly what properties it can contain with clearly defined <cfproperty/> tags. From a maintainability standpoint the idea of “mystery” dynamic properties strike me as just wrong.
For my implicit constructor, I take an approach where I loop through any named arguments that were passed, and if the name matches a property that I have defined with <cfproperty/>, then it will be passed to a setter method. Any arguments that are passed that are not defined as a property are discarded.
So let’s take a look at what this looks like. First I will paste the entire BaseBean, and below we will break it apart to discuss what is going on.
<cfcomponent output="false">
<cffunction name="init" access="public" output="false" returntype="BaseBean">
<cfset var i = "" />
<cfset initializePropertyList() />
<cfloop list="#this.propertyList#" index="i">
<cfif StructKeyExists(arguments,i)>
<cfset set(i,arguments[i]) />
</cfif>
</cfloop>
<cfreturn this />
</cffunction>
<cffunction name="initializePropertyList" access="private" output="false" returntype="void">
<cfset var i = "" />
<cfif NOT StructKeyExists(this,"propertyList")>
<cfset this.propertyList = "" />
<cfif ArrayLen(GetMetadata(this).properties)>
<cfloop from="1" to="#ArrayLen(GetMetadata(this).properties)#" index="i">
<cfset this.propertyList = ListAppend(this.propertyList,GetMetadata(this).properties[i].name)>
</cfloop>
</cfif>
</cfif>
<cfreturn />
</cffunction>
<cffunction name="onMissingMethod" access="public" output="false" returntype="any">
<cfargument name="missingMethodName" type="string" required="true" />
<cfargument name="missingMethodArguments" type="struct" required="true" />
<cfset var property = "" />
<cfif ReFindNoCase("^[gs](et)",arguments.missingMethodName)>
<cfset property = ReReplaceNoCase(arguments.missingMethodName,"^[gs](et)","") />
<cfset initializePropertyList() />
<cfif ListFindNoCase(this.propertyList,property)>
<cfif StructIsEmpty(arguments.missingMethodArguments)>
<cfreturn get(property) />
<cfelse>
<cfset set(property,arguments.missingMethodArguments[1]) />
<cfreturn this />
</cfif>
<cfelse>
<cfthrow message="The class #GetMetadata(this).name# does not have a property named #property# so the implicit #arguments.missingMethodName#() method is not available." />
</cfif>
</cfif>
<cfreturn />
</cffunction>
<cffunction name="get" access="public" output="false" returntype="any">
<cfargument name="property" type="string" required="true" />
<cfset var value = "" />
<cfset value = variables[arguments.property] />
<cfreturn value />
</cffunction>
<cffunction name="set" access="public" output="false" returntype="void">
<cfargument name="property" type="string" required="true" />
<cfargument name="value" type="any" required="true" />
<cfset variables[arguments.property] = arguments.value />
<cfreturn />
</cffunction>
</cfcomponent>
Before we walk through the actual flow, I would like to point out the method initializePropertyList() that you see here:
<cffunction name="initializePropertyList" access="private" output="false" returntype="void"> <cfset var i = "" /> <cfif NOT StructKeyExists(this,"propertyList")> <cfset this.propertyList = "" /> <cfif ArrayLen(GetMetadata(this).properties)> <cfloop from="1" to="#ArrayLen(GetMetadata(this).properties)#" index="i"> <cfset this.propertyList = ListAppend(this.propertyList,GetMetadata(this).properties[i].name)> </cfloop> </cfif> </cfif> <cfreturn /> </cffunction>
By using the GetMetadata() function, we are able to introspect our instance and create a list of property names which we can reference in our other methods. This is what enables us to enforce the rules that I described above in which we make sure that a property exists before setting it in the constructor or through an implicit accessor. You will see in both the init() and OnMissingMethod() methods that we call this method to ensure the list of properties is available before testing against it.
With that established, let’s take a look at the init() constructor method:
<cffunction name="init" access="public" output="false" returntype="BaseBean"> <cfset var i = "" /> <cfset initializePropertyList() /> <cfloop list="#this.propertyList#" index="i"> <cfif StructKeyExists(arguments,i)> <cfset set(i,arguments[i]) /> </cfif> </cfloop> <cfreturn this /> </cffunction>
After making sure that our propertyList has been initialized, we loop through that list and if there is a matching named argument, we call the set() method which sets that value into the variables scope.
So with the object initialized, let’s take a look at our accessors. For our example, let’s say that we have a Person object and we are doing to set our firstName property like this: person.setFirstName(“Dave”). Since that setter method doesn’t exist in our Person class, the OnMissingMethod() below will be invoked.
<cffunction name="onMissingMethod" access="public" output="false" returntype="any">
<cfargument name="missingMethodName" type="string" required="true" />
<cfargument name="missingMethodArguments" type="struct" required="true" />
<cfset var property = "" />
<cfif ReFindNoCase("^[gs](et)",arguments.missingMethodName)>
<cfset property = ReReplaceNoCase(arguments.missingMethodName,"^[gs](et)","") />
<cfset initializePropertyList() />
<cfif ListFindNoCase(this.propertyList,property)>
<cfif StructIsEmpty(arguments.missingMethodArguments)>
<cfreturn get(property) />
<cfelse>
<cfset set(property,arguments.missingMethodArguments[1]) />
<cfreturn this />
</cfif>
<cfelse>
<cfthrow message="The class #GetMetadata(this).name# does not have a property named #property# so the implicit #arguments.missingMethodName#() method is not available." />
</cfif>
</cfif>
<cfreturn />
</cffunction>
We are then doing a regular expression test to see if the missing method names starts with either “get” or “set”. If so, we derive the name of the target property by stripping the “get” or “set” off of the string. After making sure that our propertyList has been defined, we then look in that list to see if the target property actually exists in the instance. If it does, the request is then routed on to either the getter or the setter depending on whether arguments were passed to it. Otherwise an exception will be thrown to let the developer know that he or she has attempted to access an undefined property.
One thing you might notice is that when our conditional block routes the request to the setter, we return an instance of the class itself. This allows us to do method chaining like this: person.setFirstName(“Dave”).setLastName(“Shuck”). it should be noted that this is not the approach that Adobe took with ColdFusion 9.
So let’s take a look at it in action. Here is our Person.cfc class.
<cfcomponent output="false" extends="BaseBean"> <cfproperty name="id" type="string" /> <cfproperty name="firstName" type="string" /> <cfproperty name="lastName" type="string" /> </cfcomponent>
As you can see in the <cfcomponent/> tag, we are extending our BaseBean which is all that we need to have a workable domain class object.
When we put this together and access it in our code, we can do this:
<cfset person = CreateObject("component","Person").init(id=7,firstName="Dave", lastName="Shuck") />
<cfdump var="#person#" />

Once we have an instance, we can modify those properties like so:
<cfset person.setId(8).setFirstName("Johnny").setLastName("Rotten") />

I have not actually tested this on Railo, but I can confirm that it works in OpenBlueDragon (including GAE version), and ColdFusion versions 8 and 9.
This is a UDF that I keep on hand for converting strings to “proper case”, such as a person’s name. For instance, in a database we might have a name stored like DAVID B. SHUCK, but when they log into our site and we welcome them, we don’t necessarily want to shout it at them! Saying “Hello David B. Shuck…” would hopefully be a bit less abrasive.
Enter the user-defined function pcase(). Through the use of regular expressions we are doing a search for word patterns and capitalizing the first letter in each word. Enjoy!
<cffunction name="pcase" access="public" output="false" returntype="string">
<cfargument name="string" type="string" required="true" />
<cfreturn REReplaceNoCase(LCase(arguments.string),"(^[a-z*]|[ *][a-z*])","\U\1\E","all") />
</cffunction>
Very cool video showing a producer named Jim Pavloff re-creating this Prodigy classic using Ableton music production software, bringing in the samples one at a time and modifying them eventually building the entire track. I need me some Ableton! …. and some talent.
http://www.youtube.com/v/eU5Dn-WaElI&feature=youtube_gdata
Making Prodigy’s “Smack My Bitch Up” in Ableton by Jim Pavloff
I just got back from my first run in my new Vibram Five Fingers KSOs that I got for Christmas. To call them a minimalist running shoe would be an understatement. They are essentially a rubber sole strapped to your foot by way of neoprene, nylon, and velcro. I was first kind of intrigued on the theory of them after seeing this review on wired.com over the summer. In fact, if you don’t know anything about the Vibram Five Fingers, go watch that 2 minute video to see where I am coming from.
As that video explains, traditional running shoes encourage us to run in a pattern that our bodies weren’t designed for. The big heals typically cause us to follow a heal-to-toe pattern where the heal – and subsequently your leg – end up taking the shock of each step. Barefoot runners do not run like this, but instead land more on the ball of the foot, allowing the foot and leg to work together to become a shock absorber. A lot of studies suggest that the latter approach leads to less of the common injuries associated with running, such as shin splints, calf strain, and plantar fasciitis.
Over the summer, I began developing a calf strain injury that I simply couldn’t shake. It started when one day I was feeling great and decided to tack on 2 miles to my regular run. From that day on, my legs absolutely lit up with pain when I would try to run. Eventually I just took a month off of running an began easing myself back in following the Couch To 5K running program, building up to a longer run. While that approach has worked, I still feel a constant tinge in my left leg when I run where I feel like I am almost on the verge of hurting it again.
The more that I read about the Vibram Five Fingers and the more reviews that I read from people that have used them, I wondered if they might actually offer me a solution for not only avoiding injury, but getting stronger, and running more like I was designed to run from the beginning!
For Christmas, after hearing me talk about them again and again, my wife surprised me with a pair of the black KSOs (Keep Stuff Out), which are an improvement on the original design in that they come a bit higher on the foot to keep dirt and stuff out from the foot. And today ( December 26th ) I went for my first run.
I was a little bit apprehensive to be honest. I had heard a number of people say that it works your legs in a different fashion – most notably your calves – so start by doing shorter runs and working your way up to longer runs over time. I have had such great results with the Couch To 5K program, both with my introduction into running, and in my calf strain recovery, that I decided to invoke it yet again and start with Week 1 of the program. This is essentially 9 sets of 60 second run/90 second walk. Given my running speed that equates to a little less than a mile of actually running, and in hindsight, I feel that I could have definitely pushed a lot harder than that.
It was such a cool experience! I absolutely loved everything about it. On one hand, I could feel little things – even the cracks in the sidewalk – but not so much that it created pain or was any kind of interference. It just made me feel more in tune with my scene. I found that I had to take slightly shorter steps in an effort to make my foot land where I needed it to, but it became natural in mere moments. On the 1 mile track that I run there are a couple of steep hills and I found myself digging in on these hills to tackle them rather than feeling dread as I saw them approaching. There is something about the whole experience that felt very liberating, and gave me almost a primal, tribal pleasure as I kept thinking about the fact that this is how man has run for millenia!
Aside from the mental feeling, I got finished and realized that not a single thought went to my legs. Over the past 6 months or so, they haven’t been far from the front of my mind when I ran as I kept wondering when I was going to push them too far and tweak them again. I got home and felt completely exhilarated. My legs feel great, and I am looking forward to my next run!








