<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-1973750947775262558</id><updated>2009-12-28T08:56:45.753-05:00</updated><title type='text'>MXUnit Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.mxunit.org/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default?start-index=26&amp;max-results=25'/><author><name>bill shelton</name><uri>http://www.blogger.com/profile/06624894387927690246</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>146</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-7465419098159117802</id><published>2009-12-24T09:41:00.001-05:00</published><updated>2009-12-24T09:41:30.132-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cfeclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='coldfusion builder'/><category scheme='http://www.blogger.com/atom/ns#' term='timesavers'/><title type='text'>Sharing your CFEclipse / ColdFusion Builder Snippets across multiple installs</title><content type='html'>&lt;p&gt;As I’ve written previously, I rely heavily on &lt;a href="http://blog.mxunit.org/2009/04/timesavers-cfeclipse-snippets.html" target="_blank"&gt;snippets&lt;/a&gt; when working with CFEclipse. One problem I’ve always encountered, however, is keeping snippets synchronized across multiple Eclipse installations. Typically, this problem manifests when trying to keep them sync’d between my laptop, my work computer, and my PC at home. Recently, this problem has further been exacerbated by ColdFusion Builder. Not only do I want to keep my snippets sync’d between multiple installs of CFEclipse, but I want the same snippets applied to CFBuilder, as well.&lt;/p&gt;  &lt;p&gt;Fortunately, this is a very easy to solve problem. &lt;/p&gt;  &lt;h2&gt;Dropbox&lt;/h2&gt;  &lt;p&gt;The first step is getting yourself a &lt;a href="http://dropbox.com" target="_blank"&gt;Dropbox&lt;/a&gt; account. Dropbox is a way to share files seamlessly across multiple computers. You’ll want to install dropbox on all your target machines.&lt;/p&gt;  &lt;h2&gt;Syncing&lt;/h2&gt;  &lt;h3&gt;A) Creating the shared snippets directory in your dropbox&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;Create a new directory in your dropbox folder, and call it “CFEclipse Snippets” or “CFSnippets” or whatever. &lt;/li&gt;    &lt;li&gt;Open CFEclipse (and CFBuilder if applicable). &lt;/li&gt;    &lt;li&gt;Go find your existing CFEclipse or CFBuilder extensions. In CFEclipse, you get there by going to window – preferences – CFEclipse. The Snippets install directory field will be there. Copy that path and go to it on your machine. It’ll contain a number of folders and a keycombos.properties file &lt;/li&gt;    &lt;li&gt;Cut all of those files and paste them into your new Snippets dropbox directory &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;B) Pointing CFEclipse to the&amp;#160; new snippets location&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;If you haven’t done so yet, remove the snippets from the previous CFEclipse snippets location &lt;/li&gt;    &lt;li&gt;Open the Snip Tree View in CFEclipse and hit the “refresh” button. Your snip tree view should now be empty since there are no snippets there. This is an important sanity check… don’t skip it. &lt;/li&gt;    &lt;li&gt;Copy the path to your dropbox snippets directory into your clipboard &lt;/li&gt;    &lt;li&gt;Go to the CFEclipse window – preferences – cfeclipse preference page and paste the new snippets location into your dropbox snippets location &lt;/li&gt;    &lt;li&gt;Back in the Snip Tree View, hit the refresh button again. Your snippets should now show up. &lt;/li&gt;    &lt;li&gt;From now on, when you add or edit snippets, they’ll be modified in the dropbox location &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Other Installs&lt;/h3&gt;  &lt;p&gt;For all your other installs – different versions of eclipse, different machines, whatever – you just follow the same steps as above from Section B. The bottom line is that if you want to sync snippets, you point all your installs to the same snippets location. Dropbox handles the magic of performing the actual synchronization&lt;/p&gt;  &lt;h3&gt;CFBuilder&lt;/h3&gt;  &lt;p&gt;Thus far, I’ve been talking about CFE only. Fortunately, CFBuilder uses the same model and code as CFE. So to get CFB working with the shared snippets, simply open CFBuilder, go to window – preferences – coldfusion – Snippets, and paste your shared snippets directory into that field. Hit Save, go back to CFB, and refresh your snip tree view&lt;/p&gt;  &lt;p&gt;Voila… snippets synced!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;*Note – On some of my Eclipse installs, I had to remove the snippets from the previous/original snippet location before it would recognize the new snippets location. YMMV.&lt;/p&gt;  &lt;p&gt;-Marc&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-7465419098159117802?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/7465419098159117802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=7465419098159117802' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/7465419098159117802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/7465419098159117802'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/12/sharing-your-cfeclipse-coldfusion.html' title='Sharing your CFEclipse / ColdFusion Builder Snippets across multiple installs'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-1849467493669207086</id><published>2009-12-19T13:23:00.001-05:00</published><updated>2009-12-19T13:23:49.739-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='announcements'/><category scheme='http://www.blogger.com/atom/ns#' term='mxunit product update'/><category scheme='http://www.blogger.com/atom/ns#' term='mxunit eclipse plugin'/><title type='text'>MXUnit Eclipse Plugin Updated</title><content type='html'>&lt;style&gt;


#brhide br {display:none}&lt;/style&gt;  &lt;h2&gt;What's new?&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;The pesky “resource is null” problem that some users have experienced when using project-level CFC paths and remote URLs should finally be resolved &lt;/li&gt;    &lt;li&gt;The “Tag Context” view now has two new menu options: “Copy Exception” and “Copy Tag Context”. This is handy when you need to copy the exception message or the entire tag context, as a string, into a bug report, email, etc. &lt;/li&gt;    &lt;li&gt;Clicking on an item in the Tag Context view will now trigger the “Compare” Dialog button, if the assertion is comparable (i.e. when an assertEquals() fails). Previously, you needed to click on the failing test to enable the button. That lameness has been resolved. &lt;/li&gt;    &lt;li&gt;I was watching Terry Ryan’s&amp;#160; video on using the &lt;a href="http://www.terrenceryan.com/blog/post.cfm/apptacular-coldfusion-builder-extension-unit-tests" target="_blank"&gt;Apptacular ColdFusion Builder Extension&lt;/a&gt; to generate MXUnit tests, and I noticed that his MXUnit view in Eclipse had a gigantic “Test History” button. Turns out, I created this as a 32x32 image; Eclipse on Windows resizes this automatically to 16x16, but apparently that’s not true on the Mac. I was aghast at this hideous image, and so now it’s 16x16. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Here are some screenshots of the new stuff in the Tag Context panel:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;“Copy” options&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/__j-6QTK4wT8/Sy0aMPRBuQI/AAAAAAAAAMw/GOr7aHqF5Z8/s1600-h/tagcontextview_1%5B3%5D.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="tagcontextview_1" border="0" alt="tagcontextview_1" src="http://lh6.ggpht.com/__j-6QTK4wT8/Sy0aMb_PqSI/AAAAAAAAAM0/_bDNih1a-xc/tagcontextview_1_thumb%5B1%5D.png?imgmax=800" width="244" height="156" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;“Compare” button enablement&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/__j-6QTK4wT8/Sy0aM-utwoI/AAAAAAAAAM4/ZffxcGeCnS8/s1600-h/tagcontextview_2%5B2%5D.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="tagcontextview_2" border="0" alt="tagcontextview_2" src="http://lh3.ggpht.com/__j-6QTK4wT8/Sy0aNQvMoqI/AAAAAAAAAM8/kTGpbKe1kCg/tagcontextview_2_thumb.png?imgmax=800" width="244" height="156" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;By the way: by default, the text compare dialog shows differences in black/gray. You can change this – as I’ve changed it to a reddish background in this shot – by going to Window – Preferences – General – Appearance – Colors and Fonts – Text Compare – Outgoing change color. Click the “Edit” button, and pick your color.&lt;/p&gt;  &lt;h2&gt;How do I get the update?&lt;/h2&gt;  &lt;p&gt;If you already have the plugin installed, then go through the normal update process. On Eclipse 3.5, that’s Help – Install New Software – Work With: MXUnit OR use Help – Check for Updates&lt;/p&gt;  &lt;p&gt;If you don’t have the plugin installed, then use Help – Install New Software – Add&amp;#160; and use &lt;a href="http://mxunit.org/update"&gt;http://mxunit.org/update&lt;/a&gt; as the URL&lt;/p&gt;  &lt;p&gt;Enjoy.&lt;/p&gt;  &lt;p&gt;--Marc&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-1849467493669207086?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/1849467493669207086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=1849467493669207086' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/1849467493669207086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/1849467493669207086'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/12/mxunit-eclipse-plugin-updated.html' title='MXUnit Eclipse Plugin Updated'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-9179067759331117845</id><published>2009-11-27T10:40:00.003-05:00</published><updated>2009-11-27T11:44:55.836-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='announcements'/><title type='text'>MXUnit 1.0.8 Released</title><content type='html'>Los Hombres at MXUnit.org are proud to announce a new smokin' release. Aside from some minor bug fixes, including improvements to the Ant task, and Open Blue Dragon compatibilities (Thanks to &lt;a href="http://blog.maestropublishing.com/"&gt;Peter Farrell&lt;/a&gt;!), we have some sweet features that will make your testing more productive and even downright fun! Ok, that was a stretch ... but check it out anyway... &lt;a href="http://mxunit.org/download.cfm"&gt;http://mxunit.org/download.cfm&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Eclipse Plugin&lt;/b&gt;: New data comparison feature. Highlight a failed test and click the little 'book'-looking button in the middle part of the plugin view. It'll pop up a compare dialog and you can use the "next change" and "previous change" buttons on the far right to navigate through the differences.&lt;br /&gt;
&lt;br /&gt;
Note that this will be the &lt;i&gt;last&lt;/i&gt; version to support Eclipse 3.3. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Framework&lt;/b&gt;: New data driven  capabilities via &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;mxunit:dataprovider&lt;/span&gt; annotation. Use queries, arrays, and Excel to power your tests. &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cf" name="code"&gt;&amp;lt;cfset name_data = ['joe','taj','mary','juan','hans', 'bjork','chaksa'] /&amp;gt; 

&amp;lt;cffunction name="testNameValidation" mxunit:dataprovider="name_data"&amp;gt;
   &amp;lt;cfargument name="name" hint="Each name item in the name_data array" /&amp;gt;
   &amp;lt;cfset assertTrue( myObject.validateName(name), "#name# not valid" ) /&amp;gt;
&amp;lt;/cffunction&amp;gt;

&lt;/pre&gt;&lt;br /&gt;
See &lt;a href="http://wiki.mxunit.org/display/default/Data+driven+testing+with+MXUnit+dataproviders"&gt;http://wiki.mxunit.org/display/default/Data+driven+testing+with+MXUnit+dataproviders&lt;/a&gt; for details&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Note: Application.cfm file is still included and should be removed after install to facilitate integration with frameworks or other applications.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Continuous Integration with Hudson&lt;/b&gt;: MXUnit is now being built on a continuous basis. Test results can be viewed here:&lt;a href="http://mxunit.org/testresults/index.html"&gt; http://mxunit.org/testresults/index.html&lt;/a&gt; and nightly builds can be downloaded from: &lt;a href="http://mxunit.org/downloadNightly.cfm"&gt;http://mxunit.org/downloadNightly.cfm&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Installation and Default Look and Feel&lt;/b&gt;: New logos and layout are incorporated into the default installation.&lt;br /&gt;
&lt;br /&gt;
Also, we'd like to welcome two new MXUnit hombres: &lt;a href="http://forthedeveloper.com/"&gt;Randy Merrill&lt;/a&gt; and &lt;a href="http://www.silverwareconsulting.com/"&gt;Bob Silverberg&lt;/a&gt;. Randy has been busy doing some much needed &lt;a href="http://wiki.mxunit.org/display/default/MXUnit+Documentation"&gt;project organization&lt;/a&gt; and graphics. Bob will be taking on integrating mocking into MXUnit. &lt;br /&gt;
&lt;br /&gt;
Test and Be Happy!&lt;br /&gt;
Los Hombres.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-9179067759331117845?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/9179067759331117845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=9179067759331117845' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/9179067759331117845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/9179067759331117845'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/11/mxunit-108-released.html' title='MXUnit 1.0.8 Released'/><author><name>bill shelton</name><uri>http://www.blogger.com/profile/06624894387927690246</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17359140296736057249'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-378502249267880125</id><published>2009-11-25T05:00:00.000-05:00</published><updated>2009-11-27T10:19:43.377-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Best Practices'/><category scheme='http://www.blogger.com/atom/ns#' term='ant'/><category scheme='http://www.blogger.com/atom/ns#' term='twicf'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Continuous Integration'/><title type='text'>This Week in ColdFusion Episode #5</title><content type='html'>&lt;style&gt;#hidebr br {display:none}&lt;/style&gt;  &lt;div id="hidebr"&gt;   &lt;p&gt;The guys put out &lt;a href="http://www.twicf.com/2009/11/twicf-05-solid-software/" target="_blank"&gt;Episode 5&lt;/a&gt; this week after an an extended break. In this episode, they addressed the question “What processes/practices/tools do you use to help ensure software integrity?”. Brian did most of the talking, and threw around his favorite phrase several times. I can see it now… Brian’s at a cocktail party, the chicks are dancin’, and he’s all “Hey Baby! You got some mad cyclomatic complexity goin’ on!”&lt;/p&gt;    &lt;p&gt;OK, OK. All snarkiness aside, this week’s episode touched on three subjects near and dear to me: testing, ANT, and continuous integration. I was thrilled that they spent so much time covering these topics. As they said, each one could fill up a podcast on its own, and I appreciate their honesty here… you can’t just listen to an hour long podcast and be Jonny Test. It takes a long time, and a lot of practice, to get there. Still, the more people out there saying “you need to test, people”, the better. Introductions to the concept, benefits, and resources are never a bad thing, and I think Brian covered these topics as well as can be expected in 60 minutes.&lt;/p&gt;    &lt;p&gt;And they gave MXUnit a lot of lovin’ during the show. So, gents, thanks for that! But it’s not gonna get you out of some gentle ribbing. Here goes:&lt;/p&gt;    &lt;h2&gt;Finger on the Pulse&lt;/h2&gt;    &lt;p&gt;Your intrepid reporter (uh, me) must confess to some surprise during the first few minutes of the episode. Here are 3 dudes who have been programming in CF for years, who have a frickin’ podcast about CF, but who talked about the &lt;a href="http://www.meetup.com/coldfusionmeetup/" target="_blank"&gt;CFMeetup&lt;/a&gt; almost as if it was some alien thing. Guys… Charlie’s been hosting guest speakers for years on the CFMeetup. The sessions are recorded so you can get them after-the-fact at &lt;a href="http://carehart.org/ugtv"&gt;http://carehart.org/ugtv&lt;/a&gt;. This is a tremendously valuable resource for CFers, and I damn near have a hard time believing that people as involved with CF such as yourselves wouldn’t have been on top of that like white on rice. &lt;/p&gt;    &lt;p&gt;What’s worrisome to me about this is that if you dudes don’t know about the CFMeetup and carehart.org in general, what’s that mean for the great masses of CF developers who aren’t even as active as you all are, who don’t do a CF podcast? And more importantly, how do we get the word out to more developers about the CFMeetup awesomeness?&amp;#160; &lt;/p&gt;    &lt;p&gt;&lt;em&gt;Aside: When I started learning Eclipse plugin development, I struggled with beginner-ish things even after reading a book on the topic. Most newsgroup questions were met with “look at the source”. Fair enough, but… what I really wanted was the answer to “What are the XX most important things a newbie should know about plugin development?”. I wonder how we get the answers to those questions out to new and old CFers alike… it’s not just about code, but also about resources. I wonder how we can all do a better job of connecting developers to the community. We spend so much time worrying about how to evangelize outside the community, but it seems that we need to start thinking about how to connect the people in the community to the excellent available resources that exist that can help make their lives easier. End Aside.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;And what about other ways of keeping a finger on the pulse of CF? Having helpful blogs on the radar, knowing helpful people to contact when the going gets rough, etc. I’m in no way suggesting that it’s one’s professional duty to be reading blogs all day, interacting on twitter for hours, attending all the CFMeetups (I rarely do… I catch the ones that interest me at more convenient times, via the recordings) or otherwise engaging in annoying starry-eyed CF fanboi-dom. Simply, I hope that as CF podcasters, you fine fellows can grow into your role as emissaries of our small-but-growing(-at-least-according-to-Adobe) community. When I listen to podcasts for other technologies, I do so because I expect the people behind the mics to be completely in tune with the community. As TWiCF, people are going to expect that of you, and I know you want to deliver.&lt;/p&gt;    &lt;p&gt;While I’m heaping un-asked-for responsibilities on you, I think it’s also important that you keep on talking about .NET and the things you are working on outside of CF. Lord knows the CF community is an insular one, and more reasons to lift the head up and look around are welcome.&lt;/p&gt;    &lt;p&gt;Get involved. You’ll be better for it, and &lt;strong&gt;so will we.&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;With that &lt;a href="http://www.snpp.com/episodes/CABF10" target="_blank"&gt;ticklish&lt;/a&gt; ribbing out of the way, let’s move on.&lt;/p&gt;    &lt;h2&gt;Unit Testing vs. TDD&lt;/h2&gt;    &lt;p&gt;Brian spent a lot of time discussing programmatic testing. Good on you, Brian. Clearly he’s a practitioner and knows his stuff. I was also interested in hearing more about the different tools for functional testing. I sure would like to see all these tools in action… the great symphony of testing. How about it, Brian? How about a CFMeetup presentation demo-ing these functional testing tools?&lt;/p&gt;    &lt;p&gt;Now, a nit to pick: Brian mentioned once during the episode that there was no difference between writing tests first or last. It’s my experience that there is a tremendous difference between the two. I won’t belabor the point because it’s been done to death (google it), but here’s the bottom line: writing tests first is an act of design. It damn near forces you to write testable code because from the start, you’re thinking, “How can I test this?”. It seems to me that when I write tests first, I end up approaching &lt;a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod" target="_blank"&gt;Uncle Bob’s SOLID principles&lt;/a&gt; almost naturally.&amp;#160; However, when I wait till afterwards to test, I miss out on that design opportunity and sometimes find that I have written less-testable code. &lt;/p&gt;    &lt;p&gt;I will be the first to admit this is because I am not all that bright, and that other far more capable developers come by easy-to-test code quite naturally, as if the ability were bequeathed unto them by The Almighty Himself. &lt;/p&gt;    &lt;p&gt;Furthermore, there is certainly no lack of debate around the desirability of easy-to-test code. More than a few developers believe that writing test first is a crippling exercise, atrophying the brain, because you’re thinking about testability and not the bigger picture of the system. In addition, there are those who believe that thinking about testability inevitably leads to Frankenstein, contorted designs (accessors/mutators where there otherwise wouldn’t be; reliance on non-void functions when if you weren’t testing, the function wouldn’t return void; exposing more methods as public when they should be private, etc). All fair points, and I’ll leave it to bright people to argue over while I go write code.&lt;/p&gt;    &lt;p&gt;So: “having tests” (and running them frequently) is helpful for catching regression bugs. Writing tests first is helpful as an act of component design which – to many – leads to higher quality software. &lt;/p&gt;    &lt;p&gt;P.S. If you’re interested in other podcasts or videos covering TDD/BDD, Hanselminutes has had a few gems. The interviews with &lt;a href="http://www.hanselminutes.com/default.aspx?showID=164" target="_blank"&gt;Scott Bellware&lt;/a&gt; and &lt;a href="http://www.hanselminutes.com/default.aspx?showID=187" target="_blank"&gt;Roy Osherove&lt;/a&gt; are classics. And you can’t go wrong listening to Joel and Jeff dis TDD and SOLID on the stackoverflow podcast. Finally, in the NSFW category, is Baltimore’s own, &lt;a href="http://rubyhoedown2008.confreaks.com/05-bryan-liles-lightning-talk-tatft-test-all-the-f-in-time.html" target="_blank"&gt;the incomparable Brian Liles&lt;/a&gt;.&lt;/p&gt;    &lt;h2&gt;Continuous Integration&lt;/h2&gt;    &lt;p&gt;I’ve been using the &lt;a href="http://hudson-ci.org/" target="_blank"&gt;Hudson continuous integration server&lt;/a&gt; at work since May and am quite taken with it. I’ve written about it before so won’t belabor the point. But Brian mentioned that he’d like to hear if anyone else out there has any suggestions regarding CI. &lt;a href="http://blog.mxunit.org/search/label/Hudson" target="_blank"&gt;So… I do&lt;/a&gt;. Brian mentioned that having the build server email you on every build becomes a bit much, and I heartily agree. In fact, one of the reasons Hudson impresses me so much is its plugin ecosystem. Specifically, the ‘Extended email plugin’ is outstanding for noise reduction. If you want to read more, &lt;a href="http://blog.mxunit.org/2009/08/continuous-integration-with-hudson_29.html" target="_blank"&gt;have at it&lt;/a&gt;.&lt;/p&gt;    &lt;h2&gt;Other Resources&lt;/h2&gt;    &lt;p&gt;Brian mentioned ANT several times, so I thought I’d point out Jim Priest’s excellent &lt;a href="http://www.thecrumb.com/wiki/ant" target="_blank"&gt;ANT wiki&lt;/a&gt; as a wonderful resource for CFers getting into ANT. In addition, for those interested in learning more about Selenium, &lt;a href="http://henke.ws/archives.cfm/category/Selenium" target="_blank"&gt;Mike Henke&lt;/a&gt; has written a decent amount about it. And, finally, check out &lt;a href="http://carehart.org/ugtv"&gt;http://carehart.org/ugtv&lt;/a&gt; and search for both ANT and Selenium to find presentations on the topic.&lt;/p&gt;    &lt;h2&gt;Wait, what? That’s all?&lt;/h2&gt;    &lt;p&gt;This week’s TWiCF review has turned into less a review of the episode and more just a general meandering about the topics they discussed. Why is that? Well, because I don’t want to be your Cliff’s Notes. Go and download the episode and listen to it. It’s a good one!&lt;/p&gt;    &lt;h2&gt;Till Next Time&lt;/h2&gt;    &lt;p&gt;Thanks again, gents, for another enjoyable episode. I’m looking forward to the next one.&lt;/p&gt;    &lt;p&gt;Marc, out&lt;/p&gt; &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-378502249267880125?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/378502249267880125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=378502249267880125' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/378502249267880125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/378502249267880125'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/11/this-week-in-coldfusion-episode-5.html' title='This Week in ColdFusion Episode #5'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-353629793233523047</id><published>2009-11-18T16:57:00.128-05:00</published><updated>2009-11-19T05:35:01.645-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogging'/><title type='text'>Anonymity, Accountability, and Credibility in Blogging</title><content type='html'>One literal definition of &lt;em&gt;anonymity&lt;/em&gt; is "without a name". In many contexts I respect people's right to anonymity and privacy if they so choose. However, producing and consuming information is a moral activity [ET], and as such, author&amp;nbsp;identification is critical to the subject's credibility and evolution.&lt;br /&gt;
&lt;blockquote&gt;&lt;i&gt;"Publicly attributed authorship indicates to the readers that someone is taking responsibility for the analysis, conversely, the absence of names signals an evasion of responsibility. Readers can follow up and communicate with named sources. Also, names may have reputation for credibility - or not." [ET]&lt;/i&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
I was motivated to write about this subject when I knowingly&amp;nbsp;engaged in a discussion with an Anonymous commenter on the &lt;a href="http://blog.mxunit.org/2009/06/look-ma-no-password-secure-hashing-in.html"&gt;MXUnit blog&lt;/a&gt;. My general rule of thumb is not to engage any Anonymous dialogs, but there was something about this one that caught my attention. Regardless of the reason, I began the discourse, and I am glad I did because it got me thinking, but not so much on the subject of the discussion, which is irrelevant, but rather on the subject of anonymity and credibility. We went back and forth, me and &lt;em&gt;Anonymous&lt;/em&gt;. I was looking for proof or citations on some small point and I also wanted to know with whom I was speaking, but I never asked or demanded, which was&amp;nbsp;&lt;em&gt;&lt;u&gt;my&lt;/u&gt; failed responsibility&lt;/em&gt;. I now conclude that the points the commenter made are &lt;b&gt;100% &lt;/b&gt;&lt;strong&gt;invalid&lt;/strong&gt;. They're invalid not because of their intended or intrinsic merit, they're invalid because Anonymous is not willing to&amp;nbsp;be accountable, and accountability is a precondition for the credibility of information. &lt;br /&gt;
&lt;br /&gt;
This speaks to the broader question of anonymity in the context of the blogging and the web, too. As an information producer or consumer does anonymity do anyone any good at all? Could anonymity possibly do damage? When it comes to discourse, such as expressing ideas on technical issues, today I believe that anonymity doesn't have a place and should be discouraged. So, anonymous comments are now disabled on the MXUnit blog.&lt;br /&gt;
&lt;br /&gt;
I suspect that if you're not willing to take ownership of what you write or say, that maybe you shouldn't say it.&amp;nbsp; This may be the simple litmus test we should follow.&amp;nbsp; If we're concerned about backlash maybe the answer is not perpetuating anonymity but creating a stronger culture of acceptance, open mindedness, and freedom. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
bill shelton&lt;br /&gt;
&lt;br /&gt;
[ET] Edward Tufte - &lt;a href="http://www.edwardtufte.com/tufte/books_be"&gt;http://www.edwardtufte.com/tufte/books_be&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-353629793233523047?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/353629793233523047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=353629793233523047' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/353629793233523047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/353629793233523047'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/11/anonymity-accountability-and-blogging.html' title='Anonymity, Accountability, and Credibility in Blogging'/><author><name>bill shelton</name><uri>http://www.blogger.com/profile/06624894387927690246</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17359140296736057249'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-2509789469871777616</id><published>2009-11-11T07:00:00.000-05:00</published><updated>2009-11-11T07:17:41.871-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Best Practices'/><category scheme='http://www.blogger.com/atom/ns#' term='timesavers'/><title type='text'>Data-Driven testing with MXUnit's DataProviders</title><content type='html'>&lt;style&gt;
#hidebr br {display:none}&lt;/style&gt;  &lt;div id="hidebr"&gt;   &lt;h2&gt;What are DataProviders?&lt;/h2&gt;    &lt;p&gt;Often in unit testing, you will want to run a test function for multiple inputs. Imagine you have a reformatFullName() that parses a string like “Smith, Bob” into “Bob Smith”. And in your test case, you would like to test your reformatFullName() function for a bunch of different inputs to ensure that you’ve covered common cases and also edge cases.&lt;/p&gt;    &lt;p&gt;One common approach to this method is to specify the list/array/whatever – the collection of inputs – in the test function, and then write a loop inside the test function. This is a perfectly reasonable approach, though it does lead to some boilerplate.&lt;/p&gt;    &lt;p&gt;DataProviders essentially remove the boilerplate; in other words, DataProviders offer a way for you to specify multiple inputs, but without having to construct the looping. In addition, in MXUnit, you have multiple built-in DataProviders at your disposal, which will be covered in other documentation and blog entries. For now, let’s look at a simple case: an array dataprovider.&lt;/p&gt;    &lt;p&gt;How do I use DataProviders in my unit tests?&lt;/p&gt;    &lt;h2&gt;I Palindrome I&lt;/h2&gt;    &lt;p&gt;For this example, I wanted to have a little fun, so I chose the &lt;a href="http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-00Fall-2008/LectureVideos/detail/embed04.htm" target="_blank"&gt;classic CS101 problem of Palindromes&lt;/a&gt;. I think back to my first programming course – Introduction to Programming in C – and distinctly remember the teacher’s frustrated attempts to drill &lt;a href="http://en.wikipedia.org/wiki/Recursion_%28computer_science%29" target="_blank"&gt;recursion&lt;/a&gt; into our thick skulls. One of the problems he used to demonstrate it was &lt;a href="http://en.wikipedia.org/wiki/Palindrome" target="_blank"&gt;Palindromes&lt;/a&gt;, i.e. How do you know if a word is the same forwards and backwards (“mom”, “dad”, etc)?&amp;#160; The teacher used rubber bands; he had us “act out” a palindrome. Oi, poor guy. Anyways…&lt;/p&gt;    &lt;p&gt;Before we get into DataProviders, let’s start with a very simple test:&lt;/p&gt;    &lt;pre class="cf" name="code"&gt;component extends=&amp;quot;mxunit.framework.TestCase&amp;quot;{

	function setUp(){
		checker = new PalindromeChecker();		
	}

	function palindromeChecker_Should_ReturnTrue_ForPalindrome(){
		assertTrue(checker.isPalindrome(&amp;quot;mom&amp;quot;));
	}

}&lt;/pre&gt;

  &lt;p&gt;That’s a good start, but it doesn’t cover cases where the input isn’t a palindrome, and it sure feels incomplete, doesn’t it? Now, let’s look at a testcase that uses an array DataProvider. In here, we’ll specify an array of palindromes and tell MXUnit: Hey, MXUnit, use this array to run my test, one time for each element in the array:&lt;/p&gt;

  &lt;pre class="cf" name="code"&gt;component extends=&amp;quot;mxunit.framework.TestCase&amp;quot;{

	function setUp(){
		checker = new PalindromeChecker();
		//set up dataprovider
		variables.palindromes = [&amp;quot;wow&amp;quot;,&amp;quot;mom&amp;quot;,&amp;quot;dad&amp;quot;,&amp;quot;eye&amp;quot;,&amp;quot;marccram&amp;quot;,&amp;quot;bob&amp;quot;,&amp;quot;poooooooooooop&amp;quot;];		
	}

	/**
	*@mxunit:dataprovider palindromes
	*/
	function palindromeChecker_Should_ReturnTrue_ForPalindromes(String theWord){
		//debug(theWord);
		assertTrue( checker.isPalindrome(theWord), &amp;quot;word #theWord# should have been flagged as a palindrome&amp;quot; );
	}

}&lt;/pre&gt;

  &lt;p&gt;Here, we create an array named “palindromes”. Then, in the test, we specify the custom attribute &lt;a href="mailto:&amp;ldquo;@mxunit:dataprovider"&gt;“@mxunit:dataprovider&lt;/a&gt;” and set its value to “palindromes”. MXUnit will see that its been given a dataprovider, see that palindromes is an array, and will run the test one time for each element in the array. One other thing about this test function&amp;#160; should jump out at you: it takes a parameter. Typically, tests return void and accept no params. So why do we need this? Simply, MXUnit will pass the current value in the array into the argument which we’ve specified named “theWord”. If you run this test and uncomment the debug(theWord) statement, then hit ctrl-B on the test case in the MXUnit view in Eclipse, you’ll see each value as the test runs.&lt;/p&gt;

  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/__j-6QTK4wT8/SvoBhzS4b_I/AAAAAAAAAMk/bTb_P_HvJzQ/s1600-h/sshot-3%5B3%5D.png" target="_blank"&gt;&lt;img title="sshot-3" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="sshot-3" src="http://lh3.ggpht.com/__j-6QTK4wT8/SvoBid4H_cI/AAAAAAAAAMo/tp0EiVyYwyw/sshot-3_thumb%5B1%5D.png?imgmax=800" width="229" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

  &lt;p&gt;And now, let's add a negative test:&lt;/p&gt;

  &lt;pre class="cf" name="code"&gt;component extends=&amp;quot;mxunit.framework.TestCase&amp;quot;{

	function setUp(){
		checker = new PalindromeChecker();
		//set up dataproviders
		variables.palindromes = [&amp;quot;wow&amp;quot;,&amp;quot;mom&amp;quot;,&amp;quot;dad&amp;quot;,&amp;quot;eye&amp;quot;,&amp;quot;marccram&amp;quot;,&amp;quot;bob&amp;quot;,&amp;quot;poooooooooooop&amp;quot;];
		variables.notPalindromes = [&amp;quot;woww&amp;quot;,&amp;quot;momm&amp;quot;,&amp;quot;marc&amp;quot;,&amp;quot;eyee&amp;quot;,&amp;quot;bbobbb&amp;quot;,&amp;quot;poooeeiop&amp;quot;];
	}
	

	/**
	*@mxunit:dataprovider notpalindromes
	*/
	function palindromeChecker_Should_ReturnFalse_ForNonPalindromes(String theWord){
		assertFalse( checker.isPalindrome(theWord), &amp;quot;word #theWord# should not have been flagged as a palindrome&amp;quot; );
	}

}&lt;/pre&gt;

  &lt;p&gt;Now that we’ve got some tests – and they should be failing b/c we haven’t created a PalindromeChecker.cfc yet – let’s implement the functionality. We’ll do the braindead simplest way first (which is probably the way you would want to do it in real life):&lt;/p&gt;

  &lt;pre class="cf" name="code"&gt;/**
*@hint checks an input string for Palindrome-ness.
*
*/
component{	
	//how I'd program it if this were for a production system
	public boolean function isPalindrome_simple(String theWord){
		return theWord == reverse(theWord);
	}

}&lt;/pre&gt;

  &lt;p&gt;And now let’s have some recursion fun:&lt;/p&gt;

  &lt;pre class="cf" name="code"&gt;/**
*@hint checks an input string for Palindrome-ness.
*
*/
component{
	//use recursion to get it; this is simply to demonstrate recursion
	public boolean function isPalindrome(String theWord){
		//the &amp;quot;base&amp;quot; case... the simplest case we can have that will return true
		if(len(theWord) &amp;lt;= 1) return true;

		/*compare the far left char with the far right char, and then pass the stuff in between
		the far left and far right back into isPalindrome
		 for input: marccram, calls will look thusly:
		   m == m &amp;amp;&amp;amp; isPalindrome(arccra) is true
		   	a == a &amp;amp;&amp;amp; isPalindrome(rccr)  is true
			 r == r &amp;amp;&amp;amp; isPalindrome(cc)   is true
			  c == c &amp;amp;&amp;amp; isPalindrome('')   is true
			   len('') &amp;lt;= 1 return true
		*/
		return left(theWord,1) == right(theWord,1) &amp;amp;&amp;amp; isPalindrome( mid(theWord,2,len(theWord)-2) );
	}

	//how I'd program it if this were for a production system
	public boolean function isPalindrome_simple(String theWord){
		return theWord eq reverse(theWord);
	}

}&lt;/pre&gt;

  &lt;p&gt;If you run your tests now, you should see them pass. For fun, you could put calls to isPalindrome() and isPalindromeSimple() in each of these tests as a sanity check. &lt;/p&gt;

  &lt;h2&gt;How do I get these DataProviders?&lt;/h2&gt;

  &lt;p&gt;Great question. As of this writing, the DataProvider functionality is in &lt;a href="http://code.google.com/p/mxunit/source/checkout" target="_blank"&gt;Subversion&lt;/a&gt;, and we’re prepping a release. If you just gotta have it right now, but you don’t want to check it out from SVN, let me know and I’ll whip up a nightly build.&lt;/p&gt;

  &lt;p&gt;Stay tuned for more documentation about the other new DataProviders in MXUnit!&lt;/p&gt;

  &lt;p&gt;--Marc&lt;/p&gt;
&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-2509789469871777616?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/2509789469871777616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=2509789469871777616' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/2509789469871777616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/2509789469871777616'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/11/data-driven-testing-with-mxunit.html' title='Data-Driven testing with MXUnit&amp;#39;s DataProviders'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-3423633036699002327</id><published>2009-11-01T09:43:00.001-05:00</published><updated>2009-11-01T09:43:56.171-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='launchy'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='timesavers'/><title type='text'>Windows 7 CMD Access is Denied</title><content type='html'>&lt;h2&gt;Access is Denied&lt;/h2&gt;  &lt;p&gt;Windows 7 installed without a hitch, but I noticed that the &lt;a href="http://blog.mxunit.org/2009/04/timesavers-batch-files.html" target="_blank"&gt;bat files&lt;/a&gt; I use to turn certain programs on and off no longer worked. Specifically, I have bat files that use “NET START” and “NET STOP” to toggle Windows Services. When I’d run those, I’d get “Access is Denied”. This was particularly annoying b/c I use &lt;a href="http://blog.mxunit.org/2009/04/timesavers-launchy.html" target="_blank"&gt;Launchy&lt;/a&gt; to run these bat files to quickly set up and tear down an environment, and this new “security feature” was breakin’ my stride. Here’s how to remind Windows that you are its boss.&lt;/p&gt;  &lt;h2&gt;Do As I Say, Dammit!&lt;/h2&gt;  &lt;h3&gt;Set Command Prompt to Run As Administrator&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;From the Start menu, filter on “Command Prompt” &lt;/li&gt;    &lt;li&gt;Right click on it, select “Properties”. In the “Shortcut” tab, click the Advanced button. &lt;/li&gt;    &lt;li&gt;Check the “Run as Administrator” checkbox &lt;/li&gt;    &lt;li&gt;Restart your computer &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Here’s a screenshot of what these boxes look like (taken with the new Windows 7 “Snipping Tool”):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/__j-6QTK4wT8/Su2eqlUHdWI/AAAAAAAAAMc/I-x1wITXy9c/s1600-h/commandpromptproperties%5B3%5D.png" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="commandpromptproperties" border="0" alt="commandpromptproperties" src="http://lh4.ggpht.com/__j-6QTK4wT8/Su2eqwoLryI/AAAAAAAAAMg/O5SjxrxdQk8/commandpromptproperties_thumb%5B1%5D.png?imgmax=800" width="244" height="166" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;It was my experience that you need to restart your computer. When I changed these settings initially, it didn’t change the behavior of my bat files at all. Only after restart did my “Access is Denied” problems go away.&lt;/p&gt;  &lt;p&gt;Good luck.&lt;/p&gt;  &lt;p&gt;--Marc&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-3423633036699002327?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/3423633036699002327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=3423633036699002327' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/3423633036699002327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/3423633036699002327'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/11/windows-7-cmd-access-is-denied.html' title='Windows 7 CMD Access is Denied'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-63499823402949091</id><published>2009-10-30T14:50:00.001-04:00</published><updated>2009-10-30T14:50:46.984-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Best Practices'/><category scheme='http://www.blogger.com/atom/ns#' term='mxunit eclipse plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>How Many Assertions in My Tests?</title><content type='html'>&lt;style&gt;
#hidebr br {display:none}&lt;/style&gt;  &lt;h2&gt;One Long Test&lt;/h2&gt;  &lt;p&gt;When I first started writing unit tests with JUnit, I didn't read any books, follow blogs, or otherwise attempt to be the best test writer I could be. I wanted to crank out code, crank out tests, and see the green bar. In fact, my tests looked a lot like this:&lt;/p&gt;  &lt;div id="hidebr"&gt;   &lt;pre class="java" name="code"&gt;public void testGetRequestBeansByIDType() {
    Integer requestID=8;
    Integer statusID=4;
    Integer systemID=1;
    Integer processTypeID=1;
    String inList=&amp;quot;0,4,5,6,7,8&amp;quot;;
    
    String requestIDSQL = &amp;quot;Select count(*) as NumRequests from &amp;quot; +
        &amp;quot;requests where requestid=&amp;quot;+requestID;
    
    String statusIDSQL = &amp;quot;Select count(*) as NumRequests from &amp;quot; +
        &amp;quot;requests where statusid=&amp;quot;+statusID;
    
    String systemIDSQL = &amp;quot;Select count(*) as NumRequests from &amp;quot; +
        &amp;quot;requests where systemid=&amp;quot;+systemID;
    
    String processIDSQL = &amp;quot;Select count(*) as NumRequests from &amp;quot; +
        &amp;quot;requests where processTypeID=&amp;quot;+processTypeID;
    
    String inSQL = &amp;quot;Select count(*) as NumRequests from &amp;quot; +
        &amp;quot;requests where RequestID IN(&amp;quot;+inList+&amp;quot;)&amp;quot;;
    
    try {
        //test requestID
        HashMap&amp;lt;String,Object&amp;gt; row = dbops.getRow(requestIDSQL,1);
        int count = ((Integer)row.get(&amp;quot;numrequests&amp;quot;)).intValue();
        ArrayList&amp;lt;RequestBean&amp;gt; requests 
            = dbops.getRequestBeansByIDType(&amp;quot;RequestID&amp;quot;,requestID.toString(),&amp;quot;&amp;quot;);
        assertEquals(count,requests.size());
        System.out.println(&amp;quot;RequestID rows is &amp;quot; + requests.size());
        
        //test statusID
        HashMap&amp;lt;String,Object&amp;gt; row2 = dbops.getRow(statusIDSQL,1);
        int count2 = ((Integer)row2.get(&amp;quot;numrequests&amp;quot;)).intValue();
        ArrayList&amp;lt;RequestBean&amp;gt; requests2
            = dbops.getRequestBeansByIDType(&amp;quot;StatusID&amp;quot;,statusID.toString(),&amp;quot;&amp;quot;);
        assertEquals(count2,requests2.size());
        System.out.println(&amp;quot;statusID rows is &amp;quot; + requests2.size());
        
        //test systemid
        HashMap&amp;lt;String,Object&amp;gt; row3 = dbops.getRow(systemIDSQL,1);
        int count3 = ((Integer)row3.get(&amp;quot;numrequests&amp;quot;)).intValue();
        ArrayList&amp;lt;RequestBean&amp;gt; requests3
            = dbops.getRequestBeansByIDType(&amp;quot;SystemID&amp;quot;,systemID.toString(),&amp;quot;&amp;quot;);
        assertEquals(count3,requests3.size());            
        System.out.println(&amp;quot;systemID rows is &amp;quot; + requests3.size());
        
        //test ProcessTypeID
        HashMap&amp;lt;String,Object&amp;gt; row4 = dbops.getRow(processIDSQL,1);
        int count4 = ((Integer)row4.get(&amp;quot;numrequests&amp;quot;)).intValue();
        ArrayList&amp;lt;RequestBean&amp;gt; requests4
            = dbops.getRequestBeansByIDType(&amp;quot;ProcessTypeID&amp;quot;,processTypeID.toString(),&amp;quot;&amp;quot;);
        assertEquals(count4,requests4.size()); 
        System.out.println(&amp;quot;ProcessTypeID rows is &amp;quot; + requests4.size());
        
        
        //test IN() statements
        HashMap&amp;lt;String,Object&amp;gt; row5 = dbops.getRow(inSQL,1);
        int count5 = ((Integer)row5.get(&amp;quot;numrequests&amp;quot;)).intValue();
        ArrayList&amp;lt;RequestBean&amp;gt; requests5
            = dbops.getRequestBeansByIDType(&amp;quot;RequestID&amp;quot;,inList,&amp;quot;&amp;quot;);
        assertEquals(count5,requests5.size());
        System.out.println(&amp;quot;IN rows is &amp;quot; + requests5.size());
        
        // test order by....
        ArrayList&amp;lt;RequestBean&amp;gt; requests6
            = dbops.getRequestBeansByIDType(&amp;quot;StatusID&amp;quot;,&amp;quot;3&amp;quot;,&amp;quot;RequestID Desc&amp;quot;);
        RequestBean rb = requests6.get(0);
        RequestBean rb2 = requests6.get(1);
        assertTrue(rb.getRequestID() &amp;gt; rb2.getRequestID());
        
        ArrayList&amp;lt;RequestBean&amp;gt; requests7
        = dbops.getRequestBeansByIDType(&amp;quot;StatusID&amp;quot;,&amp;quot;3&amp;quot;,&amp;quot;RequestID asc&amp;quot;);
        RequestBean rb3 = requests7.get(0);
        RequestBean rb4 = requests7.get(1);
        assertTrue(rb4.getRequestID() &amp;gt; rb3.getRequestID());
    } catch (Exception e) {
       fail(&amp;quot;getRow should not have returned an error&amp;quot;);
    }
   
}&lt;/pre&gt;

  &lt;p&gt;If you’re looking at that thinking “What’s wrong with that?”, then please read on. If you’re horrified… join the club.&lt;/p&gt;

  &lt;h2&gt;What’s wrong with that?&lt;/h2&gt;

  &lt;p&gt;testGetRequestBeansByIDType, how do I hate thee? Let me count the ways&lt;/p&gt;

  &lt;ol&gt;
    &lt;li&gt;If some assertion fails up toward the top of this test, none of the other assertions run. So what happens is you get yourself in this constant loop of “it worked last month, now it’s not working. Why?” and so you go fix the failing test, satisfied everything is OK, and then you run em again and another assertion in the same test fails. This infuriates me &lt;/li&gt;

    &lt;li&gt;Notice how I’m using comments for each of the different tests?&amp;#160; I’m trying to communicate requirements, but I’m doing so in a way that doesn’t much help. If each of these little chunks were separate tests, the test case itself would be much more communicative in my opinion &lt;/li&gt;

    &lt;li&gt;It’s been my experience that the more things I do in a single test, the more likely I am to create/change some state that modifies the behavior of the subsequent assertions &lt;/li&gt;

    &lt;li&gt;When developing in this manner, just cranking out tests and not writing descriptive test names that describe the behavior under test, I’m missing out on one of unit testing’s greatest benefits: using it as an aide to clarify thinking. This is a huge topic, and one that I don’t want to get into here. Suffice it to say, anyone who’s done TDD for a while knows exactly what I mean. Anyone who hasn’t done it will only know what I mean once you get yourself in the camp of the people who have done it. You have to earn this answer &lt;/li&gt;
  &lt;/ol&gt;

  &lt;p&gt;So what’s a boy to do?&amp;#160; Personally, I’ve become fond of BDD-style naming. I prefer long, descriptive test names; I prefer as few assertions as necessary in a single test.&amp;#160; This leads to some additional lines of code, but I use snippets for this so I’m not spending any more time writing more tests than I would be if I were simply writing more assertions. The resultant clarity is worth it.&lt;/p&gt;

  &lt;h2&gt;Ahhhh, That’s Better&lt;/h2&gt;

  &lt;p&gt;Here’s a more recent example:&lt;/p&gt;

  &lt;pre class="cf" name="code"&gt;&amp;lt;!--- basic tests to make sure the 'outer' logic is right---&amp;gt;
&amp;lt;cffunction name=&amp;quot;recipientsWithAffectedLetterCode_Should_GetPhoneNumberCoordinates&amp;quot; returntype=&amp;quot;void&amp;quot; access=&amp;quot;public&amp;quot;&amp;gt;
	&amp;lt;cfset var coordinates = &amp;quot;&amp;quot;&amp;gt;
	&amp;lt;cfloop list=&amp;quot;#affectedLetterCodes#&amp;quot; index=&amp;quot;code&amp;quot;&amp;gt;			
		&amp;lt;cfset coordinates = getCoordinatesWithWCRBCD(&amp;quot;JH89&amp;quot;,code)&amp;gt;	
		&amp;lt;cfset assertTrue( StructCount(coordinates) GT 0,&amp;quot;Coordinates struct should not have been empty for #code# but was.&amp;quot; )&amp;gt;
	&amp;lt;/cfloop&amp;gt;
&amp;lt;/cffunction&amp;gt;

&amp;lt;cffunction name=&amp;quot;recipientsWithoutAffectedLetterCode_ShouldNot_GetPhoneNumberCoordinates&amp;quot; returntype=&amp;quot;void&amp;quot; &amp;gt;			
	&amp;lt;cfset var coordinates = &amp;quot;&amp;quot;&amp;gt;
	&amp;lt;cfloop list=&amp;quot;#unaffectedLetterCodes#&amp;quot; index=&amp;quot;code&amp;quot;&amp;gt;
		&amp;lt;cfset coordinates = getCoordinatesWithWCRBCD(&amp;quot;junk&amp;quot;,code)&amp;gt;	
		&amp;lt;cfset assertTrue( StructIsEmpty(coordinates),&amp;quot;Coordinates struct should have been empty for #code# but was not. It had keys: #StructKeyList(coordinates)#&amp;quot; )&amp;gt;
	&amp;lt;/cfloop&amp;gt;
&amp;lt;/cffunction&amp;gt;

&amp;lt;!--- more granular tests for the specifics of which number to get;
yes, this duplicates the logic in the production code. So be it. ---&amp;gt;
&amp;lt;cffunction name=&amp;quot;WCRBCD_JH89_gets_2011_PhoneNumber&amp;quot; output=&amp;quot;false&amp;quot; access=&amp;quot;public&amp;quot; returntype=&amp;quot;any&amp;quot; hint=&amp;quot;&amp;quot;&amp;gt;
	&amp;lt;cfset var coordinates = getCoordinatesWithWCRBCD(&amp;quot;JH89&amp;quot;)&amp;gt;
	&amp;lt;cfset assertEquals(&amp;quot;866.420.2011&amp;quot;,coordinates.PhoneNumber,&amp;quot;&amp;quot;)&amp;gt;		
&amp;lt;/cffunction&amp;gt;

&amp;lt;cffunction name=&amp;quot;WCRBCD_MK01_gets_9446_PhoneNumber&amp;quot; output=&amp;quot;false&amp;quot; access=&amp;quot;public&amp;quot; returntype=&amp;quot;any&amp;quot; hint=&amp;quot;&amp;quot;&amp;gt;
	&amp;lt;cfset var coordinates = getCoordinatesWithWCRBCD(&amp;quot;MK01&amp;quot;)&amp;gt;
	&amp;lt;cfset assertEquals(&amp;quot;866.356.9446&amp;quot;,coordinates.PhoneNumber,&amp;quot;&amp;quot;)&amp;gt;	
&amp;lt;/cffunction&amp;gt;

&amp;lt;cffunction name=&amp;quot;WCRBCD_NotMK01AndNotJH89_gets_7436_PhoneNumber&amp;quot; output=&amp;quot;false&amp;quot; access=&amp;quot;public&amp;quot; returntype=&amp;quot;any&amp;quot; hint=&amp;quot;&amp;quot;&amp;gt;
	&amp;lt;cfset var coordinates = getCoordinatesWithWCRBCD(&amp;quot;NOTMK01&amp;quot;)&amp;gt;
	&amp;lt;cfset assertEquals(&amp;quot;866.281.7436&amp;quot;,coordinates.PhoneNumber,&amp;quot;&amp;quot;)&amp;gt;	
&amp;lt;/cffunction&amp;gt;&lt;/pre&gt;

  &lt;p&gt;Ignore for a minute the weirdo codes (WCRBCD, JH89, etc) as they are domain-specific and well-known for people working on the project. The point here is that the names describe exactly the various expected behaviors of this single function under test (getCoordinatesWithWCRBCD()). When one test fails, I don’t have to spend time reasoning about whether previous logic or function calls are the culprit. I and other team members don’t have to learn about the behavior by reading comments because the function names themselves are the documentation.&amp;#160; I don’t have that “Fixed-this-assertion-and-now-another-one-is-failing” problem. If something breaks, I know very soon because we run everything in a continuous integration environment. Code changes, tests run, something breaks: I can go right into Hudson and see exactly the behavior that used to work and now no longer works. If multiple things break as a result of a code change, I see those multiple things, not just the first assertion that failed.&lt;/p&gt;

  &lt;p&gt;Is there a downside to this approach? Yes… if you’re typing out each function by hand, i.e. &amp;lt; c f f u …, then you’re going to be typing more. But if you’re typing out functions by hand, you’re doing it wrong! MXUnit comes bundled with a bunch of useful Eclipse snippets. Read the documentation, install them, and use them. Then, when you want to add a new test function, you type the word “test”, hit CTRL-J, and up pops this box:&lt;/p&gt;

  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/__j-6QTK4wT8/Sus1g82AITI/AAAAAAAAAMM/adohFZLHgrI/s1600-h/testbox%5B3%5D.png" target="_blank"&gt;&lt;img title="testbox" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="79" alt="testbox" src="http://lh5.ggpht.com/__j-6QTK4wT8/Sus1hJRBwCI/AAAAAAAAAMQ/1Npc7FA7f9Q/testbox_thumb%5B1%5D.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;From there, you type in your test name. For example: “thisFunction_should_DoFancyThings” and hit Enter. This code gets added to your editor:&lt;/p&gt;

  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/__j-6QTK4wT8/Sus1hVPPQwI/AAAAAAAAAMU/slhRmniInDM/s1600-h/test_result%5B9%5D.png" target="_blank"&gt;&lt;img title="test_result" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="41" alt="test_result" src="http://lh3.ggpht.com/__j-6QTK4wT8/Sus1hrWNpTI/AAAAAAAAAMY/LaOpSvGlMEI/test_result_thumb%5B5%5D.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

  &lt;p&gt;Typing problem solved.&lt;/p&gt;

  &lt;h2&gt;The Bottom Line&lt;/h2&gt;

  &lt;p&gt;In the end, the fewer assertions you put into your tests&amp;#160; -- as opposed to fewer tests with more assertions -- the more descriptive, stable, and design-for-testability-helpful your tests will become. &lt;/p&gt;
&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-63499823402949091?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/63499823402949091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=63499823402949091' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/63499823402949091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/63499823402949091'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/how-many-assertions-in-my-tests.html' title='How Many Assertions in My Tests?'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-8332089753701976432</id><published>2009-10-29T20:54:00.001-04:00</published><updated>2009-10-29T21:00:45.492-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coldfusion'/><title type='text'>Looping over an array in CFScript</title><content type='html'>The other day, I was searching the cf9 docs for an equivalent of the &amp;lt;cfloop array=”#myarray#”&amp;gt; functionality introduced in CF8, and it appears that was not introduced. So it was back to ArrayLen() looping for me. Tonight, I saw TWiCF’s &lt;a href="http://twitter.com/MickyDionisio/statuses/5272881268" target="_blank"&gt;Micky Dionisio put this out on the Twitters&lt;/a&gt;, and I thought it was cool:   &lt;blockquote&gt;   &lt;p&gt;“#coldfusion 9 tip -grab a handle on the iterator of an array by calling someArray.iterator(). then u can use that in script FOR/WHILE loops!&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I never thought of that, so I wanted to give it a whirl.&lt;/p&gt;  &lt;pre class="cf" name="code"&gt;
&amp;lt;cfscript&amp;gt;
//pre-cf8
list = "one,two,three,four";
a = listToArray(list);
for(i=1; i LTE ArrayLen(a); i=i+1){
	writeoutput(a[i]);
}

//traditionally, with cf8+ syntax
a = ["one","two","three","four"];
for(i=1; i &amp;lt;= ArrayLen(a); i++){
	writeoutput(a[i]);
}

//with an iterator
//uncomment if you want to see what's available: writedump(a.iterator());
iter = a.iterator();
while(iter.hasNext()){
	el = iter.next();
	writeOutput(el);
}
&amp;lt;/cfscript&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Warning: don’t try to skip the iter = a.iterator() and el = iter.next() steps in an effort to save a few lines of code! If you try to loop while(a.iterator().hasNext()), you’ll get stuck in an endless loop because you’ll be returning a new iterator each time. And each time you call iter.next(), you’re advancing through the array; thus, doing writeOutput(iter.next()); doSomethingWithThisElement(iter.next()); will give you very different results from what you’re expecting. You’ve been warned.&lt;/p&gt;

&lt;p&gt;Thanks for the tip, Micky!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-8332089753701976432?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/8332089753701976432/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=8332089753701976432' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/8332089753701976432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/8332089753701976432'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/looping-over-array-in-cfscript.html' title='Looping over an array in CFScript'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-4752430132024817414</id><published>2009-10-29T09:00:00.000-04:00</published><updated>2009-10-29T09:00:15.196-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coldfusion'/><category scheme='http://www.blogger.com/atom/ns#' term='CFUnited'/><category scheme='http://www.blogger.com/atom/ns#' term='cfObjective'/><category scheme='http://www.blogger.com/atom/ns#' term='twicf'/><title type='text'>This Week in ColdFusion Episode #3</title><content type='html'>&lt;style&gt;#hidebr br {display:none}&lt;/style&gt;  &lt;div id="hidebr"&gt;   &lt;p&gt;I posted my &lt;a href="http://blog.mxunit.org/2009/10/this-week-in-coldfusion-episode-4.html" target="_blank"&gt;review of TWiCF episode #4 yesterday&lt;/a&gt;, and today on the drive home I listened to &lt;a href="http://www.twicf.com/2009/10/twicf-03-to-flex-or-not-to-flex/" target="_blank"&gt;episode #3&lt;/a&gt;. The first half of the episode was a discussion of conferences, since the episode was recorded at the same time that Adobe Max 2009 was underway; the second half focused on the question “To Flex or not to Flex”, which basically means “Should I spend my time learning Flex, or should I learn a rich javascript framework instead?”. Or, perhaps it also means “If I were building a project that required X, Y, and Z, what does Flex give me, and what does &amp;lt;insert fancy JS framework here&amp;gt; give me, and why should I choose one or the other for my project?”.&amp;#160; &lt;/p&gt;    &lt;h2&gt;Conferences&lt;/h2&gt;    &lt;p&gt;The line of inquiry for the first part was “Is it worth spending the money to go to a ColdFusion conference?” I can picture some listeners thinking, “What? Are you mad? That’s the stupidest question I’ve ever heard”. But I have to say: I think it’s a completely valid question. Mike brought up his experience with conferences and I think he describes a feeling that a lot of people encounter: that feeling of “I’m here to bask in the glory of the presenter”… to be talked to, to be lectured. To soak up their wisdom and be grateful for this brief glimpse of their brilliance. Lo, a star! &lt;/p&gt;    &lt;p&gt;I’d bet that more people than are willing to admit have had those &lt;a href="http://en.wikipedia.org/wiki/Stuart_Smalley" target="_blank"&gt;Stuart Smalley&lt;/a&gt; moments. “Am I worthy?” “Am I good enough to be here?” Perhaps. Perhaps not. Regardless, I can understand the sentiment.&lt;/p&gt;    &lt;p&gt;I want to say to the TWiCF guys – and to any listeners out there with whom those thoughts resonate – you will not find a more inclusive, caring, friendly, willing-to-engage community than the ColdFusion community. And I’m not just saying that as a guy who’s fairly outgoing. I attended cfObjective for the first time in 2008, and I was so grateful for the warmth and inclusion that I saw amongst people whom I consider heroes: Andy Powell, Simeon Bateman, Peter Bell, Brian Kotek, Bob Silverberg, etc. These people rock! And they love to talk about this stuff with people, no matter whether you’re a constant blogger or just a guy/girl who wants to learn some CF and possibly something beyond CF that maybe, just maybe, will become useful down the road. In fact, if I’m reading the pulse of these people correctly, I’d bet they’d be just as or more passionate about talking to people who &lt;strong&gt;really, really&lt;/strong&gt; want to engage than to some super-smart know-it-all blowhard. And you get these small, intimate BOF sessions where it’s you and a handful of super awesome people simply talking about a topic you’re all interested in. Seriously: how often do you get to sit in a room – as peers – with &lt;a href="http://www.barneyb.com" target="_blank"&gt;Barney Boisvert&lt;/a&gt;, &lt;a href="http://www.joshuafrankamp.com/blog/" target="_blank"&gt;Joshua Frankamp&lt;/a&gt;, &lt;a href="http://mate.asfusion.com/" target="_blank"&gt;Laura Arguello&lt;/a&gt;, &lt;a href="http://blog.demirkapi.net/" target="_blank"&gt;Oguz Demirkapi&lt;/a&gt;, &lt;a href="http://coldbox.org" target="_blank"&gt;Luis Majano&lt;/a&gt;, and no-names like me talking about Git in a session led by Peter and Sim? And it’s not because you’re a Git superstar, it’s because you just want to learn more about it face-to-face?&amp;#160; These are the reasons you pester your bosses to go to conferences.&lt;/p&gt;    &lt;p&gt;This year’s CFUnited was outstanding, as well. The content was superb. The speakers were everywhere. It’s so easy to spot a dude who you saw speaking a few hours earlier, walk up to them, and start firing questions. Interestingly enough: one of the strangest takeaways for me from CFUnited this year didn’t happen as a result of me sitting in a session or picking some speaker’s brain. Rather, it came from a conversation I had after &lt;a href="http://blog.mxunit.org/2009/08/cfunited-2009-automate-like-rock-star.html" target="_blank"&gt;my session on automation&lt;/a&gt; with &lt;a href="http://blogonria.com/page.cfm/about-me" target="_blank"&gt;Sumit Verma&lt;/a&gt;. He asked me if I had ever heard of a certain Windows command for working with Services, and I hadn’t. So I emailed him afterwards, we chatted, and now what I learned from Sumit – a guy who wasn’t speaking but who was in my session – has had a profound implication for something I’m doing at work right now. How sweet is that? Teachers and Students? Speaker and attendee? Nah. The blurrier that line, for me, the better. It’s people who know things interacting with people who know other things. That’s where magic happens.&lt;/p&gt;    &lt;p&gt;You always hear “You get out of it what you put into it”. It’s true. When you go to these conferences, try to engage. Walk up to people and say Hi. Even if you don’t like hanging out in the hotel bar, go sit down anyway. Order a coke. Eat peanuts. Whatever. Just open yourself up to people. When some funny-lookin’ bald dude says “yo, you wanna go hang out with us and smoke a stogie?”, say “yeah, sure”, even if you don’t smoke stogies. You don’t have to suck down a Cohiba! Grab your beer or your coke and you might be hanging out with Terry Ryan and Ryan Stewart and Adam Lehman, talking awesome stuff about what’s coming up in CF and the Flash Platform.&lt;/p&gt;    &lt;p&gt;Notice how I spent three paragraphs talking about stuff that wasn’t sessions?&amp;#160; If the value from 5 pm to 12:00 am is this good, imagine how good the stuff from 9 to 5 is! Brian said that for one of the conferences he attended, he was “required” to give a debriefing to his team when he returned to work. I can’t recommend this enough, for several reasons: &lt;/p&gt;    &lt;ol&gt;     &lt;li&gt;It encourages you to become a more active audience member. Rather than being a passive mouth-drooler, you’re more likely to at least take notes during sessions&lt;/li&gt;      &lt;li&gt;It provides you an opportunity to revisit the material afterwards. Consider: you’re going to go to one of these conferences, sit through 15-20 sessions, and no way will you remember it all. Going back through your notes – several times – gives you more time to think and interact with the material&lt;/li&gt;      &lt;li&gt;Your team members benefit from the time you spent at the conference. Surely it’s not the same as being there. But maybe something you say during your talk will inspire them to go check something out themselves (“What’s this CouchDB thing? Sounds interesting. I’m gonna go play with it”). Who knows, maybe you’ll present on something you learned at a conference, it’ll intrigue one of your team members, and you might collaborate on a small project down the road where previously you’d have going it alone.&lt;/li&gt;   &lt;/ol&gt;    &lt;p&gt;I strongly believe that if you attend either cfObjective or CFUnited in 2010, it will be worth your while. Each conference has a great variety of tracks: ColdFusion, Flex, Air, Project Management, etc. Each conference is run by people passionate about what they’re doing. Each conference brings in wonderful speakers. Each conference LOVEs to get new speakers (Brian Carr… I’m talking to you! Suck it up… we need solid presentations on real-world ReST with CF). &lt;/p&gt;    &lt;p&gt;The guys also discussed presentation formats other than the traditional “eyes forward” style. Dudes… &lt;a href="http://blog.mxunit.org/2009/08/cfunited-2009-part-i-big-picture.html" target="_blank"&gt;I hear you&lt;/a&gt;. I don’t know what CFUnited has in store for 2010, but I can say that the people behind cfObjective are taking this very, very seriously. This will be a shake-up year. This will be a year when &lt;strong&gt;engagement&lt;/strong&gt; is paramount.&lt;/p&gt;    &lt;h2&gt;XJS?&lt;/h2&gt;    &lt;p&gt;The whole way through the 2nd half of the episode, the guys talked about “XJS”. I was like “WTF is XJS?” Is this some new javascript framework I didn’t know about? They didn’t mention CF8 at all, so I wasn’t sure if they were talking about ExtJS, which is used for a lot of the CF8 Ajax widgetry. I was cornfused, as we say in Pennsyltucky. A look at the website shownotes afterwards cleared it up. They were talking about ExtJS. So my question is: How DO you pronounce it? Since I was introduced to EXT in 2007, I’ve always said “E-X-T”. Can I get a ruling from the line judge on how to pronounce this?&lt;/p&gt;    &lt;h2&gt;LCDS, push/pull, comet, and CF9&lt;/h2&gt;    &lt;p&gt;There are probably a dozen people in the world who haven’t been confused by “what is LiveCycle? what is LCDS? what is BlazeDS? What can you do with Flex and XXXDS? and with ColdFusion? What DS hoogie comes bundled with CF, and what are its license restrictions?”&amp;#160; I know I surely was confused by this. I think I have a handle on it now though. Bottom line: if you’re running CF8, and you want Push technology, you can use the “honor license” LCDS that comes bundled with CF8, and you can also use BlazeDS (free, open source). Apparently LCDS will scale beyond more than a few hundred simultaneous users, though I do not have confirmation or links for that. Also, I believe CF9 now comes bundled with BlazeDS, so you needn’t worry about licensing for your push/pull applications. In the real world, what this should mean is that you can drop messages into your Blaze-backed gateway, have them pushed out to all your Flex clients registered on that endpoint, and you’re good to go.&lt;/p&gt;    &lt;p&gt;If you’re creating a 20,000-user online Flex-based push/pull poker game, well, you’re probably looking at some LiveCycle Data Services licensing (note: this does NOT mean you’re spending 250k on a LiveCycle ES license. LiveCycle DataSevices != LiveCycle ES).&lt;/p&gt;    &lt;p&gt;If I’m one of the hapless masses&amp;#160; who is still putting out incorrect information, please, someone, set us all straight. &lt;/p&gt;    &lt;h2&gt;WAAAAAA, BOOOOOO&lt;/h2&gt;    &lt;p&gt;Mike started off the episode with a baby crying sound effect that almost caused me to wreck my car. Egads, man, that was too real. But funny nonetheless… pulled Brian right into that one. At the end, Mike pulled Micky into another gag, too, which I thought was pretty funny.&amp;#160; I hope Micky lets the air out of Mike’s tires.&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt;    &lt;h2&gt;Till Next Time…&lt;/h2&gt;    &lt;p&gt;Thanks again, gents, for enjoyable company on the commute home. Till next time…&lt;/p&gt;    &lt;p&gt;Marc, out&lt;/p&gt; &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-4752430132024817414?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/4752430132024817414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=4752430132024817414' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/4752430132024817414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/4752430132024817414'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/this-week-in-coldfusion-episode-3.html' title='This Week in ColdFusion Episode #3'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-1833617153772021105</id><published>2009-10-28T11:40:00.000-04:00</published><updated>2009-10-28T11:40:09.862-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cfeclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='webservices'/><category scheme='http://www.blogger.com/atom/ns#' term='twicf'/><title type='text'>This Week in ColdFusion Episode #4</title><content type='html'>&lt;style&gt;#main .post br {display:none}&lt;/style&gt;  &lt;h2&gt;The Skinny&lt;/h2&gt;&lt;p&gt;I commute about 45 miles each way from Pennsylvania to the Baltimore burbs. Generally, I am not a fan of this commute. However, as one who likes turning the proverbial lemons into lemonade, I’ve found that &lt;a href="http://blog.mxunit.org/2008/10/ot-podiobooks.html" target="_blank"&gt;podiobooks&lt;/a&gt; and podcasts are a great way to spend the 90+ minutes a day in the car. I try out all different kinds of podcasts, and more often than not I delete them from my iTunes after a few episodes. With the new TWiCF podcast, I think I’ve found a keeper.&lt;/p&gt;&lt;p&gt;Episode 4 of This Week in ColdFusion (&lt;a href="http://www.twicf.com/" target="_blank"&gt;TWiCF&lt;/a&gt;) was released on October 19. I had seen mention of this new CF podcast a few weeks back, and it came across my radar today, when I was in front of the computer with easy access to iTunes. So I subscribed and listened to this latest episode on commute home from work.&lt;/p&gt;&lt;p&gt;In short, I like it! It’s relatively quick paced, the guys have good podcast voices, and the content is fun and informative. &lt;/p&gt;&lt;p&gt;While listening, however, I wished I had a good way to take notes because I wanted to speak to a few items. Rather than hijack their comments thread, I figured I’d use this blog instead. Beats hearing about unit testing, don’t it?&lt;/p&gt;&lt;p&gt;Without further adieu, some points I’d like to make:&lt;/p&gt;&lt;h2&gt;ColdFusion Builder Pricing&lt;/h2&gt;&lt;p&gt;Where did Mike get that $250 number? I have it on good sources from my inside-Adobe operatives that the price is somewhere between “We ain’t telling you” and “STFU and quit asking”. (My quotes). So, please, don’t believe any numbers anyone says about CFB until you hear it from CFB’s PM, Adam Lehman. &lt;/p&gt;&lt;h2&gt;Debugging in Eclipse&lt;/h2&gt;&lt;p&gt;Let there be no question: you can use Eclipse, right now, for free, and do step debugging on your CFML. Provided you’re running CF8, all you need is the &lt;a href="http://www.adobe.com/support/coldfusion/downloads.html" target="_blank"&gt;ColdFusion 8.01 Eclipse extensions&lt;/a&gt;. Once installed, it’s a matter of a 2-minute setup and then off you go. For an outstanding introduction to using the debugger, see &lt;a href="http://experts.na3.acrobat.com/p43721539/" target="_blank"&gt;Charlie Arehart’s CFMeetup&lt;/a&gt; presentation. While I’m at it… check UGTV often. It’s a veritable gold mine of CF content.&lt;/p&gt;&lt;p&gt;You can set “watchpoints” as well so you don’t have to scroll through gazillions of variables. I will say, though, that I personally hate being in a debugger. I figure if I’m in a step debugger, then either my app is to complicated or my unit tests are not helping me. Just sayin’ is all.&lt;/p&gt;&lt;p&gt;So, key words: CF8, Eclipse, Free, Easy.&lt;/p&gt;&lt;h2&gt;Full CFScript and CFEclipse&lt;/h2&gt;&lt;p&gt;The guys talked a bit about the enhanced cfscript support in CF9. In particular, the fact that you can write components without any tags at all:&lt;/p&gt;&lt;pre class="cf" name="code"&gt;component {
 public Order function init(required numeric id, array items = ArrayNew(1), String shippingMode=&amp;quot;StandardShipping&amp;quot; ){
  StructAppend(variables,arguments);
  return this;
 }

 public void function dumpVars(){
  writeDump(variables);
 }
}&lt;/pre&gt;&lt;p&gt;The problem in CFEclipse, as they mentioned, is that these files look like you’re editing in notepad when you open them in CFE. Good point, guys. I’ve emailed the CFE dev group to see what the level of effort would be to get the syntax highlighting working correctly.&lt;/p&gt;&lt;h2&gt;Snippets WishList&lt;/h2&gt;&lt;p&gt;One of the guys – I think it was Micky – mentioned a feature he’d like to see in Snippets, based on his work with Visual Studio. Essentially, he described the ability to type a trigger, and then have the cursor “follow” you as you “tab through” so you could type in what you wanted to type. I believe the Eclipse equivalent of this is functionality called “Templates”. Before I talk about templates and CFEclipse, though, let’s talk about what you get with the Snippets that already exist. &lt;/p&gt;&lt;p&gt;You can already get this behavior, or at least a “pretty good” version, in snippets as they’re currently implemented. I’ve found that for the (way too few) people who use snippets, this is something they don’t know about. I’m talking about “Variables”, and they are the cats pajamas. I wrote about this a while back, so I encourage you to &lt;a href="http://blog.mxunit.org/2009/04/timesavers-cfeclipse-snippets.html" target="_blank"&gt;spend 10 minutes sharpening the saw to save yourself hours cutting&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Now, onto Templates. Fortunately, Denny Valliant recently added an initial implementation of this feature into CFEclipse. Unfortunately, the CFEclipse team didn’t publicize it at all and so no one really knows about it. So it’s time to talk about them. Please &lt;a href="http://blog.mxunit.org/2009/10/new-in-cfeclipse-templates.html" target="_blank"&gt;read this post&lt;/a&gt; to learn about this sweet new feature with lots of potential for time-saving awesomeness.&lt;/p&gt;&lt;h2&gt;The REST Discussion&lt;/h2&gt;&lt;p&gt;I thoroughly enjoyed this part of the show. I’d like to see Brian give a presentation – with loads of examples, in particular from the Producer point of view – on designing and publishing REST-ful services. It’s easy to consume them… but how about architecting an application that produces the services? What strategies exist? What tools/frameworks? What big problems have you encountered? What if I want to do something more than just delete User 5? Instead I want to place an order for 13 copies of 5 different books and have them all mailed to my relatives in the 4 corners of the globe (OK, extreme, but you get the picture… simple scenarios = suck… I want more depth)?&amp;#160; What do you say, Brian?&lt;/p&gt;&lt;p&gt;Oh… and how do you unit test them? This is a blog with “unit” in its name, so I’d be remiss If I didn’t mention that.&lt;/p&gt;&lt;h2&gt;What was Missing?&lt;/h2&gt;&lt;p&gt;What was missing from the This Week in ColdFusion Podcast, Episode #4? Why… “this week in ColdFusion”, of course. I guess when I started listening, I was expecting more of a TWiT format, or perhaps at least more newscasty-ness to it. It is entitled, after all, “This week in…”. Consequently I expected more news items. I’d really like to have at least some time during the newscast devoted to keeping we CFMLers up to date on what’s happening in the community. News items, new projects, interesting blog posts, etc. Personally, I rely heavily on the Java Posse podcast to keep me up to date on all the things in the Java and Scala world that I don’t have time to investigate myself. Adding more news-i-ness into the TWiCF podcast would be a huge win for me.&lt;/p&gt;&lt;h2&gt;&lt;/h2&gt;&lt;h2&gt;Till Next Time…&lt;/h2&gt;&lt;p&gt;Again, it’s encouraging to see another CF Podcast, especially one that appears to have a lot of promise. I hope Mike, Micky, and Brian can keep it up. I can only imagine how grueling it must be to produce a podcast, so kudos to &lt;a href="http://cfconversations.com" target="_blank"&gt;all members&lt;/a&gt; of &lt;a href="http://cfhour.com" target="_blank"&gt;our community&lt;/a&gt; who &lt;a href="http://riapodcast.com" target="_blank"&gt;devote their time&lt;/a&gt; to such endeavors. &lt;/p&gt;&lt;p&gt;I hope each episode is engaging enough to make me want to come home and write a review / response like this one.&lt;/p&gt;&lt;p&gt;Marc, out.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-1833617153772021105?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/1833617153772021105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=1833617153772021105' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/1833617153772021105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/1833617153772021105'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/this-week-in-coldfusion-episode-4.html' title='This Week in ColdFusion Episode #4'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-281405878732524552</id><published>2009-10-28T11:37:00.001-04:00</published><updated>2009-10-28T11:38:16.243-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cfeclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='timesavers'/><title type='text'>New in CFEclipse: Templates</title><content type='html'>&lt;div class="note"&gt;This is part of an ongoing series on &lt;a href="http://blog.mxunit.org/search/label/timesavers"&gt;Timesavers&lt;/a&gt;. The goal is simple: short, easily-digestible posts designed to help developers get faster and more productive &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The recent 4th episode of &lt;a href="http://twicf.com" target="_blank"&gt;This Week in ColdFusion&lt;/a&gt; inspired me to finally get the word out there regarding this sweet new feature of CFEclipse: Templates. This has been in CFEclipse since June, but we never advertised it or blogged about it. If you’re a java developer who uses Eclipse, you probably rely on templates so heavily that you’d think they were just baked right into the IDE. You know how when you’re editing java, and you type “for”, and it pops up a bunch of suggestions? That’s what this is.&lt;/p&gt;  &lt;p&gt;Denny Valliant’s initial implementation only came with two default templates, though I suspect more will come down the road. It’s easy to write your own, though, and here’s how:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Window – Preferences – CFEclipse – Editor – Templates &lt;/li&gt;    &lt;li&gt;In the Templates window, hit “Add New” &lt;/li&gt;    &lt;li&gt;Type in a name, a description, and your templates. You can use “Variables” by using ${} syntax, and the contents in between the brackets can be any arbitrary name. Trust me, you’ll see how this works in a minute &lt;/li&gt;    &lt;li&gt;If you want custom stuff – like where to put the cursor or some other “standard” variables, you can insert them with the dropdown list &lt;/li&gt;    &lt;li&gt;Hit OK and get out of the preferences window. The window looks like this: &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/__j-6QTK4wT8/SuhlNkuYr0I/AAAAAAAAALs/BJAwqsfqsLg/s1600-h/cfe_templates_1%5B6%5D.png" target="_blank"&gt;&lt;img title="cfe_templates_1" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="197" alt="cfe_templates_1" src="http://lh5.ggpht.com/__j-6QTK4wT8/SuhlNzlVmiI/AAAAAAAAALw/tGvwH7zvdb4/cfe_templates_1_thumb%5B2%5D.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now, in your editor, I created a new array, went down a line, and started typing the characters that begin with my new template name. For example, in my screenshot, I had a template named “looparray”, and so I started typing “loop”, and in my editor, that template appeared:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/__j-6QTK4wT8/SuhlOJQr95I/AAAAAAAAAL0/8yN6lPjqIf0/s1600-h/cfe_templates_2%5B2%5D.png" target="_blank"&gt;&lt;img title="cfe_templates_2" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="197" alt="cfe_templates_2" src="http://lh6.ggpht.com/__j-6QTK4wT8/SuhlOR28M2I/AAAAAAAAAL4/eXbuM1Mir2E/cfe_templates_2_thumb.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I hit “Enter” to accept the template, and now I’m in the template, and with each tab, I’ll move on to the next part of the template.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/__j-6QTK4wT8/SuhlOi5fTkI/AAAAAAAAAL8/49boKpowL2Y/s1600-h/cfe_templates_3%5B2%5D.png" target="_blank"&gt;&lt;img title="cfe_templates_3" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="197" alt="cfe_templates_3" src="http://lh4.ggpht.com/__j-6QTK4wT8/SuhlO9H4csI/AAAAAAAAAMA/x7USBM2dnOU/cfe_templates_3_thumb.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In this example, I have an array named “stogies”, so I tell my template that my array is named “stogies”, and it replaces my “template variable”. I want my index variable to be named “stogie”, so I type that in, and it replaces it in the cfloop tag AND in the block of code that followed.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/__j-6QTK4wT8/SuhlPHrxt6I/AAAAAAAAAME/TzmkIGyTR50/s1600-h/cfe_templates_4%5B2%5D.png" target="_blank"&gt;&lt;img title="cfe_templates_4" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="197" alt="cfe_templates_4" src="http://lh3.ggpht.com/__j-6QTK4wT8/SuhlPYUxPvI/AAAAAAAAAMI/Qd1DNmgpDaI/cfe_templates_4_thumb.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This can save you a lot time right now, for free. This has the potential to be a huge timesaver, especially if developers write their own templates and share them with the community via the “export” functionality.&amp;#160; Hopefully, as the CFEclipse developers get more time, more templates will come bundled with CFEclipse.&lt;/p&gt;  &lt;p&gt;Viva la TimeSavers!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-281405878732524552?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/281405878732524552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=281405878732524552' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/281405878732524552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/281405878732524552'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/new-in-cfeclipse-templates.html' title='New in CFEclipse: Templates'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-5402949045237852361</id><published>2009-10-28T06:47:00.003-04:00</published><updated>2009-10-28T09:19:12.708-04:00</updated><title type='text'>Stackoverflow Dev Days D.C. 2009 Review</title><content type='html'>At $99 and just down the street, it was hard not to go. The &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.thestatetheatre.com%2Findex.xml&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzfcjmENDOpFBBIY0ZHndVMwR9j7XA"&gt;State Theatre&lt;/a&gt; is a very cool venue, a restored old theatre turned into Rock club. In Falls Church, VA, my wife's home town, it was just about as close as close could be for me. I sat front row like I was at concert or something, and, as I was reading Twitter on my G1, I noted a tweet by Liz Frederick from Adobe who was also at Dev Days and sitting right behind me. Cool! It was nice to meet her, we had a pleasant chat, and I learned some things about how Adobe is reaching out to developers. &lt;b&gt;&lt;br /&gt;
&lt;br /&gt;
Executive Summary&lt;/b&gt;: It was totally worth it for this local guy. I left wanting to buy a Mac, do iPhone development, manage my projects with FogBugz 7 (and figure out WTF bayesian statistics are), get more serious with Python, finish my Google App Engine projects, and front end all my web apps with jQuery. I met some super smart, nice, interesting people, had a good time, and left inspired. One cool thing was that most of the speakers were local folks. Not sure about Bruce Eckel, but the others were all from the general D.C. area. I think this was a good thing to do for everyone involved - the conference, the attendees, the speakers, and the community. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_R-2JPB8crqk/SugZ2rTzWRI/AAAAAAAAAQo/yOpM41pvTKY/s1600-h/2009-10-26+13.24.13.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_R-2JPB8crqk/SugZ2rTzWRI/AAAAAAAAAQo/yOpM41pvTKY/s320/2009-10-26+13.24.13.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Here're my notes:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Joel Spolsky Opening Keynote&lt;/b&gt; - Great warm up video - I got a real good laugh right off the bat. Great slides. Joel is a skilled and entertaining presenter. Joel's keynote was about Simplicity vs. Features, with specific emphasis on usability. Spend that extra time doing things &lt;i&gt;for&lt;/i&gt; the user. Don't interrupt them for stuff your app should be doing. Dialogue Boxes == bad. User's don't care how much work you did to make the app; be humble enough not to show off your effort. Hide the details of how it was built. Get out of the way and strive for elegance. &lt;i&gt;Elegance always looks like it should be more than it is&lt;/i&gt;. He showed some an example Python spell check app that I remember seeing earlier this year - it was like 150 lines of code or something - spell checking in 150 lines?! Elegance. I get it. Thx.&lt;br /&gt;
&lt;br /&gt;
Oh... here's a grin. I'm sitting in the front row and Joel is making a point about usability and he points to me and says, "Pick a gender!" ... huh? Me? ... "Yeah. Just say 'male' or 'female'" Me: "uh ... male". Then he goes into a story about "Bill" who's having an affair with his secretary who wants to blackmail him for $100K while Bill's wife is walking down the hall getting ready to bust them and Bill needs to cut a $100K check with QuickBooks but doesn't have the time to answer the stupid dialogue about upgrading the software because Bill's wife is about to open the door on the two lovers. Then Joel must have realized my name just might be Bill, so he asks, "Is your name, Bill?". Well, yeah, not that you could read my scribbled name tag in a dark room from 20 feet away ... But Joel's a pro and rolls with it no problem. I wasn't bothered by any of this at all, by the way. I was stoked to be out of the office around smart people.&amp;nbsp; I guess he remembered me later, because again he gestured towards me and used "Bill" to exemplify an idea. Ok, now if I can just figure out how to get some cool product &lt;i&gt;front row&lt;/i&gt; to buyers ... &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Dan Pilone : iPhone&lt;/b&gt;&amp;nbsp; - Dan says Objective C is not as bad as people say. It takes Apple 2 weeks to approve/disapprove an app, and they will test it and make sure it complies with rules and regulations. Even if it's been approved for release 1 and they missed something, like a minor licensing violation, it can get kicked out again in future releases. In short, you need to plan on this 2 weeks and dot your T's. There's money to be made but you have a short window of time to grab it and leverage the Apple store presence. There's a boat load of iPhone customers, so, lots of opportunity, but also lots of competition (like 100K apps in the iPhone Store) and it's growing rapidly. You can do the $0.99 app, which needs volume sales to succeed, of course, or your can go with the $20 app, which has less sales but might be more stable.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Scott Allen ASP.NET-MVC&lt;/b&gt; - Scott is clearly a great coder. Anyone who can write code on stage in front of 200-300 of probably the smartest developers in D.C. and beyond gets a big hand from me. This is me holding up my lighter for an encore - more! I don't code in C#/.NET but if I get the opportunity, I can only hope to be as skilled as Scott. And I will go right towards the MVC framework he described. One thing I personally would have liked to see, which he mentioned, was unit testing. Apparently, MVC generates test stubs and allows you to test in some interesting ways, like, defining a "context". I'll need to look into it, but I sensed an interesting approach to testing. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Joel Spolsky on Fogbugz&lt;/b&gt; &lt;b&gt;7&lt;/b&gt; - I had no idea it did all those things - much much more than issue tracking. Evidence based scheduling ... bayesian something or other statistical intelligent learning (like I have any idea) with cool graphs ... wow. They're integrating their own version of Mercurial, too, which looks like Git from the command line, and it integrates well into FogBugz with code review capabilities and task management. Having an enterprise tool like this available where I don't have to administer it, just makes sense. I'd rather focus on getting my project organized and tasks completed vs. that AND learning to administer the beast. The usability that was emphasized in FogBugz is very attractive. Joel said he wants it to be as easy to enter tasks as typing in Notepad, and he have some good demonstrations. It also supports and seems to be geared towards Scrum. &lt;br /&gt;
&lt;br /&gt;
I also "got" the idea of Stack Exchange as a way to capture domain specific knowledge. Joel's view is that the corporate wiki can fail because it's document centric and experts don't really want to write documents nobody reads. However, with a question-based environment, like Stack Exchange, specific questions can be answered and aggregated into a knowledge base. I like that idea. It's more like pull rather than push.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Lunch&lt;/b&gt; - Cheap box lunch &amp;amp; fine by me. Groups for various discussions were set up during lunch - agile, free software, start ups, etc... I wanted some sunshine and the seating did not really lend itself to round table discussions, for me. So, I sat outside in the sun, walked around the block, and talked with a PHP developer from Chicago on the corner of Washington Blvd.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
Bruce Eckel Python&lt;/b&gt; - Bruce talked about why Python makes sense and how the language develops vs. how Java/C/C++ evolved. Basically, it can do what Java/C/C++ do but with a lot less effort and do it dynamically. Also, the fact the Python is community driven and not the product of a company, makes it an appealing choice. He's working on a version on Thinking in Python, only it's under a different title. The interesting thing about this book is that it will be community driven. It sounds like an interesting idea. &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://4.bp.blogspot.com/_R-2JPB8crqk/SugaAS6wgeI/AAAAAAAAAQw/GL6oEJe1g-I/s1600-h/2009-10-26+14.33.44.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_R-2JPB8crqk/SugaAS6wgeI/AAAAAAAAAQw/GL6oEJe1g-I/s320/2009-10-26+14.33.44.jpg" /&gt;&lt;/a&gt;Bruce is a forward thinker, to say the least, and when pinged he talked in abstract terms about what he sees as part of the future - human computer interaction and machine symbiosis. Not in a &lt;i&gt;sci-fi machines taking over the world&lt;/i&gt; kinda way, but we are clearly dependent on machines today, and the future will be focusing on how this interface grows. I agree. Typing a keyboard is one weird way to communicate for a human. Speaking and audio with visual cues is how we, as humans, do it. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;i&gt;I think that might be Mr. Hankey's brother hugging the python&lt;/i&gt;.&lt;/span&gt;&lt;b&gt; &lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The last time I heard Bruce was in 1998 at my first ever tech conference - SD '98. I worked as a volunteer so I could get free admission and one of my assignments was to support Bruce's &lt;i&gt;Thinking in Java&lt;/i&gt; talk. I was so excited at the time when he said, "Hey, can someone go get some audio tech help?" I was on it, man ;-)&amp;nbsp; &amp;nbsp; &lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Jonathan Blocksom Google App Engine&lt;/b&gt;&amp;nbsp; - I think everyone could identify with Jonathans' down-to-earth style. As humble as he was, it was clear to me that he is very smart ... Google smart. This was the one topic that was a review for me. I had covered all this with some App Engine prototypes I did over the Summer. But Jonathan discussed the AppEngine architecture, quota/pricing model, and how to get up and running. It was very cool that Jonathan could do an entire talk about distributed applications and not once use the term "Cloud". Good job. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Richard D. Worth&lt;/b&gt; , &lt;b&gt;JQuery&lt;/b&gt; - A very well organized and detailed presentation. One of the main things I took away was a simple phrase about JQuery architecture: "Find Something, and Do Stuff". I love JQuery and it's been my goto for about a year, yet I never saw it like that. But it makes perfect sense. Richard clearly is passionate about JQuery and is willing to teach. He just created a poll (Poll Daddy) for a 1 or 2 day JQuery talk in D.C. in Nove,ber or December, so, keep an eye out. It will be well worth it. I'll be there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Wrap up&lt;/b&gt;: There were a lot of people who flew in from out of town and came from more than an hour away. I felt fortunate that I could wake up and drive 20-30 minutes to do a cool 1-day conference. What strikes most about this, and it's not Dev Days specific, but it's about the concept of a cheap 1-day event that's on the road, vs. a multi day conference in some place like Vegas. I kinda like the idea of 1-day, but I'm not sure if I would do a road trip for just 1 day, maybe that's what surprised me about the number of folks from out of town. I spoke with a PHP developer who flew in from Chicago. I also connected with a Python developer originally from Northern Ireland and living in Philly. Chatting with Liz Frederick from Adobe was also a breath of fresh air. So, for this developer, getting out is important. But for me,I question whether or not the multi-day big events with evening schmooz-fests are the best environment for learning. They're fun, for sure, but I sense a better way to learn new stuff ...&lt;br /&gt;
&lt;br /&gt;
It's funny, but I posed this question on Stakoverflow ... whether or not micro conferences like Dev Days are a good place to do peer-2-peer learning, and the Stackoverflow zealots quickly shut my question down, closed it, as "Non Programming Related". Whatever... So, I'll ask it here: How do you learn best and grow, and what inspires you?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-5402949045237852361?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/5402949045237852361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=5402949045237852361' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/5402949045237852361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/5402949045237852361'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/stackoverflow-dev-days-dc-2009-review.html' title='Stackoverflow Dev Days D.C. 2009 Review'/><author><name>bill shelton</name><uri>http://www.blogger.com/profile/06624894387927690246</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17359140296736057249'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_R-2JPB8crqk/SugZ2rTzWRI/AAAAAAAAAQo/yOpM41pvTKY/s72-c/2009-10-26+13.24.13.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-4607002309335696671</id><published>2009-10-25T03:24:00.046-04:00</published><updated>2009-10-25T03:59:28.973-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MongoDB'/><title type='text'>“Look, Ma. No SQL!” – MongoDB and ColdFusion Part 3</title><content type='html'>&lt;b&gt;Querying MongoDB documents with JavaScript and ColdFusion&lt;/b&gt;  &lt;br /&gt;
&lt;br /&gt;
In the &lt;a href="http://blog.mxunit.org/2009/10/look-ma-no-sql-mongodb-and-coldfusion.html"&gt;first part&lt;/a&gt; of this series I presented my fundamental attraction to MongoDB, and in the &lt;a href="http://blog.mxunit.org/2009/10/look-ma-no-sql-mongodb-and-coldfusion_20.html"&gt;last post&lt;/a&gt; I talked a bit about some of MongoDB's core concepts. In this part, I'll explore some approaches, challenges and a proposal for reading data stored in MongoDB.&amp;nbsp; The &lt;a href="http://github.com/virtix/cfmongodb"&gt;source code&lt;/a&gt; (still in a proof of concept state) is available at Github - feel free to fork it and make comments.   &lt;br /&gt;
&lt;br /&gt;
MongoDB's data is persisted as binary form of JSON (BSON) and the admin engine language is JavaScript. (We'll get to ColdFusion shortly) Let's work with the Blog document structure - JSON- presented in Part 1:   &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;{ "_id" :&amp;nbsp; ObjectId( "65c5b8782745e04afc2abf00"), 
&amp;nbsp; "AUTHOR" : "bill_1" , 
&amp;nbsp; "TAGS" : ["Comics","Games","Python","NoSQL","Ruby"] , 
&amp;nbsp; "PUB_DATE" : "Thu Oct 22 2009 07:42:19 GMT-0400 (EDT)" 
&amp;nbsp; "BODY" : "Lorem ipsum dolor sit amet ..." , 
&amp;nbsp; "TS" : 1256177399955 , 
&amp;nbsp; "TITLE" : "Blog Title No.1 ..." 
}; 
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The &lt;a href="https://gist.github.com/fd9d3fc91e13db58de06"&gt;example code&lt;/a&gt; generates 1000 such documents. Imagine 1000 items with the author and title values incremented for each one from 0-999. &lt;br /&gt;
&lt;br /&gt;
From MongoDB's admin console, you can query this structure like this: &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;&amp;gt; db.blog.find()&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
... which returns &lt;i&gt;all&lt;/i&gt; the documents in the blog collection and is semantically equivalent to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;select * from blog&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
Here's some other basic examples for querying the blog collection. This should give you a feel for how to get data back from MongoDB: &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Retrieve a blog entry by ID&lt;/b&gt;: &lt;br /&gt;
SQL: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;select * from blog where id = '65c5b8782745e04afc2abf00'&lt;/span&gt; &lt;br /&gt;
MongoDB: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;db.blog.find( {_id: ObjectId( "65c5b8782745e04afc2abf00")} )&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Retrieve 10 of the most recent titles&lt;/b&gt;: &lt;br /&gt;
SQL: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;select top 10 * from blog order by pub_date desc&lt;/span&gt; &lt;br /&gt;
MongoDB: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;db.blog.find().sort( {PUB_DATE:-1} ).limit(10)&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Retrieve 10 entries by a given author&lt;/b&gt;: &lt;br /&gt;
SQL: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;select top 10 * from blog where author = 'bill_1'&lt;/span&gt; &lt;br /&gt;
MongoDB: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;db.blog.find( {author: 'bill_1'} ).limit(10)&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To retrieve data from MongoDB you use JavaScript and object notation. An interesting point is the syntax for search criteria. The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;find(...)&lt;/span&gt; method expects a JavaScript object with the criteria; e.g., &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;{author: 'bill_1'}&lt;/span&gt;. For basic equality checks you pass in the name of the field you're searching and the value. To do comparative tests you can use the syntax:&amp;nbsp; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;db.collection.find( { "field" : { $gt: value } } ) &lt;/span&gt;for greater than. There's almost a full range of operators available, including full regular expression searches - &lt;i&gt;Wahoo!&lt;/i&gt; Take a quick peak at the docs and come back ... &lt;a href="http://www.mongodb.org/display/DOCS/Advanced+Queries"&gt;http://www.mongodb.org/display/DOCS/Advanced+Queries&lt;/a&gt; . What do you think? That's the command line shell. Very cool. But how can we do that in a ColdFusion webapp? At the root, you wrap ColdFusion around the Java client: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cf" name="code"&gt;//setup - no necessary for every search 
//create a mongo instance 
mongo = createObject('java', 'com.mongodb.Mongo').init( server_name , server_port ); 
//get a handle to the database 
db = mongo.getDb(db_name); 
//get or create a collection (e.g., Blog)&amp;nbsp;&amp;nbsp; 
collection = db.getCollection(collection_name); 

//build search criteria 
criteria = createObject('java', 'com.mongodb.BasicDBObject').init('TITLE','bill_1.*'); //regular expression 
//execute search 
results = collection.find(criteria); 
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
It's helpful to note that the primary interface for both writing data and querying data is &lt;a href="http://api.mongodb.org/java/0.11/com/mongodb/DBObject.html"&gt;com.mongodb.DBObject&lt;/a&gt;. This extends java.util.HashMap and represents a map of name value pairs that are saved to the datastore and &lt;i&gt;also&lt;/i&gt; used as search criteria. In the example above note that you create a BasicDBObject with a name and value. This object is to the find method and used to query the datastor. &lt;br /&gt;
&lt;br /&gt;
As for the syntax, I'd prefer something different. So, I here’s my attempt at a &lt;a href="http://martinfowler.com/bliki/DomainSpecificLanguage.html"&gt;DSL&lt;/a&gt; in ColdFusion which looks like this: &lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;results = mongo.collection('blog').startsWith('TITLE','Blog Title No.60').search();  &lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
This returns all documents whose title starts with the second argument. This is semantically the same as &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;select * from blog where title LIKE ‘Blog Title No.60%'&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
For other string related criteria there’s also &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;endsWith(field,value), exists(field,value), regex(field,expression) &lt;/span&gt;and others. Since this is a DSL we can chain these together to better express a search:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;results = mongo.collection(‘blog’).&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exists(‘BODY, ‘MongoDB’).&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eq(‘AUTHOR’, ‘bill’).&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; after(‘PUB_DATE’,’09/12/2009’).&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; search();&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
This is asking for all the &lt;i&gt;blog entries &lt;/i&gt;by &lt;i&gt;bill&lt;/i&gt; that were posted after &lt;i&gt;September 12, 2009&lt;/i&gt;, with &lt;i&gt;Mongo&lt;/i&gt; in the body. Now, &lt;b&gt;I&lt;/b&gt; think this is clear, but maybe you don’t. That’s cool.&amp;nbsp; Here’s the proposed syntax. Again, this is all a proof of concept, so feel free to comment. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &lt;b&gt;Proposed DSL for MongoDB searches&lt;/b&gt;:&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;pre class="cf" name="code"&gt;&amp;nbsp; results =  mongo.collection('blog').&amp;nbsp;&amp;nbsp; //optionally set the collection to search, otherwise it will use current collection 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; startsWith('name','foo').&amp;nbsp;  //string 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; endsWith('title','bar').&amp;nbsp;&amp;nbsp;  //string 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exists('field','value').&amp;nbsp;&amp;nbsp;  //string 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; regex('field','value').&amp;nbsp;&amp;nbsp;&amp;nbsp;  //string 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; before('field', 'value').&amp;nbsp;  //date 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; after('field', 'value').&amp;nbsp;&amp;nbsp;  //date 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $eq('field','value').&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  //numeric 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $gt('field','value').&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  //numeric 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $gte('field','value').&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  //numeric 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $lte('field','value').&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  //numeric 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $in('field','value').&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  //array 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $nin('field','value').&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  //array 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; search('title,author,date', limit); 

Proposed:&amp;nbsp;&amp;nbsp;&amp;nbsp; search( keys=list_of_keys_to_return, limit=num, start=num, sort={field=direction} );&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The string and date searches all work as expected, but there are issues with the numerics and the conversion from ColdFusion to Java representations. Numeric comparisons need to support &lt;i&gt;all&lt;/i&gt; numeric types. The numeric comparison methods are all prefixes with $. This is done to match the MongoDB JavaScript syntax and to get around ColdFusion's reserved keywords. The array searches have been proven, but need work.&lt;br /&gt;
&lt;br /&gt;
One last goodie:&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt; $where(…)&lt;/span&gt; : You can also do adhoc queries with JavaScript like so:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;results = mongo.collection(‘blog’).$where( ‘this.TITLE == ‘Blog Title No.1 || this.AUTHOR == ‘bill’ ’).search(); &lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Important notes:&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt; When using $where, you must prefix the item you are seaching for with 'this', which corresponds to the current collection.&lt;/li&gt;
&lt;li&gt;MongoDB mentions that there is a greater perfomance demand for $where &lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Searches are &lt;i&gt;case sensitive&lt;/i&gt;. This may throw some folks, but it might help to think in terms of JavaScript, which is case sensitive.&lt;/li&gt;
&lt;li&gt;Case sensitivity applies to both keys and values. And note, too, that ColdFusion creates uppercase keys when creating structs, unless you create the struct using this syntax: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,courier,monospace;"&gt;my_struct["my_key"] = my_value&lt;/span&gt;; &lt;/li&gt;
&lt;li&gt;There is no built in boolean OR, yet, except in $where&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Feedback is welcome, of course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Up Next: Storing Blobs, Indexes, Admin 101&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test and be Happy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-4607002309335696671?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/4607002309335696671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=4607002309335696671' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/4607002309335696671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/4607002309335696671'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/look-ma-no-sql-mongodb-and-coldfusion_25.html' title='“Look, Ma. No SQL!” – MongoDB and ColdFusion Part 3'/><author><name>bill shelton</name><uri>http://www.blogger.com/profile/06624894387927690246</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17359140296736057249'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-5341556223130023209</id><published>2009-10-23T20:35:00.003-04:00</published><updated>2009-10-23T20:40:39.326-04:00</updated><title type='text'>RESOLVED: VMWare 6.5.x Stopped Working on Ubuntu 9.04</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;b&gt;Symptoms&lt;/b&gt; first occured after upgrading from 8.10 to 9.04 and included:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Start VMWare Workstation from menu: Nothing appears to happen. No errors.&amp;nbsp; &lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Start VMWare Workstation from command line and get the following error&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;pre style="font-family: Courier New;"&gt;billy@mxunit-ubuntu:~$ sudo /usr/bin/vmware
Logging to /tmp/vmware-root/setup-25257.log
modinfo: could not find module vmmon&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
modinfo: could not find module vmnet&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
modinfo: could not find module vmblock&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
modinfo: could not find module vmci&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
modinfo: could not find module vsock&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
modinfo: could not find module vmmon&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
modinfo: could not find module vmnet&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
modinfo: could not find module vmblock&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
modinfo: could not find module vmci&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
modinfo: could not find module vsock&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
/usr/bin/vmware: line 31: 25257 Segmentation fault&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "$BINDIR"/vmware-modconfig --appname="VMware Workstation" --icon="vmware-workstation"&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Resolution&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="font-family: Courier New;"&gt;billy@mxunit-ubuntu:~$sudo mv /usr/lib/vmware/modules/binary /usr/lib/vmware/modules/binary.old
billy@mxunit-ubuntu:~$sudo vmware
&lt;/pre&gt;Solution from : &lt;a href="http://ubuntuforums.org/archive/index.php/t-1212220.html"&gt;http://ubuntuforums.org/archive/index.php/t-1212220.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="zemanta-pixie"&gt;&lt;img alt="" class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=3757ce78-0eb6-8895-9923-7456a8df4327" /&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-5341556223130023209?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/5341556223130023209/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=5341556223130023209' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/5341556223130023209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/5341556223130023209'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/resolved-vmware-65x-stopped-working-on.html' title='RESOLVED: VMWare 6.5.x Stopped Working on Ubuntu 9.04'/><author><name>bill shelton</name><uri>http://www.blogger.com/profile/06624894387927690246</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17359140296736057249'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-6213693682341677982</id><published>2009-10-20T10:17:00.008-04:00</published><updated>2009-10-27T13:51:36.961-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MongoDB'/><title type='text'>"Look, Ma. No SQL!" - MongoDB and ColdFusion - Part 2</title><content type='html'>&lt;b&gt;MongoDB Core Concepts&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In the &lt;a href="http://blog.mxunit.org/2009/10/look-ma-no-sql-mongodb-and-coldfusion.html"&gt;last post&lt;/a&gt;, I started to scratch the surface of &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEze0DS5nVnFCXSH6TazTUvDuGoHzHg"&gt;MongoDB&lt;/a&gt; and focused on some of its efficiencies. I mentioned that querying would be next, but I think it might be better to briefly discuss some of MongoDB's core concepts first. Note that some of these will also apply to other schemaless datastores, like &lt;a href="http://couchdb.apache.org/"&gt;CouchDB&lt;/a&gt; and Google's &lt;a href="http://labs.google.com/papers/bigtable.html"&gt;BigTable&lt;/a&gt;.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
The biggest challenge getting your head around a schemaless datastore is shifting in how you think about data persistence. If you're like me, you've spent most of your professional career thinking in relational terms, and maybe have even formally studied set theory, and know what tuples are and who &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FEdgar_F._Codd&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzdfY7ZUDfg8Oi5wK-BJbUZcvjx07g"&gt;E.F. Codd&lt;/a&gt; is. The concepts of tables, rows, relationships, normalization, and structured query language (SQL) might be so ingrained, that it's truly difficult to think of data storage any other way. &lt;i&gt;If you want what you got, don't change what you do&lt;/i&gt;. But, if you sense that there might be a better way to store and retrieve &lt;i&gt;some kinds&lt;/i&gt; of data, you're certainly not alone. &lt;br /&gt;
&lt;br /&gt;
Many of the schemaless/schema-free terms and concepts are either inspired by, or are borrowed from the relational model, yet there are fundamental differences - I'll touch on a couple of the differences later. For now, let's look at some of MongoDB's concepts and how they might relate to a relational mindset.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FDatabases&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzeeFIS3e6z62NU8oO2idDENRlhrZA"&gt;&lt;b&gt;Database&lt;/b&gt;&lt;/a&gt; - Like in a relational model, this is a logical and physical storage area for data, which are &lt;i&gt;Collections&lt;/i&gt; of &lt;i&gt;Documents&lt;/i&gt;. A MongoDB server can have multiple databases.&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FCollections&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzfPRpqRIcTwW_kImx0hJmdKZH0fyQ"&gt;&lt;b&gt;Collection&lt;/b&gt;&lt;/a&gt; - Similar to a table, a &lt;i&gt;Collection&lt;/i&gt; is a group of &lt;i&gt;Documents.&lt;/i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FBSON&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzcMPjjs_3x4aT7PYyn_-oFhNKWLkw"&gt;&lt;b&gt;Document&lt;/b&gt;&lt;/a&gt; - Similar to a row in a table, a Document represents an instance of some object in a Collection. In CFML, a Document object is a &lt;i&gt;structure&lt;/i&gt; (or an array). A Document can contain other documents by either directly embedding them (see below) or by reference.&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FIndexes&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzfh7jDvk9kySTTtUpCSVKjEFGVItQ"&gt;&lt;b&gt;Indexes&lt;/b&gt;&lt;/a&gt; - Like a relational database index, this is a Document attribute registered with MongoDB for query performance and query optimization.&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FQueries%2Band%2BCursors&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzcHjclGouQ699BrYrHOGHudamM7KQ"&gt;&lt;b&gt;Queries and Cursors&lt;/b&gt;&lt;/a&gt; - Lastly, like a relational database, you query Collections. The query results are common programming data structures: Iterators or Arrays, but are referred to more generally as Cursors.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;b&gt;Example CFML/Java Implementation&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cf" name="code"&gt;&amp;lt;cfscript&amp;gt; 
 person = {
  name = 'bill',
  profession = 'programmer',
  age = 'older than dirt'
 }

 mongo = createObject('java', 'com.mongodb.Mongo').init();

 db = mongo.getDb('my_db'); 
 collection = db.getCollection('people');
 doc = createObject('java', 'com.mongodb.BasicDBObject').init();
 doc.putAll(person);
 collection.insert(doc); //correction! thanks to marc e.
 criteria = createObject('java', 'com.mongodb.BasicDBObject').init('NAME','bill');
 query = collection.find(criteria);
 while(query.hasNext()){
  item = query.next();
  dump( item );
 }
&amp;lt;/cfscript&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Note that the "get" operations above will create the object if it does not exist. This a true example of &lt;i&gt;schema-freeness&lt;/i&gt;.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Embedded Document Example&lt;/b&gt;:&lt;br /&gt;
This is much simpler than the name might imply. All you need to do nest one struct within another:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cf" name="code"&gt;person = {
&amp;nbsp;name = 'bill',
&amp;nbsp;profession = 'programmer',
&amp;nbsp;age = 'older than dirt',
&amp;nbsp;address ={
&amp;nbsp;&amp;nbsp; street = 'main st.',
&amp;nbsp;&amp;nbsp; city = 'anytown',
&amp;nbsp;&amp;nbsp; planet = {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name = 'Earth',
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; planetary_code = '0xFFB3540A'
&amp;nbsp;&amp;nbsp; }
&amp;nbsp;}
}
&lt;/pre&gt;&lt;br /&gt;
If you've worked with XML, the nested document structure should be familiar. With MongoDB, Document objects can nest an arbitrary number of other documents. Check out the &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FSchema%2BDesign&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEze2frbGhBzUuIGFjsMRCeb6xFHnfg"&gt;Schema Design guidelines&lt;/a&gt; for some ideas. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Key Differences&lt;/b&gt;:&lt;br /&gt;
From a developer's perspective, the key differences are in how you &lt;i&gt;think&lt;/i&gt; about the data and how the data is retrieved. Instead of thinking about your data as a set of related 2-dimensional tables with rows and cells, you are free to think about data in terms of object structure or composition (hence the name &lt;i&gt;Document&lt;/i&gt;). Storing the data is pretty trivial in MongoDB, and quite a relief compared to writing a complex insert statement. Retrieving data, though, is where stumbling might occur, and big picture consideration should be given when embarking on a new project and considering RDBMS or schemaless. Some people have recommended that the general guideline for deciding whether or not to use a schemaless datastore is to know whether or not your data is &lt;i&gt;high volume and low value&lt;/i&gt;. In other words, if you have very complex data, such as financial data that needs to be frequently aggregated at a very atomic level (high value), or if your data not so complex and maybe, too, you have a lot of it (&lt;i&gt;low value,high volume&lt;/i&gt;) e.g., a Blog. In the case of the former, maybe a relational database might be better; in the latter, maybe MongoDB.&lt;br /&gt;
&lt;br /&gt;
As for querying the data, this is what you might be used to:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cf" name="code"&gt;select&amp;nbsp; p.*, a.*
 from Person p inner join Address a on p.id = a.pid
 where p.id = 'some_id'
&lt;/pre&gt;&lt;br /&gt;
In MongoDB, given the person Document above, this would be done more like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="js" name="code"&gt;person = db.people.find( {_id: some_id} ).limit(1);

&lt;/pre&gt;&lt;br /&gt;
Both say the same thing, semantically: "Given a person's ID, return the person and their address"&lt;br /&gt;
&lt;br /&gt;
Up next, for real, Querying MongoDB in detail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-6213693682341677982?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/6213693682341677982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=6213693682341677982' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/6213693682341677982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/6213693682341677982'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/look-ma-no-sql-mongodb-and-coldfusion_20.html' title='&quot;Look, Ma. No SQL!&quot; - MongoDB and ColdFusion - Part 2'/><author><name>bill shelton</name><uri>http://www.blogger.com/profile/06624894387927690246</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17359140296736057249'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-4010359260152963502</id><published>2009-10-19T00:23:00.113-04:00</published><updated>2009-10-20T10:29:31.594-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MongoDB'/><title type='text'>"Look, Ma. No SQL!" - MongoDB and ColdFusion - Part 1</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;From the perspective of a developer who prefers to think in terms of real-world objects, relational databases tend to slow me down. I'm not making some broad sweeping statement that "databases are bad" - they're not. They're just another layer of disparate technology that I need to contend with. What if we could just write code and store and retrieve those objects quickly? &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping"&gt;ORM&lt;/a&gt; and caching technologies do this well and they're aim is &lt;i&gt;integration&lt;/i&gt; with relational databases, and Adobe has nicely integrated Hibernate into &lt;a href="http://tryit.adobe.com/us/coldfusion/?sdid=EUWSP"&gt;ColdFusion 9&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alternatively, there's been some &lt;i&gt;very&lt;/i&gt; interesting work done in the area of &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FNosql&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzc10o7cw3ymZ94DOCoyfhVr9xSnZg"&gt;NoSQL&lt;/a&gt;, or &lt;a href="http://blog.mongodb.org/post/119945109/why-schemaless"&gt;schemaless&lt;/a&gt; data persistence. These efforts provide relatively small, fast, and distributed key-value data stores, and allow applications to store and retrieve objects in an efficient manner - &lt;i&gt;and&lt;/i&gt; programmers don't have to worry about creating and managing tables or schemas. These projects include (among others) &lt;a href="http://couchdb.apache.org/"&gt;CouchDB&lt;/a&gt;, &lt;a href="http://1978th.net/tokyotyrant/"&gt;Tokyo Tyrant&lt;/a&gt;, and &lt;a href="http://www.mongodb.org/display/DOCS/Home"&gt;MongoDB&lt;/a&gt;. In short, these can be viewed as efficient and hu&lt;b&gt;Mongo&lt;/b&gt;us persistent hash tables. I chose to work with MongoDB simply because I found it the fastest to get up and running on both Unix and Windows. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Quick example usage&lt;/b&gt; (full CFML source &lt;a href="http://github.com/virtix/cfmongodb/"&gt;available here&lt;/a&gt;):&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cf" name="code"&gt;&amp;lt;cfscript&amp;gt;
&amp;nbsp; blog = structNew();
&amp;nbsp; blog.title = '';
&amp;nbsp; blog.text = '';
&amp;nbsp; blog.author = '';
&amp;lt;/cfscript&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
This is a &lt;i&gt;very&lt;/i&gt; basic data structure (a CFML &lt;i&gt;structure&lt;/i&gt;) representing a blog entity. We know what we would need to do to write this to a database - create the table(s), specify columns and datatypes, and write SQL to insert, update, delete, and fetch. Maybe we'll use stored procedures or DAOs, too. With MongoDB here's a simple example implementation - a proof of concept&lt;a href="http://github.com/virtix/cfmongodb/"&gt; API&lt;/a&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cf" name="code"&gt;&amp;lt;cfscript&amp;gt;
&amp;nbsp; mongo = createObject('component','MongoDB');
&amp;nbsp; //create the blog
&amp;nbsp; blog = structNew();
&amp;nbsp; blog.title = 'Look, Ma. No SQL! MongoDB and ColdFusion';
&amp;nbsp; blog.text = 'Rapid development with MongoDB ...';
&amp;nbsp; blog.author = 'bill shelton';
&amp;nbsp; mongo.put(blog);
&amp;nbsp;&amp;lt;/cfscript&amp;gt;&amp;nbsp; &lt;/pre&gt;&lt;br /&gt;
That's it - the entire structure is now persisted. For the jQuery and JavaScript folks, you're &lt;i&gt;really&lt;/i&gt; going to like this. The stored data format (&lt;a href="http://www.mongodb.org/display/DOCS/BSON"&gt;BSON&lt;/a&gt; - binary JSON) in string representation is plain old JSON and the &lt;a href="http://www.mongodb.org/display/DOCS/mongo+-+The+Interactive+Shell"&gt;MongoDB admin console&lt;/a&gt; is a JavaScript shell&lt;b&gt;:&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="js" name="code"&gt;&amp;gt;db.default_collection.findOne()
{"_id": ObjectId( "58c5b878f16bdb4a94f4d300") , "AUTHOR" : "bill shelton" ,
"TEXT" :"Rapid development with MongoDB ..." , 
"TITLE" : "Look, Ma. No SQL! MongoDB and ColdFusion"}

&lt;/pre&gt;How &lt;i&gt;cool&lt;/i&gt; is that? &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Adding additional fields or data&lt;/b&gt;. There's no need to create new tables or columns -&amp;nbsp; MongoDB takes care of this for you. If they don't exist they'll be created. Just add the elements you need to your code. Let's add some &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;tags&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;comments&lt;/span&gt; to our blog entity. &lt;i&gt;Note that these are not simple string&lt;/i&gt; &lt;i&gt;properties&lt;/i&gt; - this makes the example a bit more interesting and shows how &lt;a href="http://www.mongodb.org/display/DOCS/Schema+Design"&gt;powerful&lt;/a&gt; MongoDB can be.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cf" name="code"&gt;&amp;lt;cfscript&amp;gt;
&amp;nbsp; mongo = createObject('component','MongoDB');
&amp;nbsp; //create the blog
&amp;nbsp; blog = structNew();
&amp;nbsp; blog.title = 'Look, Ma. No SQL! MongoDB and ColdFusion';
&amp;nbsp; blog.text = 'Rapid development with MongoDB';
&amp;nbsp; blog.author = 'bill shelton';
&amp;nbsp; blog.tags = ['cool stuff', 'data persistence', 'hadoop'];
&amp;nbsp; blog.comments = [
&amp;nbsp;&amp;nbsp;&amp;nbsp; comment = {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; author = 'anonymous',
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; comment_text = 'you suck at unit testing'
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp; ];
&amp;nbsp; mongo.put(blog);
&amp;nbsp;&amp;lt;/cfscript&amp;gt;&amp;nbsp; &lt;/pre&gt;&lt;br /&gt;
Here we added an array of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;tags&lt;/span&gt; and array of structs ... &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;comments&lt;/span&gt;. Again, our entity is saved to the data store. Let's read this back out and print it:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cf" name="code"&gt;&amp;lt;cfscript&amp;gt;

 mongo = createObject('component','MongoDB');

 blog = mongo.findOne();// get the most recent entry
 writeoutout(blog.title);
 writeoutout(blog.author);
 writeoutout(blog.text);
 writeoutput(blog.comments[1].author);
 writeoutput(blog.comments[1].comments_text);

&amp;lt;/cfscript&amp;gt;&lt;/pre&gt;&lt;br /&gt;
Here's a basic example of how to update and delete data.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cf" name="code"&gt;&amp;lt;cfscript&amp;gt;
&amp;nbsp; blog = mongo.findOne();// get's the most recent

&amp;nbsp; blog.title = 'My New Blog Title';
&amp;nbsp; mongo.update(blog);
&amp;nbsp; //if we want to delete it: 
&amp;nbsp; mongo.delete(blog);
&amp;lt;/cfscript&amp;gt;&lt;/pre&gt;&lt;br /&gt;
For someone who has embedded many lines of&amp;nbsp; SQL in Java and CFML and knows the pain with keeping all the parts in synch, this is &lt;i&gt;very&lt;/i&gt; appealing.&amp;nbsp; Note the dot notation for traversing, too - It's familiar &lt;i&gt;and&lt;/i&gt; fast. Also, my goal with all this as not to do a straight port of the Java driver. Rather, I tried for something extremely simple and fast for writing and fetching CFML structures to and from MongoDB datastores. &lt;br /&gt;
&lt;br /&gt;
Though one of the big motivators for MongoDB seems to be geared towards creating very large distributed data stores, from a simple rapid development perspective, it's downright sexy.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Getting Started with MongoDB and ColdFusion&lt;/b&gt;&lt;br /&gt;
1. &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FDownloads&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzeerl_omn2m7KblK5M4mIQBf_lGlQ"&gt;Download &lt;/a&gt;and start MongoDB - this is pretty much just downloading, unzipping, and running ./mongod. But, you might have to create a directory for the data. It's &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FQuickstart&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzcMvckab7jRXq0ijKls2_sveA0jZQ"&gt;well documented&lt;/a&gt; and I was able to get it up and running in a couple of minutes on both Windows and Ubunutu.&lt;br /&gt;
2. &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fgithub.com%2Fmongodb%2Fmongo-java-driver%2Fdownloads&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzcTUR0oQ7l3aa9MwqOXZ9PDWZG7gA"&gt;Download the Java driver&lt;/a&gt; and put it in your ColdFusion server's classpath or use &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.compoundtheory.com%2F&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzeW7FW7bE8TkwejxHqBvQZdbJ6fAQ"&gt;Mark Mandel's&lt;/a&gt; &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.compoundtheory.com%2F%3Faction%3Djavaloader.index&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzcRMvXGx__BOgik9mAegvrfuO-pFg"&gt;JavaLoader&lt;/a&gt;.&lt;br /&gt;
3. Check out the &lt;a href="http://github.com/virtix/cfmongodb/"&gt;example code and the MongoDB wrapper for ColdFusion&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Note that there's a lot of other information about all this from both the &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FUse%2BCases&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzdInnYAHossSenYVsYRl-V4OP8Q-A"&gt;developer's perspective&lt;/a&gt; and the &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FUse%2BCases&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzdInnYAHossSenYVsYRl-V4OP8Q-A"&gt;admin perspective&lt;/a&gt;. I recommend reading up on &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FUse%2BCases&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEzdInnYAHossSenYVsYRl-V4OP8Q-A"&gt;use cases&lt;/a&gt; and &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2FSchema%2BDesign&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFrqEze2frbGhBzUuIGFjsMRCeb6xFHnfg"&gt;schema design&lt;/a&gt;, as well as the other docs.&lt;br /&gt;
&lt;br /&gt;
Next up: MongoDB query syntax .&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
Test and be Happy!&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-4010359260152963502?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/4010359260152963502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=4010359260152963502' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/4010359260152963502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/4010359260152963502'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/look-ma-no-sql-mongodb-and-coldfusion.html' title='&quot;Look, Ma. No SQL!&quot; - MongoDB and ColdFusion - Part 1'/><author><name>bill shelton</name><uri>http://www.blogger.com/profile/06624894387927690246</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17359140296736057249'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-2476611850127354762</id><published>2009-10-16T14:05:00.000-04:00</published><updated>2009-10-16T17:35:41.182-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coldfusion'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Concision in ColdFusion and Scala</title><content type='html'>&lt;style&gt;#main .post br {display:none} &lt;/style&gt;  &lt;div class="note"&gt;I do not intend this post as some kind of Scala vs. ColdFusion shooting match. Rather, it’s about enhanced script support in CF9, but it was inspired by a nice post I read on the Scala language regarding a feature I’ve long-loved about ColdFusion: named and default arguments&lt;/div&gt;  &lt;p&gt;I've been programming with ColdFusion and Java for a long time. Recently, I've started dabbling with &lt;a href="http://www.scala-lang.org/" target="_blank"&gt;Scala&lt;/a&gt;, and it's a language I'm starting to really like. One of the reasons I’ve taken to Scala is that in a number of ways it solves certain verbosity problems that ColdFusion solves as well. I decided to write this blog post after reading &lt;a href="http://heikoseeberger.blogspot.com/2009/10/scala-28-be-more-concise-with-named-and.html" target="_blank"&gt;this article by Heiko Seeberger&lt;/a&gt; on named and default arguments in Scala 2.8. As I was reading, I thought, “Cool! Scala does something that CF has done for a long time”… something which has always irritated me about Java. And with ColdFusion 9, things get even better.&lt;/p&gt;  &lt;p&gt;When we talk about verbosity, we’re talking about at least two things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;language constructs &lt;/li&gt;    &lt;li&gt;language syntax &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Sure there are others, but these two are what I want to discuss briefly right now. Let’s talk about constructs first.&lt;/p&gt;  &lt;h1&gt;Concision via Language Constructs&lt;/h1&gt;  &lt;h2&gt;Argument Defaults&lt;/h2&gt;  &lt;p&gt;A traditional, pre-CF9 ColdFusion component (CFC) might look something like this:&lt;/p&gt;  &lt;pre class="cf" name="code"&gt;&amp;lt;cfcomponent output=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;	&lt;br /&gt;	&amp;lt;cffunction name=&amp;quot;init&amp;quot; output=&amp;quot;false&amp;quot; access=&amp;quot;public&amp;quot; returntype=&amp;quot;Order&amp;quot;&amp;gt;&lt;br /&gt;		&amp;lt;cfargument name=&amp;quot;id&amp;quot; type=&amp;quot;numeric&amp;quot; required=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;		&amp;lt;cfargument name=&amp;quot;items&amp;quot; type=&amp;quot;array&amp;quot; required=&amp;quot;false&amp;quot; default=&amp;quot;#ArrayNew(1)#&amp;quot;/&amp;gt;&lt;br /&gt;		&amp;lt;cfargument name=&amp;quot;ShippingMode&amp;quot; type=&amp;quot;string&amp;quot; required=&amp;quot;false&amp;quot; default=&amp;quot;StandardShipping&amp;quot;/&amp;gt;&lt;br /&gt;		&amp;lt;cfset structAppend(variables,arguments)&amp;gt;&lt;br /&gt;		&amp;lt;cfreturn this&amp;gt;&lt;br /&gt;	&amp;lt;/cffunction&amp;gt;&lt;br /&gt;	&lt;br /&gt;&amp;lt;/cfcomponent&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Here we see one required argument and two optional arguments. The optional arguments have default values. This means you could create an Order in at least these ways:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="cf" name="code"&gt;&amp;lt;cfset items = [&amp;quot;boat&amp;quot;,&amp;quot;car&amp;quot;,&amp;quot;flower&amp;quot;]&amp;gt;&lt;br /&gt;&amp;lt;cfset order = createObject(&amp;quot;component&amp;quot;,&amp;quot;Order&amp;quot;).init(1)&amp;gt;&lt;br /&gt;&amp;lt;cfset order2 = createObject(&amp;quot;component&amp;quot;,&amp;quot;Order&amp;quot;).init(1,items)&amp;gt;&lt;br /&gt;&amp;lt;cfset order3 = createObject(&amp;quot;component&amp;quot;,&amp;quot;Order&amp;quot;).init(1,items,&amp;quot;FancyShipping&amp;quot;)&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now, if you were to do this in Java, you’d have even more lines of code to write in your Order class. Java does not have defaults for arguments, so you’d need to write 3 different constructors. Heiko illustrates this using Scala 2.7 syntax in his article, but it’d look roughly the same in java, only worse. Your constructor signatures would roughly be:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class Order {&lt;br /&gt;	public Order(int id){}&lt;br /&gt;	public Order(int id,String[] items){}&lt;br /&gt;	public Order(int id,String[] items, String shippingMode){}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Named Arguments&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In the snippet above, I created the object by passing in 3 unnamed params. ColdFusion knows which arg is which based on position. But what if I wanted to create an order instance with the default argument for items, but “FancyShipping” for the ShippingMode? I.e. I want to pass params for arguments at positions 1 and 3, but not 2. Fortunately, ColdFusion makes this easy with named arguments:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="cf" name="code"&gt;&amp;lt;cfset order4 = createObject(&amp;quot;component&amp;quot;,&amp;quot;Order&amp;quot;).init(id=1,shippingMode=&amp;quot;FancyShipping&amp;quot;)&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In addition to making the code more readable, it affords you the ability to pick and choose which params you wish to pass, leaving the rest to the defaults.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Obviously, you can’t do this in Java, so you’d need to add a fourth constructor:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code"&gt;public class Order {&lt;br /&gt;	....	&lt;br /&gt;	public Order(int id, String shippingMode){}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;As Heiko points out, Scala 2.8 solves this Verbosity-by-lack-of-language-construct problem by providing named arguments and argument defaults. Ripped right from his post:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code"&gt;case class Order28(id: Long, items: List[Item] = Nil, mode: ShippingMode = StandardShipping)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;And to create an order, you could do:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code"&gt;val order = Order28(1)&lt;br /&gt;&lt;br /&gt;val order2 = Order28(1,item list goes here, OvernightShipping)&lt;br /&gt;&lt;br /&gt;val order3 = Order28(1,mode=OvernightShipping)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Nice! As &lt;a href="http://corfield.org/blog/index.cfm?" target="_blank"&gt;Sean Corfield&lt;/a&gt; pointed out, one difference between ColdFusion and Scala with respect to named arguments is that Scala allows you to mix named and unnamed arguments, as in the last example, whereas ColdFusion expects you to stick with one or the other.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Concision via Syntax&lt;/h1&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Looking at the Scala version (Please read Heiko’s full post to see it in all its beauty), we see how these two language constructs enhance concision when compared with Java. However, when you look at the ColdFusion code compared with the Scala code, you see that the Scala version is tighter and, in my opinion, simply nicer to look at. The primary reason is the difference in syntax between the two languages.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The ColdFusion version spends a lot of characters in tag names and attribute names. For instance:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="cf" name="code"&gt;&amp;lt;cfargument name=&amp;quot;ShippingMode&amp;quot; type=&amp;quot;string&amp;quot; required=&amp;quot;false&amp;quot; default=&amp;quot;StandardShipping&amp;quot;/&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Egads. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Prior to ColdFusion 9, you could’ve written this with a function in cfscript, but it didn’t afford you all the language constructs of the tag-based version. However, with ColdFusion 9, we get “full cfscript support”, which means tighter syntax. Check out the same CFC, but in full script:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="cf" name="code"&gt;component {&lt;br /&gt;	public Order function init(required numeric id, array items = ArrayNew(1), String shippingMode=&amp;quot;StandardShipping&amp;quot; ){&lt;br /&gt;		StructAppend(variables,arguments);&lt;br /&gt;		return this;&lt;br /&gt;	}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Admittedly not as concise as Scala, but I don’t care… it’s a long way from the tag based version and is quite good enough for me. In addition, creating instances of this CFC gets nicer, too:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="cf" name="code"&gt;&amp;lt;cfscript&amp;gt;&lt;br /&gt;	order = new Order(27);&lt;br /&gt;&lt;br /&gt;	order2 = new Order(28, [&amp;quot;boat&amp;quot;,&amp;quot;car&amp;quot;,&amp;quot;flower&amp;quot;] ,&amp;quot;FancyShipping&amp;quot;);&lt;br /&gt;&lt;br /&gt;	order3 = new Order(id=29, shippingMode=&amp;quot;Good Enough Shipping&amp;quot;);&lt;br /&gt;&amp;lt;/cfscript&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Not bad, eh? A big hat tip to the ColdFusion team for giving us named arguments and argument defaults since waaaaay back. And another hat tip to them and the &lt;a href="http://www.opencfml.org/display/cfmladvisory/Home" target="_blank"&gt;CFML Advisory committee&lt;/a&gt; for steering the language, syntactically, in a direction that aids in readability and makes coding more pleasurable.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-2476611850127354762?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/2476611850127354762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=2476611850127354762' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/2476611850127354762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/2476611850127354762'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/concision-in-coldfusion-and-scala.html' title='Concision in ColdFusion and Scala'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-5818718571831387856</id><published>2009-10-15T23:08:00.000-04:00</published><updated>2009-10-15T23:09:00.011-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coldfusion'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><title type='text'>Why is CFExecute Hanging?</title><content type='html'>&lt;style&gt;


#main br {display:none}&lt;/style&gt;  &lt;h1&gt;The Problem&lt;/h1&gt;  &lt;h2&gt;Wednesday: CFExecute is timing out, and I don’t know why&lt;/h2&gt;  &lt;p&gt;I get an IM from a coworker, Alan. One of the applications I wrote a while back isn’t working on our Dev server. Specifically, this application uses CFExecute to invoke Beyond Compare from the command line on Windows. The app would spin, and eventually, Alan would get a “Timeout period expired without completion of C:\Program Files\Beyond Compare 2\bc2.exe”. Windows Task Manager was littered with BC2.exe processes&lt;/p&gt;  &lt;p&gt;I fixed this with little troubles and sent out an email to the dev group with instructions for fixing it (explanation below).&lt;/p&gt;  &lt;h2&gt;Thursday: CFExecute is timing out – again, but on a different machine – and I don’t know why&lt;/h2&gt;  &lt;p&gt;The next day, after the app was running successfully again on the Dev server, Alan emails me. The app won’t run on his machine now, and it’s giving the same error message. Me, well… I get pissy. “C’mon, dude, I just sent an email telling how to fix it”. It was early, I was cranky, and the “angels of my better nature” weren’t in the mood. In short, I was an a-hole, assuming Alan was being lazy.&lt;/p&gt;  &lt;p&gt;He wasn’t. He tried everything I had suggested as a fix. It still wasn’t working.&lt;/p&gt;  &lt;p&gt;Sitting at his desk trying to figure it out, I was stumped. I rarely get this stumped. I *never* get stumped enough to email a company for help (in this case, Scooter, the makers of Beyond Compare). And there I was, writing an email to Scooter. &lt;/p&gt;  &lt;p&gt;But you know how it is. You’re a geek. You like puzzles. You never give up. So… one more trip over to Alan’s desk. “Let’s try a few more things…”&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;This is a post about debugging. And it’s a post about assumptions.&lt;/strong&gt;&lt;/p&gt;  &lt;h1&gt;What we did to debug&lt;/h1&gt;  &lt;h2&gt;Wednesday night: The Easy Fix&lt;/h2&gt;  &lt;p&gt;To debug the hanging bc2.exe on the Dev server took about 10 minutes. After a few piddles around (selecting different options in the app, restarting CF – ruling out the really easy stuff) I simply ran the same thing that CFExecute was running at the command line. This is CFExecute Debugging 101. In my experience, this almost always yields the answer.&amp;#160; When I wrote the app, I had it write its entire cfexecute command to a log file, so it was a cut-n-paste job to run it from the command line.&lt;/p&gt;  &lt;p&gt;When I did so, I saw the problem right away: the license had expired for Beyond Compare on the Dev server. Instead of running the command I had given it, Beyond Compare was throwing up a popup asking for a new serial number. All those BC2.exe processes in Task Manager were those popups, swallowed by CF, but never completing.&amp;#160; Fixing the license problem fixed the CFExecute problem. &lt;/p&gt;  &lt;h2&gt;Thursday: The not-so-easy Fix&lt;/h2&gt;  &lt;h3&gt;Attempt #1&lt;/h3&gt;  &lt;p&gt;After confirming that the problem on Alan’s machine was not license-related, we tried a whole bunch of things, mostly centered around answering the question: “Why does it work on one machine and not the other? What are the differences between these two machines?”&lt;/p&gt;  &lt;p&gt;We suspected a permissions issue from the start. The BC command was looking at different network locations, so the first thing we did was change the script to look only at directories on Alan’s machine… remove anything network related. No Dice.&lt;/p&gt;  &lt;p&gt;We always run CF under a special account (we’ll call it “cfservice”), and we thought “maybe the account got borked”. We weren’t taking that for granted as it’s happened before. So we tried running CF under the local system account. Nada.&lt;/p&gt;  &lt;p&gt;We added additional logging into the BC command to get more info… it wouldn’t write the logs. But it would write the logs if we ran the command directly on CMD. WTF? &lt;/p&gt;  &lt;p&gt;We went into Beyond Compare’s options and fiddled with a few important-sounding checkboxes. Still nothing.&lt;/p&gt;  &lt;p&gt;So we’re at a point where, when running the command from CMD, it worked fine. But when run from within CFExecute, it was hanging. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What’s the difference between ColdFusion running it, and us running it from CMD? &lt;/strong&gt;We were stumped.&lt;/p&gt;  &lt;p&gt;At this point, we were certain that for some reason, Beyond Compare was throwing up a popup when run from within CF, but we couldn’t “see” that popup because, obviously, CF was swallowing it. We tried hooking a debugger up to the BC2.exe process, but we got nowhere fast. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Aside: while all this is happening, another coworker is talking about some other thing, “this app (unrelated) worked a few days ago. Now it’s busted. What’s going on?”. This was an app I had fiddled with “a few days ago”. I knew exactly what the problem was. But I didn’t step in yet. When you’re debugging, you stay focused. You ignore other problems even if you know the answer because when you’re debugging, you stay in the zone. There are times when you break from the problem and let your subconscious chew. For me, those times are toward the end of the day, when I’m spent, and I can let my mind wrestle with it on my commute home. But this was 10:00 AM. This, for me, is prime focus time, and a big no-no for me is pulling off of a problem during my peak mental energy.&amp;#160; When you commit, you commit, even if it means leaving someone else hanging for a little bit. Good teams understand this, and God willing you’re patient with each other and recognize when your coworkers need to focus. It’s a high form of respect among geeks. If you see one of your colleagues in the zone, and they sort of mindlessly blow you off, it’s not necessarily an affront. Maybe it’s that they’re running at full pace and stopping would put them at the back of the proverbial pack. Be patient. Do not assume the worst.&lt;/p&gt; &lt;/blockquote&gt;  &lt;h3&gt;Attempt #2&lt;/h3&gt;  &lt;p&gt;I was about to give up, so I went back to my desk to do a little research. I drafted an email to Scooter. I held off, then went back to Alan’s desk.&lt;/p&gt;  &lt;p&gt;Alan was still pretty sure it was permissions related, and at this point I was up for anything. But we had tried that route already. We ran it under cfservice. We ran it under local system. What else could it be? What’s the *delta* among running it from cfservice, running it from local system, and running it from CMD logged into the machine normally (under Alan’s account)?&lt;/p&gt;  &lt;p&gt;OK, let’s try this: let’s take a cue from Michael Jordan. “You gotta be the ball”. So, let’s “Be ColdFusion”.&lt;/p&gt;  &lt;p&gt;We logged out, logged back into his machine under our cfservice account (which, remember, CF runs under on our machines), and attempted to run the app from the command line. Bam. Popup… The damn license popup. How? What? Huh? &lt;/p&gt;  &lt;p&gt;It turns out that Beyond Compare stores a license for each user on the machine, which we confirmed by poking through the registry. It explained why it would work when we ran it from CMD when logged in normally, and it explained why cfservice was hanging BC2.exe. We logged back in under Alan’s account, then did a shift-run as – cfservice on Beyond Compare, and sure enough we got the popup. &lt;/p&gt;  &lt;p&gt;To fix, we simply entered the license for the application while running it from the same account as ColdFusion, which cured our ills.&lt;/p&gt;  &lt;p&gt;In retrospect, it makes perfect sense. While you’re debugging, it never makes sense. This is learning, and it’s why I go to work every day.&lt;/p&gt;  &lt;h1&gt;Takeaways&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;If your application appears to hang, try running it on the command line first, outside of CF, and see if you get any popups &lt;/li&gt;    &lt;li&gt;If your application appears to hang, and it works from the command line when you run it, try running it from the same user account as CF is running&amp;#160; under &lt;/li&gt;    &lt;li&gt;Your coworkers can sometimes *appear* to be helpless, or at least appear to not be taking the initiative you wish they would take. Before you assume that’s the case, try instead to &lt;strong&gt;assume the best&lt;/strong&gt;. Assume they tried; assume they tried hard. When you think you’re not getting the best out of people, ask yourself: Are you giving them your best, too? Not your best tech. Your best &lt;strong&gt;you. &lt;/strong&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;--marc&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-5818718571831387856?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/5818718571831387856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=5818718571831387856' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/5818718571831387856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/5818718571831387856'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/why-is-cfexecute-hanging.html' title='Why is CFExecute Hanging?'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-5273404877246112638</id><published>2009-10-07T06:38:00.006-04:00</published><updated>2009-10-08T05:47:46.944-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Humor'/><title type='text'>The Nobel Prize for Software</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://virtix.stripgenerator.com/2009/10/08/the-2009-nobel-prize-for-software/"&gt;&lt;img alt="The 2009 Nobel Prize for Software" src="http://static.stripgenerator.com/generated/virtix/strip/2009/10/08/the-2009-nobel-prize-for-software_embed.png" style="border: medium none;" title="The 2009 Nobel Prize for Software" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-5273404877246112638?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/5273404877246112638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=5273404877246112638' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/5273404877246112638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/5273404877246112638'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/nobel-prize-for-software.html' title='The Nobel Prize for Software'/><author><name>bill shelton</name><uri>http://www.blogger.com/profile/06624894387927690246</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17359140296736057249'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-1651497219490818372</id><published>2009-10-06T07:38:00.010-04:00</published><updated>2009-10-06T08:07:20.089-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Presentations'/><title type='text'>From Galileo to the iPhone - Edward Tufte Connects the Dots</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;"Hey, have you heard of Edward &lt;span id="SPELLING_ERROR_0"&gt;Tufte&lt;/span&gt;?", Frank and I are standing in some random Northern Virginia parking lot and I'm swatting mosquitoes in the September humidity.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;"Who?"&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;img height="267" src="http://lh3.ggpht.com/_R-2JPB8crqk/SssdFtaBViI/AAAAAAAAAPU/mysyKLGAM4c/%5BUNSET%5D.jpg?imgmax=800" style="float: right; margin-bottom: 10px; margin-left: 10px; margin-top: 10px; max-width: 800px;" width="445" /&gt;&lt;br /&gt;
Frank enlightens. He describes a scientist and artist who wants to explain concepts of displaying information - graphs and other visual assets. Publishers can't get it right, or are not willing to publish to his standards, so, he prints his own books - &lt;span style="font-family: monospace;"&gt;eyebrows.raise()&lt;/span&gt;. I like that - not defiance, but someone believing in something deep enough they go beyond the status &lt;span id="SPELLING_ERROR_1"&gt;quot&lt;/span&gt; and make it happen correctly. Edward &lt;span id="SPELLING_ERROR_2"&gt;Tufte&lt;/span&gt;, aka ET, also builds large visual structures (statues) in Connecticut (in the town where Frank's wife grew up) - these not only present beauty, but are 3 dimensional descriptions of  &lt;span id="SPELLING_ERROR_3"&gt;ET's&lt;/span&gt; analytical and presentation concepts.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;
&lt;img src="http://lh3.ggpht.com/_R-2JPB8crqk/SssdUozRmBI/AAAAAAAAAPY/y-hHek_lua8/%5BUNSET%5D.jpg?imgmax=800" style="float: left; height: 255px; margin-bottom: 10px; margin-right: 10px; margin-top: 10px; max-width: 800px; width: 447px;" /&gt;Of the myriad of things Frank and I talk about  - rapid bi-directional streams of consciousness - this one sticks. So, I find &lt;a href="http://www.edwardtufte.com/tufte/"&gt;&lt;span id="SPELLING_ERROR_4"&gt;ET's&lt;/span&gt; web site&lt;/a&gt; and I see he's to be in Arlington, VA, in 2 weeks. I'm still a bit skeptical, but as I start reading more and more, I become quite intrigued. ET is thinking about information display at it's core, not just from the very narrow perspective of the web or the evil blood sucking spawn of Satan, known as PowerPoint, but from the perspective of history, of science, art, and  cognition. When I noticed that when you attend his lectures ($380), you receive all 4 of his books, I was immediately sold. At a minimum I would I have 4 new books - &lt;span id="SPELLING_ERROR_5"&gt;wahoo&lt;/span&gt;! I registered. (The quality of the books is, by the way, simply amazing.) I have a tendency to coddle my books, too, especially ones of high quality like these. During the lecture, again, I was enlightened. ET was explaining a concept of presentation asks the audience to fold one of the pages in half, saying, "It's a book; it's meant to be 'used'". Pragmatic.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;b&gt;&lt;br /&gt;
&lt;br /&gt;
Summary&lt;/b&gt;: Drop what you are doing and go. At the time of this writing, he's on tour now at various points in the U.S.  ET is, of course, a seasoned master at presentation and for someone who periodically presents at conferences and other venues, it was great lesson to see a pro at work. Among many other 2D and 3D visuals, he showed both a 1st edition Galileo book with &lt;span id="SPELLING_ERROR_6"&gt;original&lt;/span&gt; drawings of Galileo's sun spot discoveries, and ET also demonstrated how and why the iPhone display works. Now, that's a perspective that transcends! There's plenty of other gems and gold in ET's writings and presentation, so, go for it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://mxunit.org/"&gt;Marc &lt;span id="SPELLING_ERROR_7"&gt;Esher&lt;/span&gt;&lt;/a&gt; asked me for the top 3 concepts I took away. I'll give you 4 plus a few more, trying to keep it as brief as possible. These concepts transcend the medium; that is, they apply to any information display, whether in print, on screen, or in person.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Moral and Ethical Responsibility&lt;/b&gt;: Presenting and consuming visual information is a moral activity. If you are presenting or receiving information in any way, be it on the web, in a meeting, or at conference, it is your moral responsibility to ensure the information is true and accurate. I get the fact that when you are telling people about something, that it better be right to the best of your ability, but as a consumer? As a consumer of information, it is up to us make sure that what is being presented is true and correct. We should hold the presenter intellectually &amp;amp; ethically responsible for what they show and tell. "It's better to be approximately correct, than to be precisely wrong."&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Respect Your Audience&lt;/b&gt;: It seems that there is a dangerous assumption that as presenters we should &lt;i&gt;know&lt;/i&gt; our audience. ET explains that claiming to know your audience puts the presenter in a precarious situation, creating a &lt;span id="SPELLING_ERROR_8"&gt;tendency&lt;/span&gt; to play down to an audience. So, it's better to &lt;i&gt;respect&lt;/i&gt; your audience. Chances are your audience is as smart, if not smarter than you. Treat them as equals, as colleagues.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Use Successful Models&lt;/b&gt;: Instead of guessing at what works for your presentation, or re-inventing something, use something proven. For example, consider modeling your display after the New York Times Sports statistics or Google News. These are successful presentations that are used by millions of people each day.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Presentation Design&lt;/b&gt;: The problem with design is (1) designers are taught to introduce creative assets (pictures, images, things that dazzle the eye), but when displaying information, especially complex data, the idea is the opposite. We need to remove everything not related to or supporting the subject or content. (2) Use a &lt;i&gt;super graphic&lt;/i&gt; to describe your content. This is a single large graphic that has all the information about your subject &lt;span id="SPELLING_ERROR_9"&gt;contained&lt;/span&gt; in a cohesive visual space. ET exemplified Charles Joseph &lt;span id="SPELLING_ERROR_10"&gt;Minard's&lt;/span&gt; pictorial &lt;span id="SPELLING_ERROR_11"&gt;representation&lt;/span&gt; of Napoleon's march to Moscow:&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;div align="center"&gt;&lt;a href="http://2.bp.blogspot.com/_R-2JPB8crqk/Sssizl1OmBI/AAAAAAAAAPc/t8WLoqjG21U/s1600-h/Minard.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5389439648802969618" src="http://2.bp.blogspot.com/_R-2JPB8crqk/Sssizl1OmBI/AAAAAAAAAPc/t8WLoqjG21U/s320/Minard.png" style="cursor: pointer; display: block; height: 161px; margin: 0px auto 10px; text-align: center; width: 338px;" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;p&gt;&lt;/p&gt;The above is a bit more &lt;span id="SPELLING_ERROR_12"&gt;philosophical&lt;/span&gt;. The following, though still abstract, tries to convey the principals of how to make it happen and what should be included in the display.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Fundamental Principals of Analytical Design &lt;/b&gt;[&lt;i&gt;Beautiful Evidence, pp120-135 Edward &lt;span id="SPELLING_ERROR_13"&gt;Tufte&lt;/span&gt;, 2006&lt;/i&gt;]&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Show comparisons, contrasts, differences&lt;/li&gt;
&lt;li&gt;Show causality, mechanism, explanation, systematic structure&lt;/li&gt;
&lt;li&gt;Show multivariate data; that is, more than one variable&lt;/li&gt;
&lt;li&gt;Completely integrate words, numbers, and diagrams&lt;/li&gt;
&lt;li&gt;Documentation: Thoroughly describe the evidence. Provide a detailed title, indicate the authors and sponsors, document the data sources, show complete measurement scales, and point out relevant issues.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Content is everything: Analytical presentations ultimately stand or fall depending on the quality, relevance, and integrity of their content.&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
Displaying information is hard. As software professionals, I now see it's our responsibility (not just our job) to consider how the software we write is displaying the content our customers are trying to convey. Many of us are not &lt;i&gt;designers&lt;/i&gt;, per &lt;span id="SPELLING_ERROR_14"&gt;se&lt;/span&gt;, and get wrapped up in performing complex computational tasks. We may end up feeling smart and get or create the occasional pat on the back for being so, but we might be just a bit more successful if we applied some of that analytical brilliance to displaying the information we compute. So many times I've heard or seen programmers say at conferences, "I'm not a designer, so, excuse my slides ...", implying incompetence at visual display. Well, this is me being your responsible and ethical consumer : You're more than a just a programmer and that statement comes across like you don't care or your audience is not worth the effort of trying your best. It's your responsibility to communicate your ideas to the best of your abilities and I know you can do it well. Ask someone you respect for advice. Ask colleagues or peers for feedback on your presentation. Then Rock the World with your brilliance.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="zemanta-pixie"&gt;&lt;img alt="" class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=411f284a-d9c0-84c2-a34e-84375f425f2f" /&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-1651497219490818372?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/1651497219490818372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=1651497219490818372' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/1651497219490818372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/1651497219490818372'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/10/from-galileo-to-iphone-edward-tufte_06.html' title='From Galileo to the iPhone - Edward Tufte Connects the Dots'/><author><name>bill shelton</name><uri>http://www.blogger.com/profile/06624894387927690246</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17359140296736057249'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_R-2JPB8crqk/Sssizl1OmBI/AAAAAAAAAPc/t8WLoqjG21U/s72-c/Minard.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-6957958532655914180</id><published>2009-09-22T08:29:00.001-04:00</published><updated>2009-09-22T08:32:04.155-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hudson'/><category scheme='http://www.blogger.com/atom/ns#' term='ant'/><title type='text'>Using SVNANT in your ANT build files with Hudson</title><content type='html'>&lt;style&gt;#main br {display:none}&lt;/style&gt;  &lt;p&gt;This is a quick post about a gotcha I ran into today with Hudson and SVNANT. &lt;/p&gt;  &lt;h2&gt;The Ant Target&lt;/h2&gt;  &lt;pre class="xml" name="code"&gt;&amp;lt;property name=&amp;quot;libdir&amp;quot; location=&amp;quot;lib&amp;quot; /&amp;gt;
&amp;lt;path id=&amp;quot;classpath&amp;quot;&amp;gt;
	&amp;lt;fileset dir=&amp;quot;${libdir}&amp;quot; includes=&amp;quot;*.jar&amp;quot; excludes=&amp;quot;svnant.jar&amp;quot; /&amp;gt;
&amp;lt;/path&amp;gt;
&amp;lt;typedef resource=&amp;quot;org/tigris/subversion/svnant/svnantlib.xml&amp;quot; classpathref=&amp;quot;classpath&amp;quot; /&amp;gt;&lt;/pre&gt;
...bunch of stuff 

&lt;pre class="xml" name="code"&gt;&amp;lt;svn  username=&amp;quot;mesher&amp;quot; password=&amp;quot;mesher&amp;quot;&amp;gt;
	&amp;lt;update dir=&amp;quot;${src}${path}&amp;quot;  /&amp;gt;
&amp;lt;/svn&amp;gt;&lt;/pre&gt;
...some other stuff 

&lt;h2&gt;The Problem&lt;/h2&gt;

&lt;p&gt;I ran the Hudson build, and I got the dreaded &amp;quot;[echo] Error updating dev: Cannot use javahl nor command line svn client&amp;quot;&lt;/p&gt;

&lt;h2&gt;Debugging&lt;/h2&gt;

&lt;p&gt;The first thing I did was throw this into my build file, right above the svn task:&lt;/p&gt;

&lt;p&gt;&amp;lt;echoproperties/&amp;gt;&lt;/p&gt;

&lt;p&gt;This quickly showed me the problem: the ANT_HOME directory had svnant jars in there, and so the svn task was using those old jars and NOT the jars I had specified on my classpath.&lt;/p&gt;

&lt;h2&gt;The Solution&lt;/h2&gt;

&lt;p&gt;I did two things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Remove those jars from the lib dir of my ant install. I do not remember how they got there, but they should not have been there and were thus evicted &lt;/li&gt;

  &lt;li&gt;Started using svnkit instead of javahl. Thus, the svn task now looks like this: &lt;/li&gt;
&lt;/ol&gt;

&lt;pre class="xml" name="code"&gt;&amp;lt;svn  username=&amp;quot;mesher&amp;quot; password=&amp;quot;mesher&amp;quot; svnkit=&amp;quot;true&amp;quot; javahl=&amp;quot;false&amp;quot;&amp;gt;
	&amp;lt;update dir=&amp;quot;${src}${path}&amp;quot;  /&amp;gt;
&amp;lt;/svn&amp;gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;Bottom Line&lt;/h2&gt;

&lt;p&gt;Don’t let friends put svnant jars in your ant_home lib directory&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-6957958532655914180?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/6957958532655914180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=6957958532655914180' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/6957958532655914180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/6957958532655914180'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/09/using-svnant-in-your-ant-build-files.html' title='Using SVNANT in your ANT build files with Hudson'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-4069764507026262923</id><published>2009-09-16T05:24:00.002-04:00</published><updated>2009-09-16T05:34:30.833-04:00</updated><title type='text'>JetBrains to Include MXUnit Support in CFML plug-in for IntelliJ IDEA</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;a href='http://www.jetbrains.com/idea/'&gt;IntelliJ IDEA&lt;/a&gt; is a great Java IDE and the recent&lt;a href='http://coldfusion-in-idea.blogspot.com/'&gt; plugin for CFML&lt;/a&gt; is a nice addition to their suite. I've been following their progress and they offer a competitive commercial alternative to Eclipse flavored development. With the addition of both Flex and CFML in IDEA, this broadens the toolset and abilities for developers who would normally be coding in Java using IDEA. So, it was with excitement when I read that the talented folks at JetBrains are considering adding support for &lt;a href='http://mxunit.org/'&gt;MXUnit&lt;/a&gt; in their CFML plugin for IDEA : &lt;a href='http://coldfusion-in-idea.blogspot.com/2009/09/mxunit.html'&gt;http://coldfusion-in-idea.blogspot.com/2009/09/mxunit.html&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;Natually, los hombres at MXUnit are &lt;i&gt;always&lt;/i&gt; happy to discuss framework and tool integration with anyone in oder to get the best tools in the hands of developers and to support better software quality all around.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;Test and be Happy!&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=d72ea1e6-45f1-85f6-abeb-a3e2952e7ca0' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-4069764507026262923?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/4069764507026262923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=4069764507026262923' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/4069764507026262923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/4069764507026262923'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/09/intellij-to-include-mxunit-in-cfml-plug.html' title='JetBrains to Include MXUnit Support in CFML plug-in for IntelliJ IDEA'/><author><name>bill shelton</name><uri>http://www.blogger.com/profile/06624894387927690246</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='17359140296736057249'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-3337707966258917674</id><published>2009-09-11T05:45:00.000-04:00</published><updated>2009-09-11T05:59:39.719-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Best Practices'/><category scheme='http://www.blogger.com/atom/ns#' term='noise control'/><category scheme='http://www.blogger.com/atom/ns#' term='timesavers'/><title type='text'>Same Application, Multiple Locations: How I want to work</title><content type='html'>&lt;style&gt;


#main br {display:none}&lt;/style&gt;  &lt;p&gt;I work on 3 computers: work, home, and laptop. At home, I have VMs set up for tinkering in different operating systems. Naturally, though I do different kinds of work on each machine, there are commonalities. I use Eclipse extensively on all 3 and in the VMs. I have various app servers set up. I use Live Writer for blogging on all 3 machines. Then there’s firefox, chrome, tweetdeck. Then there’s little stuff like Notepad2 and hippoedit.&lt;/p&gt;  &lt;p&gt;It was brought home to me recently, when I reformatted my laptop, that maintaining these apps across multiple computers is a real hassle. But it’s not just initial download and install. It’s those times where you fire up your editor, go to do something, and realize, “Oh, crap, that plugin isn’t on this machine…” Or “Wait… I thought I installed the Eclipse SWT examples. Where the hell are they? Oh, that’s right, that was at home”. Or I alt-space for Launchy, type “delicious &amp;lt;tab&amp;gt; [some search term]” and it doesn’t search my delicious bookmarks. Or I open firebug, go for the google page speed tab, and it’s not there. Or I go to Facebook and I see those damned app posts and I swear I have a greasemonkey script installed that hides those retched beasts, but there they are! Or you right click on some file in Eclipse, select “compare with local history”, and you don’t have any local history because you forgot to set the local history setting to a year instead of the default 7 days.&lt;/p&gt;  &lt;p&gt;And databases. Don’t even get me started on databases.&lt;/p&gt;  &lt;p&gt;It’s these little things. These things that break my flow, that break my concentration, that cost me time.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Time is money.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Bullshit. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Time is more important than that.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;At work, in an office with precious little continuous chunks of uninterrupted time to get into flow and get things done, Time is momentum.&amp;#160; The beancounters and bosses call it “productivity”, but they don’t really understand this anyway because they schedule daily meetings at developer-energy-happy-hour so their label for it is meaningless to me. At home, time is peace. It’s freedom. It’s when I learn. And these are what I lose when the Monkey Work slows me down.&lt;/p&gt;  &lt;p&gt;This makes me wonder: Why does it have to be this way? Wouldn’t it be lovely to have all of these applications work like a AAA card, where the benefits follow me, not the hardware? &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Imagine:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You fire up Eclipse, and it’s the same install that you have at work. It has the same plugins. It has the same configuration. Maybe it even has the same projects.&lt;/p&gt;  &lt;p&gt;You fire up firefox, and it has the same extensions, themes, and greasemonkey scripts.&lt;/p&gt;  &lt;p&gt;You alt-space, hit “sql server start”, and the damn server starts instead of being met with Launchy’s [I don’t know what you want to do so I guess you wanna search Google] because the server isn’t installed.&lt;/p&gt;  &lt;p&gt;You create a new project on github one night after your wife goes to bed, you install the Eclipse git plugin to give it a whirl, you finally (finally!) get the damn thing configured right, you go to bed at 1:00 AM after wrestling with that alligator, and you get to work the next day, &lt;strong&gt;log in&lt;/strong&gt; to Eclipse, and there it all is, waiting for you, for free (NOT money free… time free). Magic.&lt;/p&gt;  &lt;p&gt;You go to write a new blog post inspired about being pissed off because you have to install the damn Live Writer templates plugin and recreate all your “templates” that you have at home, and… they’re already there, waiting for you. For free.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;This is how I want to work&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;I’m tired of maintaining installations. Images and Ghosts and VMs you carry with you do not get you this. They get you part way, but they’re “heavy” and incomplete and slow. I want it lighter, and faster, and frictionless.&lt;/p&gt;  &lt;p&gt;I want my apps when I want them. &lt;/p&gt;  &lt;p&gt;There are partial workarounds, but none of them get you this kind of magic. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Let’s break it down:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I reckon we are contending with at least 4 different Quantities here: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The application itself &lt;/li&gt;    &lt;li&gt;The application’s “extensions” &lt;/li&gt;    &lt;li&gt;The application’s configuration (settings) &lt;/li&gt;    &lt;li&gt;The data for which the application was born to manipulate (in the case of your IDE, this would be your projects) &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Sharing the application among multiple installs is generally the most difficult. Some thoughts on current solutions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Keeping them on USB sticks and carrying them with you wherever you go. This is a start, but it’s far from ideal, largely because it relies on the most unreliable component in the entire equation: You. &lt;/li&gt;    &lt;li&gt;For large apps like appservers and database servers, I do not know if there are any “good” solutions. &lt;/li&gt;    &lt;li&gt;I could completely imagine, however, keeping Railo -- which I do not use at work but which I have to use for testing MXUnit -- in Dropbox. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Sharing extensions is easier, but still problematic. Current solutions vary based on the app (obviously), but these come to mind:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;For Eclipse, you can export your update sites to a file, send that file to yourself (or whatever means you have of moving a file from one machine to another, like Dropbox), and then import the file. From there, you follow the normal Eclipse update process, which simply drops files into a known location on the target machine. &lt;/li&gt;    &lt;li&gt;There’s also Pulse and Yoxos for Eclipse. I tried Pulse and hated it because of the stranglehold it puts on extensions. I have not tried Yoxos, though it’s possible that it's hosted service comes close to what I’m looking for. &lt;/li&gt;    &lt;li&gt;For Firefox, there’s the excellent FEBE extension which will export your extensions, themes, and other stuff. From there, you follow roughly the same model as I described above for Eclipse. &lt;/li&gt;    &lt;li&gt;For LiveWriter, there’s... Nothing (that I know of) &lt;/li&gt;    &lt;li&gt;For Launchy, I don’t know of anything. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Sharing configuration is the easiest because so many applications at least have some facility for export. &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;You can export your bookmarks in Firefox. &lt;/li&gt;    &lt;li&gt;You can export your settings for Eclipse. &lt;/li&gt;    &lt;li&gt;With something like PasswordSafe, you can save your password database file anywhere and share that file. &lt;/li&gt;    &lt;li&gt;For your PHP install you can share php.ini in whatever way you transport them from one machine to the next. &lt;/li&gt;    &lt;li&gt;Go look in your favorite apps and see if there’s an import/export facility. Hopefully there is. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Sharing data is a quagmire. Current solutions might include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;For mysql, you can share the database file directories &lt;/li&gt;    &lt;li&gt;For projects, at least for personal projects you might want to have installed on multiple machines, you can use svn or git hosting and get them on each machine with ease. The hurdle here is with work projects, where you don’t want to share the source code on your other machines. But you *do* want to share them across teams. Again, SCM solutions are critical here. Pulse can support this, too, though as I said I’m not a fan. &lt;/li&gt;    &lt;li&gt;For SQL Server and other “enterprise-y” databases, you’re limited to .bak file export and import. For schema changes, you could use SCM or manually create transformation scripts. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So options do exist for mitigating the pain, to some extent. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;There’s still pain&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Still… even for apps that do provide import/export, you have to take action. You have to push (export –&amp;gt; transport), and you have to pull (import). You have to carve a chunk of time from the “Things I love to Do” part of your discretionary hours and sacrifice them to the Monkey Work part. And this tradeoff is where people like me bristle.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;It’s not all bleak&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Transport pain can, to some extent, be further reduced via Dropbox. For me, the most seamless experience I’ve had is with PasswordSafe. I had to install it on all 3 machines, but I keep my password database in my dropbox folder and so the friction is Zero. I’m considering keeping my Eclipse install in there, too, which would largely alleviate Quantities 1 and 2 (app and extensions) but not configuration. But even there, I can export the settings file to dropbox and save myself a little hassle. &lt;/p&gt;  &lt;p&gt;I’m going to stay on the lookout for other ways I can use dropbox to share apps, extensions, and settings.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Who gets it right?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The granddaddy (to me, anyway) of data sharing is Delicious bookmarks. No, it’s not an app. But it’s still extremely useful to how I work. If applications worked like Delicious, I’d be happy.&lt;/p&gt;  &lt;p&gt;Tweetdeck gets it right with the ability to share columns, provided you sign up for an account. Mix that with the very low friction way in which Adobe AIR handles application updates, and you’ve got a satisfactory solution. It’s a one-time install, but from there, you don’t think about it again. You don’t think about updates, and you don’t think about configuration. I like that.&lt;/p&gt;  &lt;p&gt;Mint.com gets it right. But wait… they’re a website. Of course they get it right… it’s a damn website! Hear me out. I was a longtime MS Money user, and I couldn’t imagine an application that could replace what I got from Money. Then MS went and completely hosed Money with the 2008 release, which sent me looking for replacements, namely, Quicken. But Quicken couldn’t import all my data. So you know what I did… I punted. I said “I don’t care about the historical data, because I’m going to have to start from scratch anyway if I drop MS Money”. I tried out Mint, and lo and behold, it’s &lt;strong&gt;better&lt;/strong&gt; than Money ever was in terms of helping me keep track of where the money goes. It’s Better! It’s faster! What?! Yes, I know, it makes no sense. But it’s superior, and I hold it up as a model of how a web app can transcend a native app. &lt;/p&gt;  &lt;p&gt;Acrobat.com gets it right, as does Google docs, for sharing documents. This is not merely document management. These are applications that span document creation and sharing. With these apps, you do not &lt;em&gt;need&lt;/em&gt; word processing or spreadsheet software anymore.&lt;/p&gt;  &lt;p&gt;iTunes gets it right. I plop my iPhone in the dock and I get podcasts on my computer and phone.&amp;#160; Oh, wait. I can’t do that on more than one machine. Scratch that. FU, iTunes. You were so close. But you failed.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The problem with Cloud-based apps&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The obvious problem with “not firing up Eclipse, but &lt;em&gt;logging in&lt;/em&gt; to Eclipse”, is performance. Imagine if Eclipse were now a JavaFX app that, when I launched it, from any computer, would contain all my plugins, all my preferences, and potentially (ideally, configurable) my projects. Or, better yet, I login and and say “give me [my&amp;#160; home project set]”.&amp;#160; How can an app like this possibly perform as well as a native app? I do not know. I hope they figure this out.&lt;/p&gt;  &lt;p&gt;The other clear problem is security. Do I really want my source code out there in space? OK, fine. So maybe projects themselves are optionally shareable.&lt;/p&gt;  &lt;p&gt;Functionality is another. Sure, I can write docs with Buzzword. But can I [insert thing I can’t do here]? Nope… I can’t do mail merge. I can’t hook it into an LDAP server. I can’t do that “Track Changes” stuff with the 4 point red font in the right margin thing (or can I… it just looks different?). Perhaps functionality is one of those areas where we’re so afraid of losing a feature we think we need but when, on inspection, we really don’t, that’s keeping us from embracing this kind of technology. Perhaps the little sticky note tabs on Acrobat.com indicating the changes from one version to the next are, in fact, &lt;em&gt;good enough&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;And certainly the infrastructure cost associated with this model is a huge barrier. It quite likely won’t come without a price. But it’s a different cost. It’s money. And I’d pay money to get back my Time.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Where do we go from here?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I’d like to hear from you: how do you contend with this issue? How do you maintain applications across computers? How do you protect the stuff you want to protect and share the stuff you feel isn’t a threat to your livelihood if you lost it? And do you know of other applications that get it right? What’s out there in this amazing world that I and others don’t know about but which helps reduce the maintenance of applications across multiple machines, and even across multiple operating systems?&lt;/p&gt;  &lt;p&gt;Considering application, extension, and configuration, how do you save Time?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-3337707966258917674?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/3337707966258917674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=3337707966258917674' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/3337707966258917674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/3337707966258917674'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/09/same-application-multiple-locations-how.html' title='Same Application, Multiple Locations: How I want to work'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1973750947775262558.post-1091757961752483253</id><published>2009-09-07T15:53:00.001-04:00</published><updated>2009-09-07T15:53:32.506-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogging'/><category scheme='http://www.blogger.com/atom/ns#' term='timesavers'/><title type='text'>Saving Insert Picture settings in Windows Live Writer</title><content type='html'>&lt;p&gt;Here’s a how-to for something that’s annoyed me about Windows Live Writer since I started using it several months back. &lt;/p&gt;  &lt;h2&gt;The Problem&lt;/h2&gt;  &lt;p&gt;When inserting a picture into a Live Writer blog post, I always want to a) have the picture open in new window and b) change the linked-to picture to appear in its original size. I could not find&amp;#160; a way in Live Writer to set these as defaults; consequently I had to make these changes to every picture I inserted. &lt;/p&gt;  &lt;p&gt;That. Sucks.&lt;/p&gt;  &lt;h2&gt;The Solution&lt;/h2&gt;  &lt;p&gt;Found right in the Live Writer Help:&lt;/p&gt;  &lt;p&gt;“To apply the properties of the current picture to all pictures that you insert in the future, in the &lt;strong&gt;Picture&lt;/strong&gt; pane, click the &lt;strong&gt;Picture&lt;/strong&gt; tab, and then click &lt;strong&gt;Save settings as default&lt;/strong&gt;.”&lt;/p&gt;  &lt;p&gt;Sure enough… it’s there. In the bottom right. Exactly where I’d expect it not to be. But hey, who am I to complain… It’s free. And this is how you do what I wanted it to do, so ‘nuff bitching. Enjoy!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/__j-6QTK4wT8/SqVkuhQaNRI/AAAAAAAAALM/tcyKvoopErs/s1600-h/sshot-1%5B7%5D.png" target="_blank"&gt;&lt;img title="sshot-1" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="156" alt="sshot-1" src="http://lh5.ggpht.com/__j-6QTK4wT8/SqVkuwlMYqI/AAAAAAAAALQ/6F0-7Ihn6tA/sshot-1_thumb%5B4%5D.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1973750947775262558-1091757961752483253?l=blog.mxunit.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.mxunit.org/feeds/1091757961752483253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=1973750947775262558&amp;postID=1091757961752483253' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/1091757961752483253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1973750947775262558/posts/default/1091757961752483253'/><link rel='alternate' type='text/html' href='http://blog.mxunit.org/2009/09/saving-insert-picture-settings-in.html' title='Saving Insert Picture settings in Windows Live Writer'/><author><name>Marc Esher</name><uri>http://www.blogger.com/profile/05942611191966201181</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='08495646389580511931'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>