Jan

22

Posted by : Billy | On : January 22, 2012

For a while now, I’ve been using Sublime Text instead of ColdFusion Builder/CFEclipse – it’s faster and just gets out of the way. (I do still use Eclipse for MXUnit plugin however)

Getting ColdFusion support wasn’t too hard – I used the great package at https://github.com/indynagpal/coldfusion-sublime-text-2. However, it felt a little too “hands-on” for me for 2011.

However, today I discovered another ColdFusion package. The folks over at sublimetext.info (as best I can tell, not connected to the official company) have a GitHub repo at http://github.com/SublimeText with a number of Sublime Text packages for various languages. ColdFusion is one, and while it doesn’t have the massive snippet support of indynagpal’s, it does do a good job of mirroring some of the most common shortcuts used in Eclipse. You can do the downloading and unzipping thing (or git clone) – uggh – but you can also use the very excellent package manager over at http://wbond.net/sublime_packages/package_control to install ColdFusion support in Sublime Text in just a few steps:

  • Install Sublime Text from http://www.sublimetext.com if you haven’t already (unregistered version currently never times out, but I recommend purchasing it – the time you’ll save not waiting around for Eclipse to load will pay for itself quickly!)
  • Open Sublime, press CTRL (Update: both Mac and PC – *NOT* CMD on Mac) + ` (For the confused: hold down those 2 keys at the same time – note it’s the character below ESC, not a single quote)
  • Copy and paste the following into the console that comes up in Sublime Text: (from http://wbond.net/sublime_packages/package_control/installation)
    import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'
  • When it finishes (“Please restart Sublime Text to finish installation” shows in the bottom line of console), close Sublime Text and reopen
  • Click Preferences > Package Control
  • Click “Package Control: Install Package”
  • Scroll to or just type “ColdFusion” – hit Enter
  • You’ll see some action in the status bar of the app – it’ll tell you when it’s installed
  • Code your little ColdFusion heart out now – for into on shortcuts, etc, see the readme at https://github.com/SublimeText/ColdFusion

 

Nov

28

Posted by : Billy | On : November 28, 2011

Every EC2 instance is based on an Amazon Machine Image (AMI), which is basically a VM image. These can be “off the shelf”, or even better, you can customize one to your exact needs.This is really useful when you want to replicate machines, spreading work load across a mini cluster.

You can automate this from ColdFusion. Typically I’ll have a URL I call that starts up a series of tasks on each machine. Since the address for each machine is assigned by Amazon (you can get fancy with Elastic IPs if you’d like, but there’s really no need), it’s a matter of querying Amazon for the list of server names. Of course, if you’re running different types of machines, you want to filter by AMI ID, which of course changes each time you build a new image.

I won’t get into the exact code for querying here, but here’s how you get the AMI for a given machine from within ColdFusion: (Assumption is that this machine is one of your cluster machines, so once you have its AMI ID, you can filter for other machines like it)

<cfscript>
if (! isdefined("application.amiId")){
application.amiId=fileRead("http://169.254.169.254/2011-01-01/meta-data/ami-id");
}
request.amiID = application.amiId;
</cfscript>

Note: above tested in Open BlueDragon 2.0 – use <cfhttp> tag for engines that don’t support fileRead(uri)

As you might guess, that IP address is an API for EC2 metadata. The date is the API version (call the root IP address to get a list of API versions), “meta-data” is the API service, and “ami-id” is the value you’re requesting. (Call the URL without “ami-id” for a list of available values). For more information, go to http://docs.amazonwebservices.com/AWSEC2/2008-08-08/DeveloperGuide/index.html?AESDG-chapter-instancedata.html

Nov

27

Posted by : Billy | On : November 27, 2011

Small tip, but this held me up a bit.

For unit testing in ColdFusion, MXUnit is the standard. Even better, you can run your tests from within Eclipse, via a plugin.

After dropping MXUnit into my app (OSX 10.7.2 on dev machine, Eclipse+CFEclipse, Tomcat 7.0, Open BlueDragon 2.0 – had some pathing issues, but that’s another post…)

Right clicking on a unit test (such as in mxunit/samples/MyComponentTest.cfc) and selecting Run MXUnit Test, I received the following error:

Turns out it was going to port 80, rather than the port my CFML engine was running on (8080 in my case). This is an Eclipse preference:

Change the port to “http://localhost:8080/…” (or whatever you’re running) and it should work

Sep

15

Posted by : Billy | On : September 15, 2011

A couple of weeks ago I had the pleasure of having a conversation with Carl Franklin and Richard Campbell on .NET Rocks!, one of the premier .NET podcasts out there. While I ColdFusion is definitely my first love, I do plenty of .NET development, mostly C# WinForms and plain ole C# objects. That said, I think the show is great for more than just .NET – I can’t tell you the number of times I’ve learned new information on their site unrelated to .NET.

The Show

Our conversation was a follow-up to some email I sent them regarding a show where Rey Bango was a guest (talking about JavaScript). Rey, currently at Microsoft, was a ColdFusion guy back in the day, and on the show, ColdFusion was referred to as a “blast from the past”. I think that’s far from true: while ColdFusion is an “old” technology, it’s highly relevant today. So… a few emails later, they brought me on the show to talk up some ColdFusion.

When you speak in a public venue, you generally have an unlimited list of things you want to discuss, but a limited amount of time. So as you can imagine, there were tons of things I wanted to talk about that I’ll try to touch on here.

To the ColdFusion community: You’ll probably find a lot of things I failed to mention, which I did, but the focus was to emphasize that ColdFusion is a modern day language that is as relevant as .NET, PHP, and others. I think we accomplished that purpose. Also, the conversation was a very candid one, and looking back, I fear I may have come off as bashing Adobe a bit. I hope that’s not how my comments were received, but rather, but in the spirit they were given: a desire that Adobe more eagerly embraces its role as a server-side leader and putting ColdFusion more front and center.

To the .NET developers: Based purely on what you heard on the show, you probably have some impressions about what ColdFusion is, and what it isn’t, and how it’s deficient. I’ll attempt to address some of those ideas here

Event handling

ColdFusion does have a large degree of event handling, but it’s more like ASP.NET’s page lifecycle approach: onServerStart/End, onApplicationStart/End, onSessionStart/End, onRequestStart/End, etc. There are error events as well: onError, onMissingMethod, etc. There is also event handling inside of ColdFusion 9′s Hibernate integration, based on various ORM events. It also has an event gateway, which let’s you respond to various non-request events (such as watching a directory or message queue and responding based on defined listeners).

Moreover, the various MVC frameworks add more. (In speaking on MVC, I’ll be referencing ColdBox, which I know best. However, I’m certain most or all of what I address with apply to the others.) These frameworks have additional events (or extend the ones built into ColdFusion) accessible via framework methods, and you can even define your own events.

What you don’t really have are client events triggering events on the server. (I’m not talking things like jQuery events, but rather, ASP.NET code-behinds) ColdFusion doesn’t care about your markup, or how it received it’s headers: it just responds to what it’s given. This how all languages work, and it’s purer to the heart of what HTTP really is. (Hence, the movement away from WebForms towards ASP.NET MVC)

Tag-based syntax

Many think of ColdFusion as HTML++, since it has a tag-based syntax. This is true, but this in no way takes away from the language – it is a fully featured programming language. (Looping, calling web services, threading, PDF integration, database integration, objects, etc….)

However, for those who don’t like this syntax, ColdFusion has an C-style syntax that anyone familiar with C# should feel comfortable with. In the past, it was simply a way to do basic variable manipulation. However, over time, it has grown to include more and more of the language. As of the most recent version, you can query databases, send mail, write log files, create threads, and pretty much everything you’d do in tags, with only a short list of exceptions (rarely used platform-specific tags). You can even write objects fully in “CFScript” (while that goes back to CF’s roots, it’s now a misnomer in my opinion, as it’s more of a “second language” than scripting)

I had an app doing a lot of crazy things with Selenium RC. Originally the app was written in C# (because iterations of it used WebClient and then the iMacros .NET object), and I was utilizing the Selenium .NET object. However, I recently migrated over to using ColdFusion, relying on CFSelenium. I was able to copy and paste this code from C# directly into ColdFusion, and it ran with very little modification (in the catch block, the Exception type is different, and I removed “System.Threading.” from my Sleep() calls).

ORM

ORM has extensive use in the .NET space, whether you’re using the built-in Linq-to-SQL, or Entity Framework, or an add-on framework like NHibernate. ColdFusion integrates Hibernate as a core feature. You can even create objects, give them a “persistent” attribute, and they’ll become entities with no boilerplate needed. In addition, there’s a couple of great custom ORM frameworks that came out in the years prior to the Hibernate integration, Transfer and Reactor.

What about the rest of LINQ, where you can use SQL-like syntax to query non-database resources? ColdFusion has a feature called Query-of-Queries. This allows you to take a recordset, perform an in-memory query of it, and create a new recordset. Yes, ColdFusion has its own built-in SQL parser. This is cool, but this can be used for more than databases, as a number of ColdFusion functions return query objects, such as <cfdirectory>. Moreover, ColdFusion allows you to construct your own recordsets using functions like queryNew(), querySetCell(), etc, so you could mold any data structure into a format that lets you query, essentially doing what LINQ-to-Objects does.

.NET integration

You can integrate .NET classes into your ColdFusion applications – it can call them the same way it can call ColdFusion objects you’ve written, Java classes, or SOAP web service, via createObject().

Some of ColdFusion’s winning moves are the integrated features that other platforms require add-on components for: easily sending and receiving email, image or chart generation, PDF file generation, etc. ColdFusion exposes a number of these features (known as ColdFusion as a Service) via a series of SOAP services.

 

ColdFusion is a great platform, and like all platforms, it has its pros and cons. I hope I’ve helped the intelligent developer out there see that most of the worn-out arguments about the platform don’t hold much water or are outright incorrect, and that it’s a valuable thing to have in your toolbox, like .NET, Ruby, etc. I want to thank Carl and Richard for having me on .NET Rocks!, and want them to keep up the awesome work.

Apr

04

Posted by : Billy | On : April 4, 2011

As languages mature and add functions, we find them using function names that we ourselves would use. For example, a recent application passed metadata along to a PDF writer function.. makes sense to write a function called GetMetadata(), right? Well, turns out that’s already used in ColdFusion. So within my CFC, even though that function was defined, calls to the function retrieved what was internal to ColdFusion (CFC metadata, for those curious) without throwing an error. So, how do we call our CFC’s function without renaming it? By referencing it as this.GetMetadata()

Nov

02

Posted by : Billy | On : November 2, 2010

Noticed this in CF Builder:

Oddly, I can’t find information on this anywhere.. no blog posts, nothing in the documentation.

Does it work? No time for a real deep dive, but a quick test:

test.cfm

<cfset myObj = new ConstructorTest()>

<cfabort>

ConstructorTest.cfc

<cfcomponent initmethod=”myconstructor”>

<cffunction name=”myconstructor”>

<cfdump var=”#cgi#”>

</cffunction>

</cfcomponent>

Obviously this is when we use the new keyword that is, um, new, to ColdFusion 9.

What about other ways to call object? Add any random function to the CFC, and call via cfinvoke:

<cfinvoke component=”ConstructorTest” method=”test” returnvariable=”foo”></cfinvoke>
<cfoutput>#foo#</cfoutput>

Nope, doesn’t call constructor. Makes sense, since we’re calling as a static method.

How about if I use the “old” manner of creating an instance object?

<cfset obj = createObject(“component”,”ConstructorTest”)>
<cfoutput>#obj.test()#</cfoutput>

Nope, doesn’t call my implicit constructor. Inconsistency? Maybe, but it makes for nice backwards compatibility.

A little more digging found that you needn’t provide the attribute – you can have an implicit implict constructor. Just call your function “init”, like we’ve been doing for years (but had to call manually). Of course, as in my little example, this would have to be an argument-less constructor. Otherwise, pass those arguments as arguments in the new() method:

<cfset obj = new test1(x=”test”)>

No, ColdFusion won’t let you overload, so no multiple versions of init()

Oddly enough, it won’t let you set access=”private” for your constructor. Either your constructor won’t get called, or if you’ve declared it in initmethod, you’ll get an exception. Seems a bit of fail to me – would you ever want to call that function as a non-constructor (which calls the method twice)?

I’m still confused as to why there’s such little coverage of this….