<?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' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6713689</id><updated>2011-11-27T18:22:29.593-06:00</updated><category term='show'/><category term='reflection'/><category term='javascript'/><category term='mock objects'/><category term='dynamic'/><category term='android development'/><category term='singleton'/><category term='porcelain'/><category term='os x'/><category term='open source'/><category term='grad school'/><category term='bike'/><category term='grails'/><category term='cisco'/><category term='css'/><category term='agile'/><category term='frameworks'/><category term='netflix'/><category term='git'/><category term='spring'/><category term='dynamicweb'/><category term='iesucks'/><category term='sun'/><category term='nodejs'/><category term='prototypal'/><category term='maintenance'/><category term='oauth'/><category term='progressive enhancement'/><category term='webdev'/><category term='greasemonkey'/><category term='work'/><category term='acegi'/><category term='dependency injection'/><category term='user experience'/><category term='jsf'/><category term='shell scripting'/><category term='personal'/><category term='austin'/><category term='java'/><category term='refactoring'/><category term='patterns'/><category term='ajax'/><category term='security'/><category term='semantic web'/><category term='programming'/><category term='shipping is a feaure'/><category term='ux'/><category term='teams'/><category term='langauges'/><category term='dwr'/><category term='duct tape programmer'/><category term='mvc'/><category term='jquery'/><category term='android'/><category term='groovy'/><category term='software'/><category term='html'/><category term='code quality'/><category term='slicehost'/><category term='mac'/><category term='worse is better'/><category term='dropbox'/><category term='design'/><category term='vpn'/><category term='project management'/><category term='fun'/><category term='testing'/><category term='architecture'/><category term='stubs'/><category term='extjs'/><category term='prototype'/><category term='json'/><category term='ioc'/><title type='text'>noah's blog</title><subtitle type='html'>Technical and occasionally personal junk. Groovy, Grails, JavaScript and one or two Java posts. Updated whenever I feel guilty. Sometimes there's something about bikes.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>37</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6713689.post-1286372872630373719</id><published>2010-09-27T09:07:00.005-05:00</published><updated>2010-09-27T13:46:44.400-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android development'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android - Reliable Alarms to Services</title><content type='html'>I love programming for Android. The APIs just make sense. You can tell that fluent Java developers designed this thing. Despite the fact that everyone's favorite criticism is that Android is "fragmented" I haven't had any significant cross-hardware issues. Follow the guidelines (What?!? I have to follow rules if I want my app to work? So much for freedom...) and 95% of apps should just work on any platform without much trouble. I'd say you're even a step ahead of iOS development because the platform has extremely simple ways to support multiple screen sizes, so your app can easily look good on any device. That said, there are occasional bugs, and this post is about one of them.&lt;br /&gt;&lt;br /&gt;This may not even be a bug, but rather a case of poor documentation. The problem arrises when you use the &lt;a href="http://developer.android.com/reference/android/app/AlarmManager.html"&gt;AlarmManager&lt;/a&gt; to schedule a repeating alarm that is supposed to wake the phone and start a service. e.g.,&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;PendingIntent pi = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);&lt;br /&gt;alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timeToStart, 15 * 60 * 1000, pi);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It will probably work great during most of your testing as the phone will be awake. However, once you stick your phone in your pocket and forget about it for a while, you'll realize, "Hey, wasn't an alarm supposed to go off?" You'll pull your phone out, turn it on, and suddenly it will go off. The first few times you'll think it's odd, until you realize that the alarms aren't going off when the phone has been asleep for awhile, but they are delivered as soon as it wakes.&lt;br /&gt;&lt;br /&gt;Hopefully you find this post or something like it and don't have to spend days Googling to figure out that only a &lt;a href="http://developer.android.com/reference/android/content/BroadcastReceiver.html"&gt;BroadcastReceiver&lt;/a&gt; can reliably receive a wakeup alarm and then spend another day learning that the &lt;a href="http://developer.android.com/reference/android/content/Context.html"&gt;Context&lt;/a&gt; that&amp;nbsp;&lt;a href="http://developer.android.com/reference/android/content/BroadcastReceiver.html#onReceive(android.content.Context, android.content.Intent)"&gt;onReceive&lt;/a&gt;&amp;nbsp;gets &lt;s&gt;can't start services. The &lt;/s&gt;&lt;a href="http://groups.google.com/group/tts-for-android/browse_thread/thread/198c0dc54c635b64"&gt;&lt;s&gt;solution&lt;/s&gt;&lt;/a&gt;&lt;s&gt; is pretty simple, but you'd never figure it out from the documentation.&lt;/s&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;EDIT: I may be totally wrong about the context being a problem as you can see in the comments. Try it without the using getContext first and if you don't have any problems getting the service to start, avoid the &lt;/i&gt;&lt;a href="http://en.wikipedia.org/wiki/Cargo_cult"&gt;&lt;i&gt;Cargo Cult&lt;/i&gt;&lt;/a&gt;&lt;i&gt; code I'm using below. If you do have problems and the context trick helps, please let me know in the comments.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;import android.content.BroadcastReceiver;&lt;br /&gt;import android.content.Context;&lt;br /&gt;import android.content.Intent;&lt;br /&gt;import android.content.pm.PackageManager.NameNotFoundException;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class AlarmProxy extends BroadcastReceiver {&lt;br /&gt;&lt;br /&gt;    Context getContext(Context ctx) {&lt;br /&gt;        try {&lt;br /&gt;            return ctx.createPackageContext("com.yourpackage.ofyourapp", 0);&lt;br /&gt;        } catch (NameNotFoundException ignore) {}&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;    @Override&lt;br /&gt;    public void onReceive(Context ctx, Intent intent) {&lt;br /&gt;        Context context = getContext(ctx);&lt;br /&gt;        Intent newIntent = new Intent(context, YourService.class);&lt;br /&gt;        newIntent.setData(intent.getData());&lt;br /&gt;        newIntent.putExtras(intent);&lt;br /&gt;        context.startService(newIntent);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The context your receiver gets is probably a &lt;code&gt;ReceiverRestrictedContext&lt;/code&gt;&lt;s&gt; which isn't connected to your application and can't start services, so &lt;/s&gt;you may need to use &lt;code&gt;createPackageContext&lt;/code&gt;&amp;nbsp;to get your app context and start your service. You'd then set alarms by sending them to your receiver:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Intent intent = new Intent(this,AlarmProxy.class);&lt;br /&gt;// ...&lt;br /&gt;PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);&lt;br /&gt;alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timeToStart, 15 * 60 * 1000, pi);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Happy alarming!&lt;br /&gt;&lt;br /&gt;EDIT: Don't forget to register the receiver in your Android manifest:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;receiver android:name=".AlarmProxy"&amp;gt; &amp;lt;/receiver&amp;gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-1286372872630373719?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/1286372872630373719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=1286372872630373719' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1286372872630373719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1286372872630373719'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2010/09/android-reliable-alarms-to-services.html' title='Android - Reliable Alarms to Services'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-7694076804968245574</id><published>2010-07-26T10:00:00.003-05:00</published><updated>2010-07-26T10:00:02.952-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='progressive enhancement'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>A Grails Porcelain Ajax Framework - Part I: Component Refresh</title><content type='html'>&lt;h3&gt;The Foundation&lt;/h3&gt;The foundation of a good &lt;a href="http://iamnoah.blogspot.com/2010/07/how-to-build-ajax-framework.html"&gt;porcelain Ajax framework&lt;/a&gt; is component refresh, i.e., refreshing an area of the page with new/updated information. Component refresh is equivalent to reloading the page, but provides a better user experience since it happens&amp;nbsp;asynchronously, and reduces the amount of work the server has to do. &amp;nbsp;Because we are requesting a block of HTML from the server, we don't have to write any additional JS to update the page. &lt;a href="http://api.jquery.com/load/"&gt;jQuery.load&lt;/a&gt; does all the heavy lifting. With component refresh it becomes trivial to Ajax enable pagination, sorting, filtering, lazy loading, tabs and many other actions for a better user experience and better performance.&amp;nbsp;In this post, we'll learn how to create a&amp;nbsp;porcelain&amp;nbsp;Ajax framework with component refresh using Grails.&lt;br /&gt;&lt;h3&gt;The App&lt;/h3&gt;Porcelain frameworks are usually built around an application. For our purposes, lets say we have a simple app for creating, listing, viewing and editing products. The products have a name, price, and description. Additionally, each product can be viewed in four different colors. In our app, the only difference between colors will be the image that is displayed for the product, but the different colors could easily be different tabs of product information, or different configurations of the product.&lt;br /&gt;&lt;br /&gt;All our work will be on the product list, which will look like this:&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_ZS-2AgZmgD0/TEoUoW4E3uI/AAAAAAAABUA/ipGnODEEDdM/s1600/grails-ajax-product-list.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="491" src="http://2.bp.blogspot.com/_ZS-2AgZmgD0/TEoUoW4E3uI/AAAAAAAABUA/ipGnODEEDdM/s640/grails-ajax-product-list.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;our made up products list&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Project&lt;/h3&gt;We start with a standard Grails project and add a Product domain class and generate the controller and views. How to do all that with Grails is out of scope for this discussion, but it's pretty easy.&lt;br /&gt;&lt;br /&gt;By default, Grails lists products in a table. Typically products are listed as "cards" to give them more room, so we'll enhance the markup slightly:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/488131.js?file=gistfile1.rhtml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;At this point we haven't written a line of Ajax code, we're just creating a simple app that will work even with JS disabled. In anticipation of adding Ajax functionality though, we should break the list page up into the components that we plan to refresh. To do this, we'll make use of the &lt;a href="http://www.grails.org/doc/1.1/ref/Tags/include.html"&gt;g:include&lt;/a&gt; tag, which allows us to inline another controller action in our page. We'll create two new controller actions and adjust our templates accordingly:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/488142.js?file=gistfile1.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Notice the original list code has moved into renderList and we return productIds instead of the actual product object.&lt;br /&gt;&lt;br /&gt;And we replace the list in list.gsp with&amp;nbsp;g:include controller="product" action="renderList". renderList.gsp is just:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/489050.js?file=gistfile1.rhtml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;and renderProduct.gsp is the product div above.&lt;br /&gt;&lt;br /&gt;For the colors pages, we're going to reuse renderProduct:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/489054.js?file=gistfile1.rhtml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;and that's it. We now have all our functionality setup and it all works even with JavaScript disabled. Time for some progressive enhancement.&lt;br /&gt;&lt;h3&gt;The Framework&lt;/h3&gt;The core of our component refresh implementation is going to be &lt;a href="http://www.grails.org/doc/1.1/ref/Tags/include.html#"&gt;g:include&lt;/a&gt;. Since g:include is plumbing, we need to ensure that our porcelain covers it very thinly to make future extension easy. One option would be to &amp;nbsp;use Groovy meta-programming magic to intercept calls to the built in Grails taglib where g:include is. This &amp;nbsp;has the advantage of being transparent to the user. We don't have to worry about using the right tag, and if we already have a lot of existing code using g:include, this would be the way to go. However, it has the disadvantage of being complicated. If we're starting from scratch, it's much simpler to define our own tag. So enter the FrameworkTaglib:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/489065.js?file=gistfile1.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Instead of g:include, we will use ajax:include.&amp;nbsp;The new tag does two thing. First, it wraps the content of the component in a div with the class "ajax-component" so that out framework JavaScript will know that it's a component. Secondly, it sets the id of that div to the controller action and optional id for the include. That will allow us to call the correct action from our Ajax requests.&lt;br /&gt;&lt;br /&gt;The second part of our framework is framework.js:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/489068.js?file=framework.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;refresh&lt;/code&gt; is also a very thin wrapper, this time around &lt;code&gt;jQuery.load&lt;/code&gt;. It has the nice feature of allowing us to use any element inside a component as a representative of the component. Also, we don't have to pass a URL, and can pass a data string or object, just like &lt;code&gt;jQuery.load&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;With these two components, our framework is ready! Our first task will be to Ajax enable the color links so we can view the different colors without leaving the list:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/489074.js?file=application.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;With our framework code in place, it couldn't be simpler. We strip the query string off of the link and pass it as data to refresh and we're done. The color links now refresh the individual products in place, for a greatly improved user experience. Also, notice we use &lt;a href="http://api.jquery.com/delegate/"&gt;jQuery.delegate&lt;/a&gt; so that when the component is refreshed we don't have to reattach event handlers.&lt;br /&gt;&lt;br /&gt;So that was easy, but what about pagination? Surely it will be a bit more work to Ajax enable pagination.&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/489081.js?file=application.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Or maybe it's the exact same code. It looks like progressively enhancing links in this way might be something to add to framework.js. Notice that we can refresh the entire list as a component, but also have nested components that can be refreshed individually.&lt;br /&gt;&lt;br /&gt;In very little code, we've built a framework that has allowed us to progressively Ajax enhance both pagination and content toggle in about seven lines of JS. But lets take an objective look at what this framework does well and what might be problematic.&lt;br /&gt;&lt;br /&gt;You can download the complete project to this point &lt;a href="http://github.com/iamnoah/Grails-Ajax/zipball/part1"&gt;from GitHub&lt;/a&gt;.&lt;br /&gt;&lt;h3&gt;The Good&lt;/h3&gt;There is a lot to like about the framework as it stands.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Very simple usage.&lt;/li&gt;&lt;li&gt;We take advantage of progressive enhancement. Normal links become refreshes very easily.&lt;/li&gt;&lt;li&gt;The whole framework is less than 50 lines of code at this point.&lt;/li&gt;&lt;li&gt;Components can be nested inside other components.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;The Bad&lt;/h3&gt;Using this code as is on a serious project is probably not the best idea for a few reasons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;All components are wrapped as divs. That means refreshing something like a table row is impossible.&lt;/li&gt;&lt;li&gt;In framework.js we assume that the default URL mapping of "/$controller/$action?/$id?"&amp;nbsp;is used, which may not be the case, in which case refresh will fail.&lt;/li&gt;&lt;li&gt;We have to pass all the parameters to refresh. For just progressively enhancing links, this isn't such a big deal since the link should have all the parameters, but as we get into more advanced features, it will become a pain point.&lt;/li&gt;&lt;li&gt;Several features of &lt;a href="http://www.grails.org/doc/1.1/ref/Tags/include.html#"&gt;g:include&lt;/a&gt; will not work. In particular, the model and params attributes will not be present in a refresh. For simple cases, that's not a problem, but a seriously application will quickly feel the pain of such limitations.&lt;/li&gt;&lt;li&gt;Two nitpicks&lt;/li&gt;&lt;ul&gt;&lt;li&gt;We use the namespace "ajax" for the taglib, which is not likely to be unique. Another poorly written plugin could cause problems.&lt;/li&gt;&lt;li&gt;We use the id attribute to store the controller action information. A class might be more appropriate, if a little harder to parse.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;h3&gt;The Conclusion&lt;/h3&gt;The core idea of a good component refresh is being able to pair together the view (GSP) and the code that generates the model (the controller action). This pairing allows us to treat each component as it's own entity, making refresh and other advanced features possible.&amp;nbsp;Grails and jQuery provided us with some very nice pipes to start with, so creating the component refresh porcelain was perhaps easier than it would normally be, but I think the simplicity helps the underlying concepts to show more easily.&lt;br /&gt;&lt;br /&gt;Next time we will build multi-component refresh and try to fix some of the problems with our framework. It's not good from much beyond basic&amp;nbsp;enhancement at this point, but we're off to a good start.&lt;br /&gt;&lt;br /&gt;Remember, you can download the complete project to this point &lt;a href="http://github.com/iamnoah/Grails-Ajax/zipball/part1"&gt;from GitHub&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-7694076804968245574?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/7694076804968245574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=7694076804968245574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7694076804968245574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7694076804968245574'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2010/07/grails-porcelain-ajax-framework-part-i.html' title='A Grails Porcelain Ajax Framework - Part I: Component Refresh'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ZS-2AgZmgD0/TEoUoW4E3uI/AAAAAAAABUA/ipGnODEEDdM/s72-c/grails-ajax-product-list.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-8173254582844085328</id><published>2010-07-22T15:45:00.001-05:00</published><updated>2010-07-23T11:08:58.637-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='porcelain'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>How to Build an Ajax Framework</title><content type='html'>&lt;h3&gt;Plumbing &amp;amp; Porcelain&lt;/h3&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;I've built three or four Ajax "frameworks" in my career. I don't know if you would call them frameworks because there are really two kinds of things I mean when I say "framework". There is the&amp;nbsp;extremely general purpose&amp;nbsp;&lt;b&gt;plumbing&amp;nbsp;&lt;/b&gt;framework, which can do anything, but as a result leaves you to write a good bit of code and maybe pick and choose which parts you need. Some examples of plumbing type Ajax frameworks/components would include sever side frameworks like DWR, Ajax4JSF, etc. but also client side frameworks like dojo, Scriptaculous, jQuery, etc. Also most of the Rails type server frameworks have Ajax support built in: e.g., Grails and Django.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Then there are the&amp;nbsp;&lt;b&gt;porcelain&amp;nbsp;&lt;/b&gt;frameworks. The problem with the plumbing frameworks is that they can do anything, so you're presented with a big toolbox full of neat things and a bunch of pipes, but you have to put it all together. A porcelain Ajax framework is usually built by an organization for their apps, or even for a single application. Sometimes they become an entire platform internal to the application and sometimes no thought is put into developing the porcelain and you end up with each developer doing Ajax in their own way.&lt;/div&gt;&lt;h3&gt;Inner Platforms &amp;amp; Thoughtless Scaffolding&lt;/h3&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Some developers recoil at the thought of internal platforms. They tend to make a few use cases easy but then require horrible black voodoo workarounds when trying to do something the original&amp;nbsp;architects&amp;nbsp;didn't think of. &amp;nbsp;Other developers are completely frustrated with the thoughtlessly thrown together and generally rickety Ajax platform they've been trying to maintain.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;An inner platform sometimes arises&amp;nbsp;when otherwise highly competent enterprise (read: Java or .Net) developers first encounter front-end programming and dynamic&amp;nbsp;languages. &amp;nbsp;They are used to structure and standards and ACID properties and so forth. This lack of static types and compilers instills a certain sense of fear and the only way to conquer that fear is to create "coding standards" and, then when those are not followed, to create an internal UI framework that forces everyone to code in a certain way, without closures, functional programming, overloaded operators, dynamic dispatch, and all those other ugly hacks that are bad for performance.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Other times, an inner platform is really just the result of well intentioned senior developers trying to make things easier for the more junior members of the team. Unfortunately, they often do so by hiding important information and you end up with a very&amp;nbsp;&lt;a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html"&gt;leaky abstraction&lt;/a&gt;&amp;nbsp;that is buggy and that the users (programmers other than the authors) are completely helpless to fix because they have no experience with the underlying framework. The points is that there are many ways to end up with an inner platform that does more harm than good.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Thoughtless&amp;nbsp;scaffolding on the other hand is just the result of... thoughtlessness. Most often it's because a programmer without much experience and no real computer science training is writing all the code and whatever tool he's read about today is the perfect tool for the job. But it also happens when a new project is started and the technical leadership fails to identify the patterns that should be used. Maybe they start off with some vague notion like,&amp;nbsp;&lt;a href="http://iamnoah.blogspot.com/2010/07/json-is-overrated.html"&gt;"JSON is the answer,"&lt;/a&gt;&amp;nbsp;and become&amp;nbsp;committed&amp;nbsp;to a bad strategy early on and never have the time or the courage to go back and clean it up.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Both extremes have problems, but they also have advantages. For the tasks it was built for, the inner platform makes adding &amp;nbsp;new Ajax features extremely simple. On the other hand, the thoughtless&amp;nbsp;scaffolding&amp;nbsp;never gets in the way. Because very little of it is connected, it's easy to rip part of it out and build something new entirely.&amp;nbsp;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;We want to find a middle ground between over engineered and thrown together, but where that middle ground lies can depend a lot on whether maintenance or new features are your priority.&amp;nbsp;Instead we will focus on the core principles and features that any porcelain Ajax framework should encompass.&lt;/div&gt;&lt;h3&gt;Core Principles&lt;/h3&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;These are the core principles I have learned through trial an error over the past 5 years, building and using frameworks across the spectrum from somewhat thoughtless to a massive inner platform:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Remember it's a web app&lt;/b&gt;&amp;nbsp;- It's not a desktop app. You're probably not build the next Gmail, so stick with what works. Use semantic markup, keep the pages simple and light, and use progressive enhancement so the app works without JS.&amp;nbsp;For public facing apps this is a must obviously, but even for internal apps where you know that your users have a decent browser with JS enabled, you will stay out of trouble by keeping it simple.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Do everything you can on the server&amp;nbsp;&lt;/b&gt;- Especially rendering HTML.&amp;nbsp;&lt;a href="http://iamnoah.blogspot.com/2010/07/json-is-overrated.html"&gt;JSON is overrated&lt;/a&gt;. jQuery's&amp;nbsp;&lt;a href="http://api.jquery.com/load/"&gt;load&lt;/a&gt;&amp;nbsp;method can do 95% of what you need in one line of JS.&amp;nbsp;For the most part, JS should not be producing HTML. Things go much more smoothly when all HTML is produced server side because then the logic to generate the markup doesn't need to be duplicated. There are exceptions, like if you have a feature using 3rd party code, like a Google Map, that simply will not work without JavaScript. Then it&amp;nbsp;&lt;i&gt;might&amp;nbsp;&lt;/i&gt;be necessary &amp;nbsp;to generate some of the UI in JS. If you must generate HTML in JS, use a&amp;nbsp;&lt;a href="http://github.com/janl/mustache.js/"&gt;templating framework&lt;/a&gt;. If you are concatenating anything more than 100 characters of HTML together, you're making a mess of your code.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Keep the&amp;nbsp;porcelain&amp;nbsp;thin&lt;/b&gt;&amp;nbsp;- Do not under any circumstances create more than one layer of abstraction between the code and the core web technologies. Most of the HTML output of your application should correspond to HTML in a template file.&amp;nbsp;Taglibs&amp;nbsp;are fine, but try to use your templating language even inside of them. Do not create a system where the developer doesn't have to know HTML. The same goes for JavaScript and CSS. Do not write code to generate CSS ever. You may use a framework that generates CSS to reduce repetition, but try to only use the big ones with a good community. Do not generate JavaScript code ever. Generate inline JSON instead and have your scripts consume it to determine behavior dynamically. Use&amp;nbsp;&lt;a href="http://iamnoah.blogspot.com/2009/01/whadya-know-this-semantic-markup-crap.html"&gt;stateful CSS rules&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Cover all the pipes&lt;/b&gt;&amp;nbsp;- When you realize that to make it all work you need every load() call to add some parameter, or check some condition, you better hope you can go to one place in your code and make that change. Hopefully the plumbing provides good hooks, or there is some AOP/IoC magic that can cover it. Otherwise, you may have to create very very thin wrappers around plumbing functionality. Not in the hopes of portability (you will never port this app to a different framework, it will be rewritten), but so that you can&amp;nbsp;funnel&amp;nbsp;all calls to that feature through one place.&lt;/li&gt;&lt;/ol&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: 19px; font-weight: bold;"&gt;Core Features&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;So what features does a HTML based, server oriented porcelain framework provide?&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Component Refresh&amp;nbsp;&lt;/b&gt;- This is the core. There needs to be a simple way to designate an area of the page as a component and an easy way to make a call to refresh its HTML. This may be as simple as using&amp;nbsp;&lt;a href="http://api.jquery.com/load/"&gt;jQuery's load&lt;/a&gt;&amp;nbsp;with a selector to get the desired page fragment, although it's nice if the server can do the minimal amount of work necessary to render the HTML you need.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Multi-Component Refresh&lt;/b&gt;&amp;nbsp;- Sometimes you need to refresh several parts of the page whose only common parent is the body element. You could just reload the whole page, but for an action that only affects part of the page that's both inefficient and bad UX. You could also use multiple requests, but if there are more than 2 components, then many browsers will block the 3rd request until one of the others return. There is probably also a server part of the framework that allows the components to share data instead of making redundant calls.&lt;/li&gt;&lt;li&gt;&lt;b&gt;JSON&lt;/b&gt;&amp;nbsp;- Not to be consumed by Ajax calls, but to inline as script tags in the page. Most frameworks can take the same data model you pass to your templates and convert it to JSON&amp;nbsp;automagically&amp;nbsp;for your JS to consume too. You probably will want to include it inside your components' HTML so you can update the JS state when a component is refreshed.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Next Time Let's Build One&lt;/h3&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Soon, I hope to have some example code for a simple Grails porcelain framework. Actual code can be a lot more informative and illuminating than pithy maxims.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-8173254582844085328?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/8173254582844085328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=8173254582844085328' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/8173254582844085328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/8173254582844085328'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2010/07/how-to-build-ajax-framework.html' title='How to Build an Ajax Framework'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-7609621799007420284</id><published>2010-07-14T21:48:00.000-05:00</published><updated>2010-07-14T21:48:48.593-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><title type='text'>JSON is Overrated</title><content type='html'>JSON is great. It's an extremely concise, machine parsable yet still human readable format. It's the best thing to happen to data interchange since XML, and it makes XML looks like the big piece of dog crap that it is. (Seriously, angle brackets? And redundant closing tags? Who thought that was human readable?)&lt;br /&gt;&lt;br /&gt;However, some of you may be surprised to know, JSON is not the only format that can be returned in an Ajax request. Don't get me wrong, if I make a request to the Twitter API or some other webservice, I'm not going to be happy if it returns XML. That stuff is a pain. But there are other uses for Ajax that just consuming raw data. Did you know you can return HTML?&lt;br /&gt;&lt;br /&gt;For example, search results since the&amp;nbsp;beginning&amp;nbsp;of time have been paginated. The nice thing to do nowadays is to make an Ajax request when the user requests the next page so we can avoid reloading the header, footer, sidebar and whatever else in your page isn't a search result. Now you almost certainly rendered the first page of results on the server, using whatever templating language it is you use. Something like:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/476415.js?file=gistfile1.rhtml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;So when it comes time to make an Ajax call and load that next page of results, naturally you will write another controller method to render the results as JSON and then a bunch of hideous JavaScript to concatenate HTML together and replicate the logic you already have on the server. Because that's a lot easier than:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/476419.js?file=gistfile1.js"&gt;&lt;/script&gt;&lt;br /&gt;([/sarcasm] for the facetity&amp;nbsp;impaired; it's a terrible&amp;nbsp;affliction.)&lt;br /&gt;&lt;br /&gt;When you're creating any sort of Ajax endpoint, just ask yourself one question, "Is anyone other than a script on this site going to consume this?" The answer is probably no, so I'm going to ask you a question in return, "What is wrong with you? Why would you want to generate HTML on the client by&amp;nbsp;concatenating&amp;nbsp;strings together instead of on the server with a nice templating language?"&lt;br /&gt;&lt;br /&gt;If you're reading this blog, you probably already know that HTML&amp;nbsp;concatenation&amp;nbsp;is a code smell. You&amp;nbsp;quickly&amp;nbsp;realize that replicating all that rendering logic in JavaScript is going to be a mess. I bet you also know someone who's code stinks, so please find them and give them a gentle talking to about how their shiny new JSON hammer is not the best tool for screwing with Ajax.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-7609621799007420284?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/7609621799007420284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=7609621799007420284' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7609621799007420284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7609621799007420284'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2010/07/json-is-overrated.html' title='JSON is Overrated'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-1490962433746382611</id><published>2010-07-07T22:21:00.002-05:00</published><updated>2010-07-14T21:16:17.413-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='user experience'/><category scheme='http://www.blogger.com/atom/ns#' term='ux'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='oauth'/><category scheme='http://www.blogger.com/atom/ns#' term='dropbox'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>OAuth and Android - Dropbox is wrong; never ask for passwords</title><content type='html'>EDIT: Not having an iPhone and not having any dev experience with it (yet), I wasn't sure whether or not this was possible on an iPhone. However, I've had an iPhone dev assure me that it is and that several apps (TripIt being an example) do it. So there really is no excuse. If OAuth is good on the web, it's good on iPhone and Android too.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.dropbox.com/referrals/NTEzOTY5NDk"&gt;Dropbox &lt;/a&gt;recently announced their API, which is pretty exciting because it's a great service. It uses OAuth for authentication, but under the &lt;i&gt;Authentication For Mobile Devices&lt;/i&gt; section, there is this statement:&lt;br /&gt;&lt;blockquote&gt;While Dropbox uses OAuth for the base of its authentication strategy, OAuth doesn’t work very well for mobile devices. It’s much too difficult and error prone to have a mobile device switch context to a browser, do the OAuth handshake, and then magically return to the original application with the tokens in hand ready to use. It’s bad for user experience and it’s bad for developer sanity.&lt;/blockquote&gt;&amp;nbsp;I emphatically disagree with this statement, at least as far as Android is concerned. I think OAuth vastly improves the user experience, even from a mobile app and this attitude that it's too hard or too much trouble is damaging to both the experience and security of users.&lt;br /&gt;&lt;br /&gt;Lets take their statement piece by piece.&lt;br /&gt;&lt;h3&gt;It’s much too difficult and error prone to have a mobile device switch context to a browser&lt;/h3&gt;This is trivial on Android. I'll use the &lt;a href="http://gowalla.com/api/docs/oauth"&gt;Gowalla OAuth flow&lt;/a&gt; in my examples because I think it's an elegantly simple implementation of OAuth, but this works for any OAuth system:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/467603.js?file=AndroidGowallaAuth.java"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;That's it. The browser is launched and the user will see the Gowalla authorization page. If they're already logged in, they don't even have to type their username and password. Now &lt;b&gt;there &lt;/b&gt;is an activity that is difficult and error prone. I hate entering login credentials on my phone, and I can copy and paste them from &lt;a href="http://lastpass.com/"&gt;LastPass&lt;/a&gt;. Even with &lt;a href="http://www.swypeinc.com/"&gt;Swype&lt;/a&gt;, typing on a mobile device is neither easy or error free. Save your users the headache and use OAuth.&lt;br /&gt;&lt;h3&gt;It’s much too difficult and error prone to ... do the OAuth handshake, and then magically return to the original application with the tokens in hand ready to use.&lt;/h3&gt;&lt;br /&gt;Again, this "magic" is almost trivial for an Android app. You simply specify that your activity can handle the custom data URI scheme you specified in your redirect link:&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/467601.js?file=Android-Custom-Data-Scheme.xml"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Once the user clicks "Allow", your activity will be launched and the Intent data will have a parameter telling you the access code needed to complete the OAuth handshake. This isn't any more difficult and error prone than implementing OAuth in a web application. But it's not that difficult, because there are plenty of &lt;a href="http://code.google.com/p/oauth-signpost/"&gt;great OAuth libraries&lt;/a&gt; out there to help you on the web server, and you can use them on your Android device too.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;It’s bad for user experience&lt;/h3&gt;If this is true for OAuth on mobile devices, then it's even more true for the web and we should abandon OAuth completely. An app launching a browser is not an&amp;nbsp;unfamiliar&amp;nbsp;thing. Receive an email with a link on a desktop, you click the link and it opens your browser. This is normal, good UX. I click a link to comment on your site and you take me to Facebook? That's weird. As a user I'm not sure what is going on. Suddenly everything looks different... I thought I was commenting on your blog? Why are you on my Facebook?&lt;br /&gt;&lt;br /&gt;The response to this (for web applications) is that users simply need to become familiar with the concept and then it wont seem weird at all, it will seem normal. That argument also works for mobile devices. In fact, if you are worried about the user not knowing what is going on, just tell them! "You will now be taken to Gowalla to authorize this app. You may be asked to log in. After you authorize &lt;i&gt;myApp, &lt;/i&gt;you will be returned here."&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;OAuth is Good for Dev, and Good for UX&lt;/h3&gt;The idea that OAuth isn't suited for mobile isn't in any way grounded in the Android mobile experience, as far as I can tell. That might explain why Dropbox has a lot to say about it's Objective-C library, but for Java they only offer two words: "Coming soon."&lt;br /&gt;&lt;br /&gt;Anything you can truthfully say about OAuth being bad UX or bad for dev in regards to mobile is equally if not more true for the web. But nobody is suggesting that OAuth be abandoned on the web and we go back to asking users for their passwords. So don't do it in your mobile apps either.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-1490962433746382611?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/1490962433746382611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=1490962433746382611' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1490962433746382611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1490962433746382611'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2010/07/oauth-and-android-dropbox-is-wrong.html' title='OAuth and Android - Dropbox is wrong; never ask for passwords'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-5813668596686149240</id><published>2009-12-10T16:08:00.004-06:00</published><updated>2011-07-30T10:15:47.330-05:00</updated><title type='text'>jquery.writeCapture.js - Now with 60% more magic!</title><content type='html'>I've gone ahead and written a jQuery plugin for &lt;a href="http://github.com/iamnoah/writeCapture"&gt;writeCapture.js&lt;/a&gt;. I've reduced the problem to making one extra call in the chain and then the voodoo black magic takes over and you can't go wrong. Here's a kitchen sink example:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;$('#foo').writeCapture().find('.bar').html(dangerousHtml).end().&lt;br /&gt;find('.baz').load('returnsDanger.php').after(moreDangerousHtml).end().&lt;br /&gt;addClass('loading');&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In this context, "dangerous" HTML is any HTML that does or could contain a script tag that uses &lt;code&gt;document.write&lt;/code&gt;, aka, the evil method. The implementation details are wonderfully complicated, but I've made the usage so simple that any code monkey can just chain whatever they like off of a call to writeCapture() and everything will be perfectly "safe". e.g., document.write will not destroy the application and all the content will show up where it is supposed to. So enjoy.&lt;br /&gt;&lt;br /&gt;EDIT: the comments here aren't a good place to ask for help. You can get help through GitHub.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-5813668596686149240?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/5813668596686149240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=5813668596686149240' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/5813668596686149240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/5813668596686149240'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/12/jquerywritecapturejs-now-with-60-more.html' title='jquery.writeCapture.js - Now with 60% more magic!'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-2025560785305226296</id><published>2009-12-02T13:00:00.005-06:00</published><updated>2009-12-02T13:23:49.578-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='nodejs'/><title type='text'>GitHub, Taming document.write and node.js fun</title><content type='html'>I have &lt;a href="http://github.com/iamnoah"&gt;a few projects on GitHub&lt;/a&gt; now.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The serious project is &lt;a href="http://github.com/iamnoah/writeCapture"&gt;writeCapture.js&lt;/a&gt;. It exists to solve a corner case of the "load some HTML and inject it into the document" pattern.  I love this pattern because it's generally the simplest way to combine Ajax with progressive enhancement. The idea is that you load a HTML fragment and just stick it into the document, or replace the old fragment with the new fragment. It degrades easily, and keeps things simple. The only problem is when the HTML you're loading is outside of your control, or can't be changed for some reason. Maybe it's a service provided by a 3rd party. If the HTML contains script tags, and the script tags contain calls to document.write, you're going to have 1 of 2 bad outcomes:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;If you just use innerHTML, the scripts probably wont run (at least, not in every browser), so whatever content document.write provides will be missing. That's probably bad.&lt;/li&gt;&lt;li&gt;If you use jQuery.html() or .replaceWith() or any jQuery manipulation method, the scripts will run, and all the content already in the document gets wiped out. Oops.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;So this is the part where you realize that you need &lt;a href="http://github.com/iamnoah/writeCapture"&gt;writeCapture.js&lt;/a&gt;. It's open source, well tested, and covers every possible convoluted way that document.write can be slipped into a script: inline, local script file, cross domain and any combination of the 3 (even the script that writes a script tag that includes a script that uses document.write case. Seriously.) You're welcome.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lastly, I've been having fun with &lt;a href="http://nodejs.org/"&gt;node.js&lt;/a&gt;. node &lt;a href="http://jsconf.eu/2009/video_nodejs_by_ryan_dahl.html"&gt;can do a lot of things&lt;/a&gt;, but using it as a web server/application is the one that appeals to me most, so I wrote &lt;a href="http://gist.github.com/246761"&gt;a simple web server that streams whatever files are in the current directory&lt;/a&gt;. Of course, you can make it do anything you want in response to a HTTP request (or use raw sockets, or whatever) and I'm sure there are a dozen (G)rails like frameworks being written for it as we speak. Enjoy.&lt;/div&gt;&lt;div&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/6713689-2025560785305226296?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/2025560785305226296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=2025560785305226296' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/2025560785305226296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/2025560785305226296'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/12/github-taming-documentwrite-and-nodejs.html' title='GitHub, Taming document.write and node.js fun'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-6253955641715706892</id><published>2009-10-20T08:59:00.010-05:00</published><updated>2009-10-20T10:16:58.457-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='worse is better'/><category scheme='http://www.blogger.com/atom/ns#' term='duct tape programmer'/><category scheme='http://www.blogger.com/atom/ns#' term='shipping is a feaure'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>How to refactor without reFing it up</title><content type='html'>Sometimes technical debt is unavoidable.  There are lots of good reason why the code you have today is increasing your maintenance costs and slowing feature development. Sometimes you have to accept a hack in order to ship (&lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html"&gt;shipping is a feature&lt;/a&gt;). Or if your product has been around a while, it's probably evolved far beyond the original design, and it just needs to be restructured. Or maybe it's not a good reason but it happened anyways, e.g., you trusted a less than stellar developer, forgot to write unit tests, or adopted &lt;a href="http://java.sun.com/javaee/javaserverfaces/"&gt;a framework that sounds great in theory but just doesn't make any sense in practice&lt;/a&gt;. In any case, taking an iteration or more (when you can afford it) to deal with technical debt is just par for the course.&lt;br /&gt;&lt;br /&gt;The first mistake made by many developers when they start refactoring is to start by cleaning up code.  That way is a rabbit hole that will take you through multiple iterations to increasingly madder tea-parties (read: standups) and end with your PM screaming "Off with his head!" because you've made the codebase unworkable for weeks, all in an effort to make things better.  It starts so innocently, with a single class. Then you notice that the problem with that class is related to one of its dependencies, so you chase that dependency down and discover that the general architecture is too small (or too large) so you eat the mushroom or drink the drink and soon you're drowning in your own tears. The caterpillar may console you momentarily by giving you a hit off his hookah, but it's just going to get weirder. Better to stay out of the rabbit hole.&lt;br /&gt;&lt;br /&gt;The key is limiting the scope and hammering it into everyone involved that "WE DO NOT TOUCH ANYTHING OUT OF SCOPE". I'll say that again, in all caps WE DO NOT TOUCH ANYTHING OUT OF SCOPE.  "But, but, the service layer is still a mess, which is why w-" WE DO NOT TOUCH ANYTHING OUT OF SCOPE.&lt;br /&gt;&lt;br /&gt;The first step in a successful refactoring is for a senior developer or lead to sit down and figure out the smallest possible refactoring that can be done. Then create specific instructions on how the refactoring should be done. Literally, instructions like "Move line X to class Y and put Z where X was." You don't want to leave it up to the developer to come up with their own way of doing things. Developers get bored easily, and a single developer can try six different ways of doing things before he decides on one he likes.&lt;br /&gt;&lt;br /&gt;Once you have detailed instructions and guidelines, cut your developers loose. After the first commit, be prepared to devote at least 10 minutes of your next standup to explaining the instructions again, because it turns out half of them didn't read them. It's not that you have stupid or bad coders on your team, it's that they're smart and think they don't need instructions.  It's more fun to get coding and figure it out as you go, right?&lt;br /&gt;&lt;br /&gt;Because you made the original refactoring small, once the effort is underway, you need to start planning the next one. Small and iterative works for features and it works for bugs. It will work for refactoring just as well. Don't waterfall refactor.&lt;br /&gt;&lt;br /&gt;It goes against every technical design instinct we have, but the better course of action will almost always be to incrementally improves components of a system rather than redesign it from the ground up. You also have to keep the app running. If HEAD is unusable for even a day because of your refactoring, you're trying to change too much at once. Sometimes that means writing some glue code that is ugly and inelegant so that the component you're refactoring can be pretty and elegant. Your inner architecture astronaut will be screaming as he burns up on rentry, but even &lt;a href="http://octanecreative.com/ducttape/NASA/index.html"&gt;NASA sometimes needs duct tape&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here is an example to get you started: Take your JSP/ASP/GSP or PHP templates. Define model classes for them, based on the needs of the UI, not based on whatever model you have in the database or ORM or the DTOs your services return. You should end up with simple inline expressions. e.g., ${model.foo} rather than ${_POST['foo'].replaceAll("\\.","-")} or ${fooList[i].bar.baz.foo}. Move all that ugly logic into your controller. That part is easy. The hard part is resisting the urge to go back your service layer or even your ORM mapper and develop a factory and mapping system that trasforms the output to perfectly match your templates so you can just write Foo.list(params) in your controller and have it be oh-so-elegant.  It will be done in 2012. Remember: Worse is better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-6253955641715706892?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/6253955641715706892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=6253955641715706892' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/6253955641715706892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/6253955641715706892'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/10/how-to-refactor-without-refing-it-up.html' title='How to refactor without reFing it up'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-514689248781170919</id><published>2009-07-20T10:55:00.004-05:00</published><updated>2009-07-20T13:24:17.375-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='langauges'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>The Ugly American Programmer: Bill Burke</title><content type='html'>I originally tried to post this as a comment on Bill Burke's &lt;a href="http://bill.burkecentral.com/2009/07/20/polyglotism-is-the-worst-idea-i-ever-heard/" rel="nofollow" title="Permanent Link to Polyglotism is the worst idea I ever heard"&gt;Polyglotism is the worst idea I ever heard&lt;/a&gt;, but as far as I know, my comment is still awaiting moderation. So I'll go ahead and dissect it here. Burke starts with an alleged tongue-in-cheek:&lt;br /&gt;&lt;blockquote&gt;Let me first start off with some tongue in cheek…I’m an American.  I have no need to speak another language because well, I speak English.  99% of the civilized world speaks English so WTF should I ever learn another language?  Case in point, I minored in German in college.  For two semesters I went over to Munich and worked at Deutsche Aerospace so that I could learn German better.  The thing is, besides the fact that my coworkers spoke damn good English to begin with, all the documentation they put out was in English, the units used were feet, pounds, miles.  When the French came over to work with us, we also spoke English.  So what is the freakin point of learning German?  I was pretty damn disappointed that I wasted all this time in college learning German when in reality it was just a freakin useless exercise…&lt;/blockquote&gt;So we've taken the ugly American attitude and are now applying it to software development.  Now, if he was trying to make the point that there is a lot of benefit to learning another language, his tongue-in-cheek disclaimer would make sense. But instead the above ignorant statement is followed by more ignorant rambling about using multiple languages in a project. He seems to think tongue-in-cheek means "I can say something ignorant and not be criticized for it".&lt;blockquote&gt;Which brings me to the point of this blog.  Polyglotism in software has to be the worst idea I ever heard.  The idea of it is that you use the language that is best fits the job.  Some say this is a huge boon for the developer as they will become more productive.  In practice though, I think this is just a big excuse so the developer can learn and play with a new language, or for a language zealot/missionary to figure out a way to weasel in his pet language into a company.  Plus, you’d probably end up being average or good at many languages but a master of none….But lets pretend that it is a benefit to the developer.  Developers need to realize that there are implications to being polyglot.&lt;/blockquote&gt;Notice his focus on the single developer who is out to ruin things through his own selfishness (he must hate America!)   No consideration is given to the benefits that a team and organization can derive from using multiple languages (which we will get to). His next point, maintenance:&lt;blockquote&gt;So, you’ve added a Ruby module to that big flagship Java application or product your company is so proud of.  You did it fast.  It works. And management loves you for it.  They love you so much for it, they’ve promoted you to software lead and now you are running a brand new project.  Now that you’ve left your polyglot project, somebody needs to take over your work.  Unfortunately, your group is a bunch of Java developers.  For any bug that needs to be fixed, these developers need to be retrained in Ruby, a new Ruby developer needs to be hired, and/or a Ruby consultant/contractor needs to be brought it.  Multiply this by each language you’ve introduced to your project.&lt;/blockquote&gt;Oh no, a Java programmer has to learn some Ruby! If you have any talented developers, they'll probably jump at the chance to escape Java hell and learn something new, assuming they haven't already learned Ruby on their own.  "Multiply this by each language" is meaningless scare language. This assumes that skills are not transferable between programming languages. It's not at all difficult to be proficient in multiple languages. Many Java/PHP developers are also well versed in JavaScript (if you discount JavaScript at this point, I hope you have a career path that &lt;a href="http://iamnoah.blogspot.com/2008/02/java-developers-guide-to-javascript.html"&gt;doesn't involve any programming for the web&lt;/a&gt;). Knowing multiple languages demonstrates mental flexibility and teaches a developer to think about problems in different ways. I would never hire a programmer that was only proficient in a single language.&lt;br /&gt;&lt;blockquote&gt;The JVM is pretty cool now.  We can run Ruby on it, Python on it, and even PHP on it.  Your JRuby apps can work with Java APIs.  Same with Jython and JPHP.  Great.  So now your developers can use any one of these language to build out extensions to your Java app.  But what happens when you want to refactor one of your re-used Java libraries?  OOPS!!!&lt;/blockquote&gt;Groovy and Scala are conspicuously absent from Mr. Burke's list. Could that be because they both compile to bytecode, and the resulting classes can therefore be used by any JVM language? So you could use Java, Scala and Groovy together in the same project in a completely interchangeable way, right now.&lt;br /&gt;&lt;blockquote&gt;Ah, so you’ve weathered through the maintenance and refactoring nightmares and you’ve finally shipped your product.  Hmm, but you’ve just added the complexity of installing multiple runtimes on your user base.  Its not hugely bad if you’ve used the JVM as your base virtual machine.  But you still need to package and install all the appropriate Java libraries, Ruby gems, and Python libraries on the appropriate places of your user’s machine.  You also need to hope that all the desparate environments don’t conflict with anything the user has already installed on his machine.  And that’s just with languages running in the JVM.  Imagine if you used vanilla Ruby, Python and Java all as separate silos!&lt;/blockquote&gt;These new languages are used to reduce maintenance by dramatically reducing the size of the codebase, and simplifying application setup and ramp up times.  Give me a domain model and I can have a functional Grails or Rails application running in less than an hour. And the code base will be a fraction of the size of the equivalent Java project.  As for packaging, Maven handles Groovy and JRuby quite well. I'm sure PHP and Jython will have support soon enough, if they don't already (I don't know).&lt;br /&gt;&lt;blockquote&gt;A support call comes in for your product or application.  Its obviously a bug, but where is the problem?  Is it your application code?  Your JVM?  Your Ruby VM?  Your Java library? Your Ruby gem?&lt;/blockquote&gt;What an absurd statement. Where is the bug? I don't know, how do you normally find the bug in a "pure" application? Lets see, the date is parsed incorrectly and we're using some Ruby code to parse dates... Where could the bug be? Is it in the PHP templates? Only if you're an idiot. You could make the same argument about the MVC pattern and Hibernate. 3 layers? How will I know where the bug is? What if the bug is in a library? I better write it all myself in C. (Note that this is the correct way to make a tongue-in-cheek statement).&lt;br /&gt;&lt;blockquote&gt;All and all, let me put it this way.  We all work in multi-national environments.  What if each developer documented their projects in their own native language, because lets face it, they are most productive in that language.  Where would we be?  Doing what’s best for oneself isn’t always best for the big picture&lt;/blockquote&gt;This last point about documentation doesn't even make sense. You write for your target audience. The compiler/interpreter is the intended audience of a programming language. You write Ruby code for the Ruby interpreter, Java for the Java compiler, etc.&lt;br /&gt;&lt;br /&gt;The whole thing is absurd. You might as well say that SQL is a waste of time. The simple fact is that modern programmers use multiple languages in the same project with regularity, and the only ones who have trouble are the poorly trained &amp;amp; ignorant (who can hardly be called master of even the single language they know), and the old fogies, like Burke, who consider learning something new a waste of time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-514689248781170919?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/514689248781170919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=514689248781170919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/514689248781170919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/514689248781170919'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/07/ugly-american-programmer-bill-burke.html' title='The Ugly American Programmer: Bill Burke'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-4303237960742433834</id><published>2009-04-02T21:09:00.004-05:00</published><updated>2009-04-02T21:11:07.958-05:00</updated><title type='text'>Buy my House!</title><content type='html'>My apologies for posting something almost personal, but this is mostly as a note for myself.&lt;br /&gt;&lt;br /&gt;If you live in the Austin in area and are looking for a good house, mine is &lt;a href="http://b.vrguild.net/c/stnd.pl?U=0903311938546581"&gt;for sale&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-4303237960742433834?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/4303237960742433834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=4303237960742433834' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/4303237960742433834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/4303237960742433834'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/04/buy-my-house.html' title='Buy my House!'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-9023926521665367085</id><published>2009-03-10T11:41:00.006-05:00</published><updated>2009-03-10T16:25:33.076-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dynamic'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='langauges'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>When to go dynamic</title><content type='html'>The most typical complaint I hear from Java developers about Groovy is, "I spent X hours trying to figure out this problem that would've been a compile time error in Java."  And they're right. Very little compile time checking is done in Groovy. It can't be done because methods may be available at runtime that aren't resolvable at compile time. That's part of what it means to be a dynamic language.&lt;br /&gt;&lt;br /&gt;Some developers seem to think using the optional types will save them. e.g.,&lt;pre&gt;&lt;br /&gt;int foo (String bar) {&lt;br /&gt; return bar.size()&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Looks good, right? Try running this script:&lt;pre&gt;&lt;br /&gt;int foo (String bar) {&lt;br /&gt; return bar.size()&lt;br /&gt;}&lt;br /&gt;if(false) {&lt;br /&gt; String s = foo(123)&lt;br /&gt; println s&lt;br /&gt;}&lt;br /&gt;println "Done"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Go ahead. Run that script. No error. Types aren't checked at compile time. If we change false to true, we get a groovy.lang.MissingMethodException at runtime, but that's it. Your compiler can't save you here. Good unit tests will catch some errors if you use the optional types, but you have to know what the error is before you can test for it, so you've already spent the X hours trying to track it down.&lt;br /&gt;&lt;br /&gt;What makes Java so good for enterprise work is the static types. Static types enforce a contract. Static types make it possible for Eclipse to take you to the exact method that will be invoked by a particular line in the source. If the method is on an interface, Eclipse can tell you all types that implement that interface method and take you to any implementation you choose immediately. This is extremely useful when you're trying to navigate a complex, unfamiliar system. While a human may be able to easily figure out what file to open, having a tool that can do it for you automatically allows your concentration to remain on what the code does and lets you work at a higher mental level of abstraction.&lt;br /&gt;&lt;br /&gt;If I have to learn a new framework that someone has written, I'll get through it 10x faster if it's in Java. No/bad documentation? Not a problem, I'll just look at the code for that method. Whereas if I come upon an undocumented Groovy method, what do I do? Ugh, I have to grep through all of the source to figure out where it's defined, how it's used, yada yada. Not quick. Breaks my concentration.&lt;br /&gt;&lt;br /&gt;Java is very good at making large systems manageable. However, the trade off is that&lt;br /&gt;any system that has been under active development for more than 2 weeks quickly becomes a large system. There is nothing concise about Java. There are very few shortcuts. The simplicity of the language and the rigidity of types means you have to write more code and produce more classes to get things done and God help you if you want anything remotely flexible. Code that needs to do something even slightly dynamic can quickly become unreadable and strewn with all kinds of reflection objects, odd exceptions and other nastiness. Or worse. You could end up in &lt;a href="http://java.dzone.com/news/draft-spring-xml-hell"&gt;XML hell&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Enter Groovy. Dynamic languages do best when there are conventions and consistent ways of doing things. Grails is proof of this. Controllers are in the controllers folder, services in the services folder, etc. Each class follows a certain arechtype and there are good idioms in place that imply what is going on.  However, when you start writing plugins, or doing things outside of the normal scope of Grails, things can get messy fast.&lt;br /&gt;&lt;br /&gt;Anytime you're coding in uncharted territory, consider going back to Java. Writing a plugin? Implement as much of it as you can in Java. Only go back to Groovy if the equivalent Java code gets too ugly or would be many times longer.  Most of your plugin/framework/new invention's plumbing should be in Java. The plumbing is where you connect everything together, and it's important to verify that thingDoer is of type ThingDoer, and that all interceptors properly implement the ThingDoerInterceptor interface. You want your API to &lt;a href="http://en.wikipedia.org/wiki/Fail-fast"&gt;fail fast&lt;/a&gt; so your users don't end up with a NPE exception deep in your code that they have no hope of debugging.&lt;br /&gt;&lt;br /&gt;Keep Groovy at the fringes, handling the nasty implementation details, and protected by static types and good assertions. Make sure your Groovy class implements an interface, or better yet, have a Java class implement the interface and wrap the Groovy implementation so you can jump to it in Eclipse. Use Java to provide enforce the type contracts and provide a well defined framework. Use Groovy to make the implementation readable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-9023926521665367085?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/9023926521665367085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=9023926521665367085' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/9023926521665367085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/9023926521665367085'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/03/when-to-go-dynamic.html' title='When to go dynamic'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-365004691229771882</id><published>2009-02-12T20:15:00.005-06:00</published><updated>2009-02-19T12:05:17.999-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='stubs'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='mock objects'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Mock object are making your tests stupid</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Mock_object"&gt;Mock objects&lt;/a&gt; were created because when you're writing unit tests (especially in a statically typed language), it can be a pain to create a subclass/implementations to use for your tests. You need a mock whenever the class you are testing depends on another class. You want to guarantee that changes to the other class don't break your tests for this class, because that would defeat one of the purposes of unit testing: isolation of the failure to a particular class/method. So you want an object that, whenever getTemperatureOutside is called, returns 32 degrees.&lt;br /&gt;&lt;br /&gt;Sometimes you also want to make sure that the method you are testing causes some side effect. e.g., if the temperature outside is less than 32 degrees, it should call deployIceScraperNarwhals(). So, you want a method that records that deployIceScraperNarwhals() was called (but doesn't actually deploy the Narwhals) and something that checks that it actually was called, failing the test if it wasn't. Thus, the idea of verifying method calls was inextricably bound to the idea of providing fake methods to isolate behavior and every genius-pants writing a mock object framework decided that the verification was the most important part, to be emphasized throughout the documentation.&lt;br /&gt;&lt;br /&gt;Then you came along, read the mock object documentation and proceed to go and write unit tests like this (mock object syntax is made up):&lt;pre&gt;&lt;br /&gt;class UnderTest {&lt;br /&gt; int calculate(Foo foo,Bar bar) {&lt;br /&gt;    int a = foo.getA()&lt;br /&gt;    int b = bar.getB()&lt;br /&gt;    return a + b&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class UnderTestTest {&lt;br /&gt;  void testCalculate() {&lt;br /&gt;     Foo foo = createMock(Foo).getA().andReturn(3)&lt;br /&gt;     Bar bar = createMock(Bar).getB().andReturn(2)&lt;br /&gt;     assertEquals(5,instance.calculate(foo,bar))&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Honestly, I'm looking for the stupid thing you did here, and I can't find it. The test passes, you didn't have to write MockFoo and MockBar classes, and all is right with the world. Until you decide to make an optimization:&lt;pre&gt;&lt;br /&gt;class UnderTest {&lt;br /&gt; int calculate(Foo foo,Bar bar) {&lt;br /&gt;    if(foo.getA() == bar.getB()) {&lt;br /&gt;      return foo.getA() &lt;&lt; 1 // a+b = a*2 = a left shifted 1 bit     &lt;br /&gt;    }     &lt;br /&gt;    int a = foo.getA()     &lt;br /&gt;    int b = bar.getB()&lt;br /&gt;     return a + b&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;Ignoring the fact that this probably hurts performance instead of helping, lets rerun the test and see what we get (error message made up because I'm lazy): "Unexpected call to getA." That's right, you only told it to expect one call to getA, not two. You didn't change the result, you didn't remove an important side effect, in short, you did nothing that should break a test. Everything is still working perfectly. But it broke the test.&lt;br /&gt;&lt;br /&gt;This is the part where I get to tell you you're an idiot. Instead of realizing that what you really want is a &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html#TheDifferenceBetweenMocksAndStubs"&gt;stub object&lt;/a&gt;, you decided that you must have written the test wrong so you rewrite it to expect between 1 and 2 calls to getA(). Because these mock object things can be tricky, you proceed to write all of your unit tests from then on by examining the source of the method you are testing, creating a mock for each dependency, adding a method call for each method call in the source, and basically rewriting the method in mock form. You idiot. You just wrote a test that confirms that the method was coded a particular way, not that the method behaves correctly.&lt;br /&gt;&lt;br /&gt;Here's an example:&lt;pre&gt;&lt;br /&gt;class OtherUnderTest {&lt;br /&gt; /**&lt;br /&gt;  * @return a Map with a result entry, which is a message to the user.&lt;br /&gt;  */&lt;br /&gt; Map deployNarhwals(Foo foo,Bar bar,Narwhals narwhals) {&lt;br /&gt;    if( underTest.calculate(foo,bar) &lt; 32 ) {&lt;br /&gt;       narwhals.deploy()&lt;br /&gt;       return [result: narwhals.getStatus()+' narwhals deployed']&lt;br /&gt;    }&lt;br /&gt;    return [result:'ok']&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class OtherUnderTestTest {&lt;br /&gt;  void testDeployNarwhals() {&lt;br /&gt;     Foo foo = createMock(Foo).getA().andReturn(3)&lt;br /&gt;     Bar bar = createMock(Bar).getB().andReturn(2)&lt;br /&gt;     Narwhals narwhals = createMock(Narwhals).getStatus().andReturn('Deadly')&lt;br /&gt;     narwhals.deploy()&lt;br /&gt;     Map result = instance.deployNarwhals(foo,bar,narwhals)&lt;br /&gt;     assertEquals([result:'Deadly narwhals deployed'],result)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;You did so many things wrong here I'm going to have to make a list:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;You mocked the parameters, but didn't stub the internal dependency.&lt;/strong&gt; See that instance of UnderTest in there? You're not testing it's calculate method, you're testing deployNarwhals, so you need to replace it with an instance that returns something like 31 so that you'll always be testing the condition (which should be a part of your API documentation) "if the temperature outside is less than 32 degrees, the narwhals will be deployed." Stupid.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;You verify that the side effect occurs, but you also couple your test to your implementation.&lt;/strong&gt;What if I decide that the user doesn't need to know the Narwhal's status, I change the wording of the message, or make an extra call to getStatus()? Broken test. But the test shouldn't break just because your marketing department decided that 'released' was a more green term than 'deployed', or you cleaned up your code and change the number or order of non-side-effect-causing method calls.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;You check for equality on a Map&lt;/strong&gt;Do you really care if there are extra keys in the Map? Probably not. Instead, check that all the key value pairs you expect are there.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;This is how you should have written your test:&lt;pre&gt;&lt;br /&gt;class OtherUnderTestTest {&lt;br /&gt;  void testDeployNarwhals() {&lt;br /&gt;     boolean deployed = false&lt;br /&gt;     Narwhals narwhals = [&lt;br /&gt;        getStatus: { return "Deadly" },&lt;br /&gt;        deployNarwhals: {&lt;br /&gt;          deployed = true&lt;br /&gt;        }&lt;br /&gt;     ] as Narwhals&lt;br /&gt;     instance.setUnderTest([calculate:{ return 31 }] as UnderTest)&lt;br /&gt;     Map result = instance.deployNarwhals(new Foo(),new Bar(),narwhals)&lt;br /&gt;     assertTrue(deployed)&lt;br /&gt;     assertNotNull(result.result)&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;You &lt;em&gt;could&lt;/em&gt; use a mock object framework for the Narwhals object, but you should configure it to only require the call to deployNarwhals, and not to fail when other methods are called. The above test will not fail unless the API contract is broken. I only assert that the expected side effect occurred, and that a non-null message was returned.&lt;br /&gt;&lt;br /&gt;The problem is that you morons seem to think that more assertions == better test. That's simply not true. A good test covers as many cases as possible, but only asserts what is defined in the API contract. If you start asserting things that are not part of the API, like getA() is called, you make the test brittle. Even worse, someone could come along and see your assertion and think that getA() being called is part of the API and code accordingly! Now you've introduced a bug somewhere else in the code that your tests wont catch and could become a complete mess if it isn't caught quickly. The reality is you should assert only what you have to to catch a bug. Sometimes tests don't even need assertions, or it's not worth the effort to write them. It's enough that they show that the code under test ran without error, which is no small matter. Knowing that retrieveNarwhals(null,null,null) doesn't throw an exception can be very important.&lt;br /&gt;&lt;br /&gt;Now, get back to work and try to stop writing brain dead tests. You thick ninny.&lt;br /&gt;&lt;br /&gt;EDIT: Here's a good alternative: &lt;a href="http://code.google.com/p/mockito/"&gt;Mockito&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-365004691229771882?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/365004691229771882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=365004691229771882' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/365004691229771882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/365004691229771882'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/02/mock-object-are-making-your-tests.html' title='Mock object are making your tests stupid'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-3096182818770623475</id><published>2009-01-30T11:51:00.000-06:00</published><updated>2009-01-30T12:08:59.989-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='dependency injection'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='ioc'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='singleton'/><category scheme='http://www.blogger.com/atom/ns#' term='webdev'/><title type='text'>Kill the Singletons. (And those things you thought were Singletons too)</title><content type='html'>You guys think you're so smart. You read something about design patterns once, and now you can justify any code you write by showing the pattern it implements. Except you only remember the Singleton, and a few others. You probably remember the Factory, because you usually implement it as a Singleton. Maybe you remember the Facade and/or the Adapter pattern.  You may even have some code somewhere that implements the Visitor pattern, probably where it was not at all appropriate. But Singleton is the one that everyone knows. Even those of you who never even read a poorly written article on design patterns. And you use it everywhere.&lt;br /&gt;&lt;br /&gt;Or you think that you do. Probably you're using it as a Factory or a Locator. Or you have a class with static methods that you use to load resources or something like that. Those are singletons right? No, but you thought they were. There are even some clever and occasionally useful Singletonish things implemented using &lt;a href="http://crazybob.org/2006/07/hard-core-java-threadlocal.html"&gt;ThreadLocal&lt;/a&gt;s, but that's for later. The point is, you've used Singletons as an excuse for what amounts to a bunch of global variables and methods. Bad programmer! No copy and paste for you!&lt;br /&gt;&lt;br /&gt;The real problem is in how you're using them. Singletons can't (easily or at all) be proxied, decorated, replaced or mocked. You're losing all kinds of flexibility, without gaining any sort of benefit. This is your code:&lt;pre&gt;&lt;br /&gt;public void doSomething() {&lt;br /&gt;MyConfig config = MyConfig.getConfiguration();&lt;br /&gt;config.doSomething();&lt;br /&gt;// etc....&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; This is your code on inversion of control:&lt;br /&gt;&lt;pre&gt;private MyConfig config;&lt;br /&gt;&lt;br /&gt;public void doSomething() {&lt;br /&gt;config.doSomething();&lt;br /&gt;// etc....&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setConfig(MyConfig config) {&lt;br /&gt;this.config = config;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; Of course, somewhere else you need to &lt;code&gt;myClassThatDoSomething.setConfig(configInstance);&lt;/code&gt;, or have your &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html"&gt;container&lt;/a&gt; do it.  This pattern is also called dependency injection, but unlike the Singleton, it's easy to get right. Don't call static lookup methods (or any lookup methods if you can avoid it) and make everything you need an object property. It's a simple change, but it gives you tons of flexibility. The only downside is that you have to learn how to use an &lt;acronym title="Inversion of Control"&gt;IoC&lt;/acronym&gt; &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html"&gt;container&lt;/a&gt;. Fortunately, they're getting more idiot proof by the day, so with a little work, you can probably figure it out.&lt;br /&gt;&lt;br /&gt;Now, before you go and delete every last one of your singletons, there are a few situations where IoC wont work. For IoC to work, you have to have control of the creation of the object, or at least be able to get a reference to it before it's used.  A good example is logging. Logging has to be available before the container even initalizes, so you can't dependency inject logging components (easily). And sometimes, the thing you need to inject can't be managed by the container. For example, suppose you need access to the current HTTP request object, or the session object? Ignore for a second that your container can usually mange to inject special objects like these and recognize that what makes these object special is that, in a particular scope, there is only one of them at a time. By their very definition, there can only be one HTTP Request and one Session at a time. To have two requests, or two session doesn't make any sense. That means you actually have a good candidate for a singleton. A filter like this can be very helpful (some types &amp;amp; casts omitted for brevity):&lt;br /&gt;&lt;pre&gt;private static ThreadLocal request = new ThreadLocal();&lt;br /&gt;&lt;br /&gt;public static HttpRequest getRequest() {&lt;br /&gt;return request.get();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void doFilter(request,response,chain) {&lt;br /&gt;request.set(request);&lt;br /&gt;try {&lt;br /&gt; chain.doFilter(request,response);&lt;br /&gt;} finally {&lt;br /&gt; request.clear();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;That lets anything that's executed inside the filter call MyFilter.getRequest() to get the current HTTP request object, regardless of whether the framework was kind enough to pass it in. Even this should only be a last resort. There may be a legitimate case where someone needs to wrap, replace or mock the request, but your singleton code gets in the way. How will you unit test code that accesses the request in this way? There is no real HTTP request when you're running unit tests. Dependency injection solves a lot of problems.&lt;br /&gt;&lt;br /&gt;Sometimes you can't avoid the Singleton, but considering the mess that you've made of things so far, maybe you should ask someone smarter than you next time you think you really need a Singleton. You probably don't. Now get back to work, and when you have some time, get &lt;a href="http://www.amazon.com/gp/product/0201633612?ie=UTF8&amp;amp;tag=noahsloancom-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0201633612"&gt;the original (and best) design patterns book&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=noahsloancom-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0201633612" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt;, read it, and stop abusing them. Design patterns are meant to describe good code, not magical pixie dust that you sprinkle on to make your crappy code suddenly good. Alas, that is another post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-3096182818770623475?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/3096182818770623475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=3096182818770623475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/3096182818770623475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/3096182818770623475'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/01/kill-singletons-and-those-things-you.html' title='Kill the Singletons. (And those things you thought were Singletons too)'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-7118682610515777405</id><published>2009-01-29T21:30:00.004-06:00</published><updated>2009-02-02T18:28:49.161-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>JS Tips &amp; Tricks</title><content type='html'>&lt;a href="http://javascript.crockford.com/"&gt;http://javascript.crockford.com&lt;/a&gt;, &lt;a href="http://www.amazon.com/gp/product/193398869X?ie=UTF8&amp;amp;tag=noahsloancom-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=193398869X"&gt;Secrets of the JavaScript Ninja&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=noahsloancom-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=193398869X" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt; and &lt;a href="http://www.amazon.com/gp/product/0596517742?ie=UTF8&amp;amp;tag=noahsloancom-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0596517742"&gt;JavaScript: The Good Parts&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=noahsloancom-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0596517742" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt; will cover almost everything you need to know about JavaScript. Still, there are a few tricks that I use almost every day that I feel are often underrated:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&amp;amp;&amp;amp; and || aren't your father's boolean operators. Thanks to JavaScript's notion of truth (anything but false, null, 0, undefined and the empty string), they don't have to return boolean value, and will not unless you coerce it into one with !!. That means you can use them inline as part of assignments and in parameter lists. e.g, &lt;pre&gt;function(someParam) {&lt;br /&gt; // provide a default value&lt;br /&gt; someParam = someParam || {};&lt;br /&gt; // ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// guard against null objects&lt;br /&gt;var count = foo &amp;amp;&amp;amp; foo.count || 0; // if foo is null, count == 0, else foo.count&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;function scope: &lt;pre&gt;(function($){&lt;br /&gt;$('#foo').doSomething();&lt;br /&gt;// ...&lt;br /&gt;})(jQuery);&lt;/pre&gt;The key here is that you're taking a global/wider scoped variable and making it a local variable, which allows you to rename/replace the original variable with little to no impact to your code. For example, suppose you need to use 2 versions of jQuery in your page. If you have the good sense to wrap all of your scripts in a function, you can include jQuery version A, then include your scripts that need version A, then include jQuery version B and your other scripts. Or if you wrote all of your scripts using $ as a reference to jQuery and then wanted to use Prototype in the same page.&lt;br /&gt;&lt;br /&gt;The other nice thing about wrapping your scripts is that any vars and function your define wont bleed into the window scope unless you specifically assign them to window. e.g., &lt;code&gt;window.GLOBAL_FOO = 123;&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;Sorry for the short post. I have some more code heavy stuff I think I'm working on for next time, I promise.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-7118682610515777405?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/7118682610515777405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=7118682610515777405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7118682610515777405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7118682610515777405'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/01/js-tips-tricks.html' title='JS Tips &amp; Tricks'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-1723925334489937317</id><published>2009-01-28T15:21:00.002-06:00</published><updated>2009-01-30T11:16:14.335-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='prototype'/><title type='text'>Quit being lazy. lern2javascript noob</title><content type='html'>[Note: This is a blog post from a year ago, but I'm reviving it because I'm seeing developers and companies lose work because they don't have JavaScript experience. If you work on web applications, you need to learn JavaScript. In addition to this post, which targets Java developers, I've added links to good getting started resources at the end.]&lt;br /&gt;&lt;h2&gt;Prologue: Why you need to learn JavaScript&lt;br /&gt;&lt;/h2&gt;For the foreseeable future (probably the next 5-10 years), the majority of software development will be done on web applications. Many of these will be ports of existing desktop applications or designed to replace such applications.  Developing desktop-like applications on the web is going to require that Ajax thing you've been hearing about, something called DHTML, DOM, etc. That means you'll be using JavaScript.&lt;br /&gt;&lt;br /&gt;We Java developers have been conditioned to flee at the first mention of JavaScript which has meant that it has long been the job of the 'creatives' to do the JavaScript work.  That's not going to cut it anymore. While the work &lt;acronym title="user experience"&gt;UX&lt;/acronym&gt; experts do is crucial to developing any application, they have different training, priorities and experiences. &lt;acronym title="Rich internet applications"&gt;RIAs&lt;/acronym&gt; need solid technical developers who understand best practices, patterns, unit testing, etc. and can apply them to JavaScript.&lt;br /&gt;&lt;br /&gt;One way Java developers try to avoid having to deal with JavaScript is through frameworks like &lt;acronym title="JavaServer Faces"&gt;JSF&lt;/acronym&gt; or &lt;acronym title="Google Web Toolkit"&gt;GWT&lt;/acronym&gt;.  There are certainly advantages to using a framework, but they are no substitute for being comfortable with JavaScript.  Developing RIAs through a framework without knowing JavaScript is like using Hibernate without a solid understanding of SQL and relational databases.  You may get by, but it wont be easy and it wont be pretty.&lt;br /&gt;&lt;br /&gt;Hopefully you're now convinced that JavaScript is in your future.  I want you to know that you don't have to be dragged into it kicking and screaming. It will be fun. You know those closure things that they're talking about putting in Java 7? JavaScript has always had them.  Ever get tired of writing the same Java code over and over? JavaScript code is far shorter and less repetitive.&lt;br /&gt;&lt;h2&gt;Differences: The Good, The Bad, and The Ugly&lt;/h2&gt;I'm going to focus on the immediately important differences for now. We'll pick up the more subtle ones as we go.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;JavaScript, like Java, has a C like syntax so you should feel pretty much at home. It has fewer keywords than Java, but adds a few new ones. The most important one is &lt;code&gt;function&lt;/code&gt;, which we'll talk about more in the next chapter, but there's also &lt;code&gt;var&lt;/code&gt;(declares a variable), &lt;code&gt;with&lt;/code&gt; (to generally be avoided), and &lt;code&gt;in&lt;/code&gt; (multiple uses).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;JavaScript is loosely (weak) typed.  For a UI, that's a good thing, because most of the data you're working with is string data, so you don't have to declare &lt;code&gt;String&lt;/code&gt; everywhere and if you need a string to occasionally be a number, it happens automatically.  Every object has a boolean value of true except 0,the empty string and &lt;code&gt;false&lt;/code&gt;. An undefined or null variable also evaluates to false, so you can check to see if an object has the method/property that you want like so:&lt;br /&gt;&lt;pre&gt;if(!foo.bar) {&lt;br /&gt; throw "foo must have bar";&lt;br /&gt; // you can throw anything to raise an error&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Of course, you can do whatever you like if the object you were passed doesn't have a particular method.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;There are only &lt;code&gt;Number&lt;/code&gt;s in JavaScript. There is no distinction between &lt;code&gt;int&lt;/code&gt;,&lt;code&gt;float&lt;/code&gt;, &lt;code&gt;double&lt;/code&gt; and &lt;code&gt;long&lt;/code&gt;.  &lt;code&gt;Math.round&lt;/code&gt;, &lt;code&gt;Math.floor&lt;/code&gt; and &lt;code&gt;Math.ceil&lt;/code&gt; are there if you need them. The maximum value is &lt;a href="http://www.thescripts.com/forum/thread91435.html"&gt;1.7976931348623157e+308&lt;/a&gt; so don't worry too much about overflowing. You shouldn't be doing any heavy computation on the client anyways.  If you try to do arithmetic with something that isn't a number, the result will be &lt;code&gt;NaN&lt;/code&gt; (not a number). &lt;code&gt;NaN&lt;/code&gt; and anything is &lt;code&gt;NaN&lt;/code&gt;. That includes undefined variables: &lt;pre&gt;var foo = 1;&lt;br /&gt;foo + bar; // == NaN, since bar is undefined&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;There is no &lt;code&gt;char&lt;/code&gt; type. You can use either single or double quotes to delimit a string. &lt;code&gt;'f'&lt;/code&gt; is always the string "f". &lt;code&gt;charCodeAt(index)&lt;/code&gt; on strings will give you the character code as a number.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In addition to functions, objects and arrays are first class citizens (technically functions and arrays are also objects).  You can define array literals using the [] syntax: &lt;code&gt;var myArray = [1,2,3];&lt;/code&gt;. For objects you use {} and provide a list of name:value pairs: &lt;code&gt;var myObj = { foo: "bar", baz: [1,2,3] }&lt;/code&gt;. Both array and object literals can span multiple lines. It's generally good form to break lines after a comma (if you must break lines):&lt;br /&gt;&lt;pre&gt;var foo = {&lt;br /&gt; bar: "baz", qux: 123,&lt;br /&gt; quxx: { a: 1, b: 2, c: 3}&lt;br /&gt;};&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Perhaps the most important JavaScript data type is the function.  We wont get into it now, but you need to know that you can treat functions like any other variable. e.g.,&lt;br /&gt;&lt;pre&gt;var foo = function(a,b) {&lt;br /&gt; return a + b;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;foo(1,2); // == 3&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;When a function is called as a property of an object, it gets access to &lt;code&gt;this&lt;/code&gt;. e.g.,&lt;pre&gt;var foo = new Object();&lt;br /&gt;foo.bar = function(a) {&lt;br /&gt; return a + this.b;&lt;br /&gt;};&lt;br /&gt;foo.b = 2;&lt;br /&gt;foo.bar(1); // == 3&lt;br /&gt;foo.bar(2); // == 4&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Note that while you can get put a reference to foo's bar function in a variable, it will no longer have access to foo via &lt;code&gt;this&lt;/code&gt;.&lt;pre&gt;var bar = foo.bar;&lt;br /&gt;bar(2); // == NaN (not a number)&lt;/pre&gt; Since &lt;code&gt;this.b&lt;/code&gt; is undefined, 2 + undefined is NaN.  You might be wondering why &lt;code&gt;this.bar&lt;/code&gt; doesn't result in an error. Well, it's because &lt;code&gt;this&lt;/code&gt; is always defined. Since JavaScript executes in the context of the browser window, the default &lt;code&gt;this&lt;/code&gt; is the window.  This is where all global variables live. Incidentally, you can reference the window explicitly with the &lt;code&gt;window&lt;/code&gt; object.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;There is a difference in scoping in JavaScript as well. You're used to having block local variables. Well, in JavaScript variables are either global or function local. Blocks share their enclosing scope, so&lt;br /&gt;&lt;pre&gt;var foo;&lt;br /&gt;if(true) {&lt;br /&gt; foo = 1;&lt;br /&gt;}&lt;/pre&gt;is the same as&lt;pre&gt;if(true) {&lt;br /&gt; var foo = 1;&lt;br /&gt;}&lt;/pre&gt;&lt;code&gt;foo&lt;/code&gt; will still be visible after the else block. If you fail to define a &lt;code&gt;var&lt;/code&gt; inside a function, a global variable is created (or if it exists it is overwritten). e.g.,&lt;pre&gt;&lt;br /&gt;function() {&lt;br /&gt; foo = 1; // sets window.foo = 1&lt;br /&gt;}&lt;/pre&gt;So, think carefully about scope when you declare and use variables.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;JavaScript is interpreted, which means that you don't even know 100% if a line of your script is valid until it actually runs.  That makes unit testing crucial. Fortunately tools like JUnit, Javadoc, etc. all have JavaScript equivalents that will seem very familiar.  There are also a host of development tools including Eclipse plugins, Aptana, IntelliJ support, etc. to help you along.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Lastly, you should know that JavaScript inheritance is prototypal. It is fully possible to achieve class based inheritance, which we will do with the help of a library called Prototype, but the prototypal nature of JavaScript gives us some interesting options which we will explore later.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Your Environment&lt;br /&gt;&lt;/h2&gt;We're Java developers, so we know the power of a good IDE. Eclipse, NetBeans and IntelliJ all have decent JavaScript support.  There are  a variety of plug-ins for Eclipse (I use &lt;a href="https://www.adobe.com/cfusion/entitlement/index.cfm?e=labs%5Fjseclipse"&gt;JSEclipse&lt;/a&gt;), but I'm going to tell you right now that none of them will give you the code completion that you're used to. It's simply not possible with a dynamic, weakly typed language.  You'll have to learn APIs the old fashioned way, by reading the docs and using them.&lt;br /&gt;&lt;br /&gt;Fortunately, JavaScript gives you an amazing debugging and exploratory tool that you have never had and likely will never have with Java. Its name is &lt;a href="http://www.getfirebug.com/"&gt;Firebug&lt;/a&gt;.  Go ahead and install it. Done? You need to restart Firefox. OK. Good. Now see &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ZS-2AgZmgD0/SYCMhl9Th5I/AAAAAAAABBg/5sLDGe9JBx4/s1600-h/Picture+1.png"&gt;&lt;img style="cursor: pointer; width: 22px; height: 18px;" src="http://4.bp.blogspot.com/_ZS-2AgZmgD0/SYCMhl9Th5I/AAAAAAAABBg/5sLDGe9JBx4/s200/Picture+1.png" alt="" id="BLOGGER_PHOTO_ID_5296387670540519314" border="0" /&gt;&lt;/a&gt; in the bottom right corner? Click it. This is Firebug. It does a lot of things, but for now we're just going to mess around with the 'command line'. Do the following:&lt;br /&gt;&lt;ol id="demoSteps"&gt;&lt;li&gt;Click the &lt;img src="http://bp3.blogger.com/_ZS-2AgZmgD0/R60W2w2RQGI/AAAAAAAAArk/EmNUp0LB5aA/s200/bigConsole.png" /&gt; in the bottom right corner of Firebug.&lt;/li&gt;&lt;li&gt;Paste this into the command line and press Ctrl+Enter or click 'Run':&lt;br /&gt;&lt;pre&gt;$('demoSteps').childElements().each(function(item,i) {&lt;br /&gt; item.insert("("+i+")");&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;OK, it's not the most impressive example, but you did just execute code without having to reload the page or anything.  Here we're making use of a library called &lt;a href="http://www.prototypejs.org/"&gt;Prototype&lt;/a&gt;. Bookmark the &lt;a href="http://www.prototypejs.org/api/"&gt;API&lt;/a&gt; immediately. What the above code does is call a function named '$' (yes, that's a valid variable name in JavaScript) with the argument 'demoSteps'. When $ is given a string, it looks for the element in the HTML with &lt;code&gt;id="demoSteps"&lt;/code&gt;. We get the child elements and iterate over them, calling the anonymous function we defined there on each element, along with it's index. We then append the index in parentheses to the body of each element.&lt;br /&gt;&lt;br /&gt;The equivalent JavaScript without Prototype is a lot longer.  You could start learning JavaScript without any libraries, but then you'd quickly get caught up in fixing bugs and writing the same code over an over.  Fixing bugs doesn't give you a good appreciation for a language, nor does clunky repetitive code.  In any serious web project you will use Prototype or a similar library, so it doesn't hurt to know it. After you're comfortable, we will delve deeper into the JavaScript language and you'll learn what Prototype hides from you.&lt;br /&gt;&lt;br /&gt;Before we go, drag this onto your bookmarks toolbar: &lt;a href="javascript:void(function(){var%20s=document.createElement('script');s.src='http://www.prototypejs.org/assets/2007/11/6/prototype.js';document.getElementsByTagName('head')[0].appendChild(s);}())"&gt;Insert Prototype&lt;/a&gt;. Now you can go to any web page, click that bookmarklet, pop open the console and start using Prototype to play.  For homework, explore the Prototype API, especially the utility functions and the Enumerable methods.  Try to write as many snippets using the API as you can.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;Resources&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://javascript.crockford.com/"&gt;http://javascript.crockford.com/&lt;/a&gt; Read these essays. They're all pretty short, but they are essential. Also, get a copy of Crockford's &lt;a href="http://www.amazon.com/gp/product/0596517742?ie=UTF8&amp;amp;tag=noahsloancom-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0596517742"&gt;book&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=noahsloancom-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0596517742" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://jquery.com/"&gt;http://jquery.com/&lt;/a&gt; jQuery is very popular. It has tons of plug-ins, with new ones popping up everyday. You will need it.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;script src="http://www.prototypejs.org/assets/2007/11/6/prototype.js"&gt; &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-1723925334489937317?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/1723925334489937317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=1723925334489937317' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1723925334489937317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1723925334489937317'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/02/java-developers-guide-to-javascript.html' title='Quit being lazy. lern2javascript noob'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ZS-2AgZmgD0/SYCMhl9Th5I/AAAAAAAABBg/5sLDGe9JBx4/s72-c/Picture+1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-266687570832734199</id><published>2009-01-26T13:13:00.000-06:00</published><updated>2009-01-26T13:13:01.226-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='semantic web'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='maintenance'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='webdev'/><title type='text'>You don't know what a controller is for, do you?</title><content type='html'>This is my second post in what I'm going to call the "You deserve verbal abuse because your code is dumb" series. These are things that frustrate me greatly, like &lt;a href="http://iamnoah.blogspot.com/2009/01/whadya-know-this-semantic-markup-crap.html"&gt;creating spaghetti code because you don't understand CSS&lt;/a&gt;. (In fairness, my solution may not be obvious, but there is no excuse for highly fragmented spaghetti code in the view layer; someone should have come up with something better).&lt;br /&gt;&lt;br /&gt;Last time I talked about how you can use CSS to get rid of most of that if/else logic you have in your page templates. Today, I'm going to explain controllers to you. That's the C in &lt;abbrev title="Model View Controller"&gt;MVC&lt;/abbrev&gt;. You should know this stuff. The controller is the thing that receives the HTTP request and decides what to do with it. Most frameworks will map URLs to different controller classes and methods. The controller is responsible for picking the view to render and loading the right data based on the request (and maybe the URL).&lt;br /&gt;&lt;br /&gt;Most of you seem to think that it ends there, and that it's OK to take whatever convulted data structure your service layer spits out and pass that right on to the view. Lean in really close so I can hit you. No! Bad developer! The whole reason that we moved away from CGI/Servlets is because mixing the processing code and the view markup is a bad idea. Unfortunately, you Philistines didn't get it, so you invented crap like Struts that just puts a layer of abstraction around HTML code and then get yourselves back into the same mess.&lt;br /&gt;&lt;br /&gt;This is what your templates look like:&lt;pre&gt;&amp;lt;div id="${result.product.productInfo.productId.toString()}"&gt;&lt;br /&gt;&amp;lt;h4&gt; ${result.product.productInfo.productName.getLocalizedString(request.client.language)} &amp;lt;/h4&gt;&lt;br /&gt;etc....&lt;br /&gt;&lt;/pre&gt;and here is how they should look:&lt;pre&gt;&amp;lt;div id="${productId}"&gt;&lt;br /&gt;&amp;lt;h4&gt; ${productName} &amp;lt;/h4&gt;&lt;br /&gt;etc....&lt;br /&gt;&lt;/pre&gt;The controller is responsible for getting and creating a model that makes sense for the view. Even the most technically averse designer can look at a view with a smart controller and figure out what's going on and how to edit it. It's when the expressions start to get long and the if/else logic creeps in that they start to get confused and scared. So, have pity on the designers, keep the logic in the controller. If you're careful, maybe someday the designers can get in there and actually change the templates themselves, instead of having to file a bug report for every single HTML change. Wouldn't that be nice?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-266687570832734199?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/266687570832734199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=266687570832734199' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/266687570832734199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/266687570832734199'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/01/you-dont-know-what-controller-is-for-do.html' title='You don&apos;t know what a controller is for, do you?'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-804011269640866435</id><published>2009-01-23T12:16:00.011-06:00</published><updated>2009-07-11T12:14:38.742-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='code quality'/><category scheme='http://www.blogger.com/atom/ns#' term='maintenance'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>One liners for readability</title><content type='html'>(For clarity, when I say one liner, I mean single statement. For various reasons, including readability, it may be desirable to split statements across multiple lines)&lt;br /&gt;&lt;br /&gt;Which is easier to read? Is it this multi-statement snippet:&lt;br /&gt;&lt;pre&gt;def params = request.params&lt;br /&gt;def config = whatever.getMyConfig()&lt;br /&gt;def request = MyLongTypeNameRequestTransformer.toMyRequest(params, config)&lt;br /&gt;def result = myLongNamedServiceThatDoesSomethingCool.execute(request)&lt;br /&gt;&lt;/pre&gt;or this single statement:&lt;br /&gt;&lt;pre&gt;def result = myLongNamedServiceThatDoesSomethingCool.execute(&lt;br /&gt;  MyLongTypeNameRequestTransformer.toMyRequest(&lt;br /&gt;      request.params, whatever.getMyConfig ) )&lt;br /&gt;// line breaks added to protect the page-width. 80 columns&lt;/pre&gt; Now your answer to that question probably depends on how you interpreted 'easier to read'. Most of you probably thought that I meant "Which format makes it easier to understand what this snippet does?" Typically people are going to say that the first one is more clear in that respect. However, I want to consider a different question, "Which format makes it easier to understand/follow/debug/grok/refactor the overall codebase?"&lt;br /&gt;&lt;br /&gt;I would argue that the second form is better in that respect, and that overall manageability of a codebase is generally more important than a small readability improvement for a section of code.  I see one liners as an implied abstraction. It hints to the reader that, despite the complexity involved, we are really only interested in one result (either a return value or a side effect), so they can mentally collapse all that code into "get X" or "do Y". It says, "Skim over me, the details are not important."&lt;br /&gt;&lt;br /&gt;There are two alternatives to one liners. The first is to use a bunch of local variables. While this can certainly make an algorithm more readable, each one adds one more thing that I have to keep track of when I'm reading your code. I have to remember that config came from whatever.getMyConfig(), and I have to consider that it may be used later in the method. If config is inlined, I don't even have to mentally register its existence unless I'm trying to parse the one liner.&lt;br /&gt;&lt;br /&gt;The second alternative is to encapsulate the snippet as a function. This gets rid of the mental scope pollution from stray variables, but it introduces two new problems. Firstly, if I want to know what the function does, I have to go to another place in the file (or another file), which breaks the continuity. Often times one liners also need several of the variables in the current scope, so you end up with a lot of parameters, which adds even more clutter. Secondly, you end up poluting the scope of the class or script with yet another function that is only used in one place. You've just moved the clutter up a level.&lt;br /&gt;&lt;br /&gt;Now, there are certainly times and places where  you don't want to inline everything all willy nilly. If an expression appear multiple times in a function (e.g., whatever.getConfig()), don't repeat yourself, use a local variable. If you can extract a function that can be used in more than one place, go right ahead. If you have code that is several indentation levels deep, first consider a redesign and/or refactoring that simplifies, but if that doesn't work, extract a function to make it more readable. However, declaring variables and functions should be things that you do out of a clear need, not just because you think you'll need it, or because your CS professor always told you to (CS professors are concerned with algorithms and minutia, not codebase managability). Remember,  &lt;a href="http://www.codinghorror.com/blog/archives/000061.html"&gt;premature optimization is the devil&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Most modern languages offer syntax that can assist in creating readable one-liners. If your language has map/has and/or list literals, you should avoid building those constructs procedurally. e.g., in JavaScript:&lt;br /&gt;&lt;pre&gt;var array = new Array();&lt;br /&gt;array[0] = 'foo';&lt;br /&gt;array.push('bar');&lt;br /&gt;myMethod(array);&lt;br /&gt;&lt;/pre&gt;is lame. Write that as&lt;br /&gt;&lt;pre&gt;myMethod(['foo','bar']);&lt;br /&gt;&lt;/pre&gt;Groovy's map literal:&lt;br /&gt;&lt;pre&gt;myMethod([foo:'bar',baz:'quxx']);&lt;br /&gt;&lt;/pre&gt; Even Java can be slightly improved thanks to anonymous inner classes and initializer blocks:&lt;br /&gt;&lt;pre&gt;myMethod(new HashMap() {&lt;br /&gt;{&lt;br /&gt; put("foo","bar");&lt;br /&gt; put("baz","qux");&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;Hopefully you have the idea by now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-804011269640866435?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/804011269640866435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=804011269640866435' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/804011269640866435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/804011269640866435'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/01/one-liners-for-readability.html' title='One liners for readability'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-334978584920168943</id><published>2009-01-20T14:31:00.002-06:00</published><updated>2009-01-23T14:40:05.975-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='semantic web'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='webdev'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Whadya know, this semantic markup crap is actually useful</title><content type='html'>&lt;h4&gt;why you should use a rules engine&lt;br /&gt;&lt;/h4&gt;The UI of a web application generally consumes 60-90% of the development effort. UIs are complex, and they're big.  All the cross cuttng concerns of the application combine in the UI to give you as many versions as there are variables. For many sites that means there can be hundreds of unique ways for a page to be rendered. As a consultant, I see a lot of you writing templates that look like this:&lt;br /&gt;&lt;pre&gt;&amp;lt;div id="product"&gt;&lt;br /&gt;&amp;lt;c:if test="${hasErrors}"&gt;&lt;br /&gt; &amp;lt;div class="errors"&gt;&lt;br /&gt;  Bid must be a number&lt;br /&gt; &amp;lt;/div&gt;&lt;br /&gt;&amp;lt;/c:if&gt;&lt;br /&gt;&amp;lt;c:if test="${forSale}"&gt;&lt;br /&gt; &amp;lt;input class="buyButton" value="Buy!" type="button"&gt;&lt;br /&gt;&amp;lt;/c:if&gt;&lt;br /&gt;&amp;lt;c:else&gt;&lt;br /&gt; &amp;lt;span id="saleMessage"&gt;Sorry, not for sale.&amp;lt;/span&gt;&lt;br /&gt;&amp;lt;/c:else&gt;&lt;br /&gt;&amp;lt;c:if test="${isAdmin}"&gt;&lt;br /&gt; &amp;lt;input value="Delete" class="deleteButton" type="button"&gt;&lt;br /&gt;&amp;lt;/c:if&gt;&lt;br /&gt;&amp;lt;/div&gt;&lt;br /&gt;&lt;/pre&gt;You get tag/conditional soup, because the there are a bunch of different states that the page could be in, and you have to show/hide lots of things, or give things different colors, or whatever based on whatever state the page is in. Or maybe you list several things on a page, and some of them will be in different states than others. Or you have some button that the user isn't allowed to click because they don't have the right role.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If you have tag soup, you're doing it wrong. &lt;/span&gt; All of the things I described above are state, or semantically useful information. With the exception of hiding information from those who are not allowed to see it, there is absolutely no reason not to render just about everything and use CSS rules to hide and otherwise transform the page based on the current situation. Here's an example:&lt;br /&gt;&lt;pre&gt;&amp;lt;div id="product" class="user${userRole} ${forSale ? '' : 'notForSale'} ${hasErrors ? 'error' : ''}"&gt;&lt;br /&gt;&amp;lt;div class="errors"&gt;&lt;br /&gt; Bid must be a number&lt;br /&gt;&amp;lt;/div&gt;&lt;br /&gt;&amp;lt;input class="buyButton" value="Buy!" type="button"&gt;&lt;br /&gt;&amp;lt;span id="saleMessage"&gt;Sorry, not for sale.&amp;lt;/span&gt;&lt;br /&gt;&amp;lt;input value="Delete" class="deleteButton" type="button"&gt;&lt;br /&gt;&amp;lt;/div&gt;&lt;br /&gt;&lt;/pre&gt;And you have CSS rules like so:&lt;br /&gt;&lt;pre&gt;.errors, .deleteButton, .notForSale .buyButton, #saleMessage { display: none; }&lt;br /&gt;.error .errors { display: block; }&lt;br /&gt;.notForSale #saleMessage { display: inline; }&lt;br /&gt;&lt;/pre&gt; You can't tell me that isn't simpler. It's easier to read too. All those business rules that you have translate nicely to CSS rules. Imagine that, rules begin easily represented as rules. This approach combines nicely with Ajax as well. Receive an update from the server and suddenly the item is for sale? &lt;code&gt;$('#product').removeClass('notForSale');&lt;/code&gt; and the browser takes care of the rest.&lt;br /&gt;&lt;br /&gt;You might tell your self such an approach would never fly, what about security? Anyone could look at the source and see the delete button, or use Firebug to show it, then suddenly they're deleting things! Hopefully you understand the problem with that argument, but for the naive: if you're not checking permissions and validating data on the server, you're wide open to all kinds of attacks. Your rendered HTML is just the preferred interface. The real interface to your application is HTTP, and an attacker will quickly figure out what a real delete request looks like, so unless you're also checking credentials, you're screwed.&lt;br /&gt;&lt;br /&gt;The exception, as I said before, is information that needs to stay secret. You shouldn't render some element with user passwords and hide it with CSS. Don't do it with trade secrets, launch codes or your secret pictures of yourself dressed as a drag queen either. For anything else, take advantage of one of those things about semantic markup that actually works well, and make your life simpler.&lt;br /&gt;&lt;br /&gt;Next time: You obviously don't understand what a controller is for.&lt;br /&gt;&lt;br /&gt;But first: &lt;a href="http://iamnoah.blogspot.com/2009/01/one-liners-for-readability.html"&gt;Writing one liners; for readability&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-334978584920168943?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/334978584920168943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=334978584920168943' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/334978584920168943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/334978584920168943'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2009/01/whadya-know-this-semantic-markup-crap.html' title='Whadya know, this semantic markup crap is actually useful'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-7324272768888246312</id><published>2008-08-27T16:45:00.000-05:00</published><updated>2008-08-27T16:45:01.020-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teams'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='project management'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>'Opt-In' Changes and the Importance of Testing Suites</title><content type='html'>A development mistake I see all the time is when a developer fails to make changes to core classes 'Opt-In' or backwards compatible.  For example, suppose you find a bug in your table/grid widget that causes one of the several instances of that widget to fail mysteriously.  You come up with a solution that involves an extra method call or two at a certain point, or changing an option/property to another value. Your first instinct might be to make that change the default behavior, but in most cases, that's wrong.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Minimize Affect&lt;/h2&gt;&lt;br /&gt;Summary: How many instances of that widget do you have in your application? Are they all failing? Why not? Were they functioning properly before? If they ain't broke, why fix 'em?  &lt;br /&gt;&lt;br /&gt;Most likely the change you are going to make really should have been the default behavior all along, however, you now have working code that was developed and presumably tested against the old behavior. If you change that behavior now, even if it is now the 'right' behavior and was previously the 'wrong' behavior, you now need to test every single instance and subclass of your widget in all possible scenarios to ensure you haven't introduced a bug.  Do you have a comprehensive automated testing suite? If you do, great, but you probably don't.&lt;br /&gt;&lt;br /&gt;Even if you do have a good test suite, why fix something that isn't broken? Suppose, instead of making that change the default, you instead add a &lt;code&gt;useFooHack&lt;/code&gt; property to your base class. It defaults to false, but if it's true, you use your new behavior. When you discover that other instances have a problem caused by the old behavior, you just change the flag to enable Foo, and it's fixed. Easy as that. If you discover that every last instance has the problem, you can remove the &lt;code&gt;useFooHack=true&lt;/code&gt; line from your instances and &lt;code&gt;if(useFooHack)&lt;/code&gt; from your base class. Simple.  The alternative is to risk introducing bugs into every instance that you thought was working.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Testing is a waste of time&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Now some people will learn of problems like this and say you should have done more testing before committing. You know, you should have gone through all the major paths of your application to ensure that they're working before committing. Most of the time those people are managers who don't have to waste time doing the testing themselves, but expect you to do it. &lt;br /&gt;&lt;br /&gt;Suppose a developer spends X time testing before a check-in and finds some bugs that take Y time to fix, it has cost him X+Y time. However if he instead verifies that his code does what he intended it to do and checks in, but someone discovers the bugs, emails him, and he spends Y time fixing it, it only cost him Y time. Now if X is small, say 30 seconds, because all the developer had to do was kick off the automated testing suite, then the developer will do the testing to avoid getting angry emails. However, if testing takes more than a few minutes, most people will realize they can get more work done by letting someone else hunt for bugs. You can argue about it all you want, you're not going to change human nature, and the optimal choice most of the time is to skimp on the testing. &lt;br /&gt;&lt;br /&gt;In short, you have to work with people the way they are. No amount of training or lecturing will keep people doing things that are not in their own best interest. If your project's big problem is that people keep breaking the build, make not breaking the build the easy path. You may have to sacrifice some hours to developing and maintaining a test suite, but you will generally save more hours of lost productivity from broken builds.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-7324272768888246312?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/7324272768888246312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=7324272768888246312' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7324272768888246312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7324272768888246312'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/08/opt-in-changes-and-importance-of.html' title='&apos;Opt-In&apos; Changes and the Importance of Testing Suites'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-2341383785255696089</id><published>2008-08-20T17:28:00.004-05:00</published><updated>2008-08-21T20:54:09.109-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Java Fun Continued - Groovy FTW</title><content type='html'>Here's the equivalent Groovy for my previous Java &lt;a href="http://iamnoah.blogspot.com/2008/08/java-fun-when-all-you-have-is-hammer.html"&gt;abomination&lt;/a&gt; that prints the Java wrapper methods for me:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;new File("src/main/java/Foo.java").text.&lt;br /&gt;    replaceAll(/(?sm)\s*public\s+(\S+)\s+(\S+)\((.*?)\)\s*\{/) { &lt;br /&gt;       s,ret,name,params -&gt;&lt;br /&gt;  print """&lt;br /&gt;    public ${ret} ${name}(${params}) {&lt;br /&gt;        """&lt;br /&gt;  if("void" != ret) {&lt;br /&gt;    print "return "&lt;br /&gt;  }&lt;br /&gt;  print "foo.${name}("&lt;br /&gt;  // -1 hack avoids index out of bounds when params is ''&lt;br /&gt;  print params.trim().split(/\s*,\s*/).collect { &lt;br /&gt;    it.split(/\s+/)[-1] &lt;br /&gt;  }.join(',')&lt;br /&gt;  print """);&lt;br /&gt;    }&lt;br /&gt;"""&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I could change the prints to concatenation and reformat the whole thing as a single line, so it only counts as one statement. Technically I cheated a little because this version doesn't look up the methods by reflection, but it doesn't make a difference in the result, and wouldn't significantly shorten the Java code. Definitely more readable than the Java. The JavaScript is a little messier since you don't have multi-line string literals, &lt;a href="http://groovy.codehaus.org/Strings"&gt;GString&lt;/a&gt;s, and closures are &lt;code&gt;function(it){ return it.foo; }&lt;/code&gt; instead of &lt;code&gt;{ it.foo }&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-2341383785255696089?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/2341383785255696089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=2341383785255696089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/2341383785255696089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/2341383785255696089'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/08/java-fun-continued-groovy-ftw.html' title='Java Fun Continued - Groovy FTW'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-9182349898364993000</id><published>2008-08-20T12:24:00.004-05:00</published><updated>2008-08-21T10:53:48.770-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Java Fun: When all you have is a hammer...</title><content type='html'>I ought to be ashamed, but I was bored and lazy, so I thought I'd test my somewhat dormant Java skills. Can you tell me (without running it) what this code does?&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  Method[] methods = Foo.class.getMethods();&lt;br /&gt;  String source = FileUtils.readFully(new FileReader(&lt;br /&gt;    "src/main/java/"&lt;br /&gt;      + Foo.class.getCanonicalName().replaceAll(&lt;br /&gt;        "\\.", "/") + ".java"));&lt;br /&gt;  PrintStream out = System.out;&lt;br /&gt;  for (Method method : methods) {&lt;br /&gt;   Matcher matcher = Pattern.compile(&lt;br /&gt;     "public (\\S+?) " + method.getName() + "\\((.*?)\\)",&lt;br /&gt;     Pattern.DOTALL | Pattern.MULTILINE).matcher(source);&lt;br /&gt;   if (matcher.find()) {&lt;br /&gt;    String ret = matcher.group(1);&lt;br /&gt;    String params = matcher.group(2);&lt;br /&gt;    out.printf(" public %s %s(", ret, method.getName());&lt;br /&gt;    out.print(params);&lt;br /&gt;    out.print(") {\n  ");&lt;br /&gt;    if (!"void".equals(ret)) {&lt;br /&gt;     out.print("return ");&lt;br /&gt;    }&lt;br /&gt;    out.print("foo.");&lt;br /&gt;    out.print(method.getName());&lt;br /&gt;    out.print('(');&lt;br /&gt;    if (!StringUtils.isEmpty(params)) {&lt;br /&gt;     out.print(StringUtils.join(CollectionUtils.collect(&lt;br /&gt;       Arrays.asList(params.split(",\\s*")),&lt;br /&gt;       new Transformer() {&lt;br /&gt;        public Object transform(Object input) {&lt;br /&gt;         return ((String) input).split(" ")[1];&lt;br /&gt;        }&lt;br /&gt;       }), ','));&lt;br /&gt;    }&lt;br /&gt;    out.println(");\n }\n");&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I'll post the equivalent Groovy (and maybe JavaScript) &lt;a href="http://iamnoah.blogspot.com/2008/08/java-fun-continued-groovy-ftw.html"&gt;later&lt;/a&gt;. I imagine I can do it in a single statement function. I don't miss Java very much.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-9182349898364993000?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/9182349898364993000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=9182349898364993000' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/9182349898364993000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/9182349898364993000'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/08/java-fun-when-all-you-have-is-hammer.html' title='Java Fun: When all you have is a hammer...'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-2324422271843160997</id><published>2008-08-20T08:04:00.002-05:00</published><updated>2008-08-20T08:44:27.962-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='bike'/><title type='text'>New (to me) Bike: Issues letting go</title><content type='html'>My friend John is letting me borrow his fancy Specialized bike that he doesn't ride anymore. I'd say it's about a third of the weight of Old Creaky, my bike that I built at the &lt;a href="http://www.austinyellowbike.org/"&gt;Yellow Bike Project&lt;/a&gt;, and is definitely nicer in every way, but I'm having some problems letting go.&lt;br /&gt;&lt;br /&gt;Firstly, this thing is a true road bike, everything is built for speed. The problem is that the tires have little to no tread on them (by design) so if it's remotely wet or gravelly, I make myself slow way down because I'm afraid this thing will slip out from under me. Old Creaky had some decent tread, but not too much. Just something I need to get used to I supposed.&lt;br /&gt;&lt;br /&gt;Secondly, the shifters are those neat kind that are built into the brakes, so naturally they're &lt;a href="http://en.wikipedia.org/wiki/Shifter_(bicycle_part)#Index_shifting"&gt;indexed&lt;/a&gt;. I've been riding for the past year with &lt;a href="http://en.wikipedia.org/wiki/Shifter_(bicycle_part)#Friction_shifting"&gt;friction shifters&lt;/a&gt;, so I'm used to being able to go from 5th back to 1st in about 2 seconds just by pushing a little lever down. With these indexed things, I have to click, click, click, and then I'm not sure where I am because they don't have any sort of indicator, so I'm constantly looking down to see where the chain is. I suppose I'll get used to it, I just hope I don't get hit by a car in the meantime.&lt;br /&gt;&lt;br /&gt;Lastly, John is about 6'5", and although I'm 6'3" Old Creaky was not built for a 6'3" person, while John's bike is built for John, so I'm bent over a lot further than my back is used to. I'm sure I'll get used to it too. &lt;br /&gt;&lt;br /&gt;So, three things to beware of when you get a new bike. I wouldn't keep riding it if I didn't think it was a net positive, but I also never thought any of these things through. I'm working on my fear of change.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-2324422271843160997?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/2324422271843160997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=2324422271843160997' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/2324422271843160997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/2324422271843160997'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/08/new-to-me-bike-issues-letting-go.html' title='New (to me) Bike: Issues letting go'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-13552587960023167</id><published>2008-06-17T13:29:00.005-05:00</published><updated>2008-06-17T13:37:39.730-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell scripting'/><category scheme='http://www.blogger.com/atom/ns#' term='cisco'/><category scheme='http://www.blogger.com/atom/ns#' term='os x'/><category scheme='http://www.blogger.com/atom/ns#' term='vpn'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Cisco VPN Client Shell Script on OS X</title><content type='html'>I like to start and stop the VPN client from the command line, but sometimes, for whatever reason, the VPN service isn't running or isn't responding. I then have to go Google it to find the incantation to restart it.  Rather than do that every time, I use this script to connect to the VPN:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CMD="sudo vpnclient connect MyProfileName user myUserName pwd myPassword"&lt;br /&gt;yes | $CMD&lt;br /&gt;if [[ $? -eq 8 ]]&lt;br /&gt;then&lt;br /&gt;    # exit code of 8 means it couldn't connect to the vpnd&lt;br /&gt;    sudo /System/Library/StartupItems/CiscoVPN/CiscoVPN restart&lt;br /&gt;    yes | $CMD&lt;br /&gt;fi&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-13552587960023167?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/13552587960023167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=13552587960023167' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/13552587960023167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/13552587960023167'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/06/cisco-vpn-client-sheel-script-on-os-x.html' title='Cisco VPN Client Shell Script on OS X'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-1993790975894399753</id><published>2008-05-15T08:56:00.003-05:00</published><updated>2008-05-15T09:38:03.023-05:00</updated><title type='text'>Static vs. Dynamic: The Line</title><content type='html'>If you read many programming blogs, you've probably heard about the recent rekindling of the static vs. dynamic debate. In particular, it started with Steve Yegge's &lt;a href="http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html"&gt;Dynamic Languages Strike Back&lt;/a&gt;, followed by Cedric Beaust's &lt;a href="http://beust.com/weblog/archives/000483.html"&gt;Return Of The Statically Typed Languages&lt;/a&gt; and finally Ola Bini's &lt;a href="http://ola-bini.blogspot.com/2008/05/new-hope-polyglotism.html"&gt;A New Hope: Polyglotism&lt;/a&gt;. Ola does a good job of summarizing the other 2 and then proclaims that the correct answer is somewhere in between, using both static and dynamic languages in different situations.&lt;br /&gt;&lt;br /&gt;As a Java developer who knows JavaScript far too well, this is something I've believed for quite some time. I'm going to go one step further and say that I have a vague idea of where the line is where it is appropriate to switch from static to dynamic. If you've done much JEE development (if you're reading this, I know you have!), then you also know too, but you may not realize it.&lt;br /&gt;&lt;br /&gt;Think about a typical web application. Say we're using Struts, Spring, and Hibernate, but it really doesn't matter.  In the view we have this mix of XML/HTML and some sort of code, be it logic tags or inline code. The type of everything is a string. We produce a big string as the output, all the inputs are strings, we validate strings. We have to do conversion in varying degrees to pass things on to the service layer, but by the time we get to the persistence layer, you better not be passing a String when you really need a Long.  Did you spot it? We get virtually no benefit from types in the view, which is why no one uses Servlets anymore. Declaring that everything is a String is kind of pointless, so a dynamic language is a good choice for the view.  On the other side, types help us ensure the integrity of our persistent data and let us avoid nasty things like injection attacks. The persistance tier has to be fast and it has to be correct. A UI glitch is annoying, but if we commit corrupt or invalid data, we're in big trouble. &lt;br /&gt;&lt;br /&gt;That leaves the middle tier, which is where the blurry line between static and dynamic lies. One option would be to use a language with optional static types like Groovy (i.e., persistence layer is pure Java, middle tier is Groovy, top is JavaScript or Groovy with minimal typing).  Another would be to use a library like DWR that takes care of most of the type conversions so you can have a statically typed service later but a fully dynamic view.  The JVM really shines here because it gives us so many options. What languages you choose are largely going to be affected by what people know (i.e., what's easy to support) but picking the right tool for the job is important too. I think one thing is certain though, the days where developers can be effective knowing just one language are drawing to a close.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-1993790975894399753?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/1993790975894399753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=1993790975894399753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1993790975894399753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1993790975894399753'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/05/static-vs-dynamic-line.html' title='Static vs. Dynamic: The Line'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-5275728709564398356</id><published>2008-04-16T17:07:00.006-05:00</published><updated>2008-04-16T17:20:53.487-05:00</updated><title type='text'>RegExs for Common JavaScript Bugs</title><content type='html'>I use these 2 quite a bit:&lt;br /&gt;&lt;dl&gt;&lt;br /&gt;&lt;dt&gt;&lt;code&gt;:\s*[\[{]\s*[\]}]&lt;/code&gt;&lt;br /&gt;&lt;dd&gt;This catches empty object and array literals in another object literal. Chances are you put this in a class/prototype definition like so:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Class.create({&lt;br /&gt;  myHash: {},&lt;br /&gt;  myList: []&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's roughly equivalent to declaring 'myHash' and 'myList' as &lt;code&gt;static&lt;/code&gt; in Java. Unless you really want every instance of that class to share the same hash/array, that initialization needs to happen in the constructor:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Class.create({&lt;br /&gt;  initialize: function() {&lt;br /&gt;    this.myHash = {};&lt;br /&gt;    this.myList = [];&lt;br /&gt;  }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;dt&gt;&lt;code&gt;,\s*[\]}]&lt;/code&gt;&lt;br /&gt;&lt;dd&gt;Catches &lt;code&gt;[1,2,]&lt;/code&gt; and &lt;code&gt;{1,2,}&lt;/code&gt;. The trailing comma causes IE to fail silently, which is always fun to debug. Since this is always wrong, you can change that to &lt;code&gt;,(\s*[\]}])&lt;/code&gt; and do a find and replace with &lt;code&gt;$1&lt;/code&gt; as the replacement.&lt;br /&gt;&lt;/dl&gt;&lt;br /&gt;Post another regex findable bug if you know one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-5275728709564398356?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/5275728709564398356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=5275728709564398356' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/5275728709564398356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/5275728709564398356'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/04/regexs-for-common-javascript-bugs.html' title='RegExs for Common JavaScript Bugs'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-8604114875347643988</id><published>2008-02-25T20:00:00.000-06:00</published><updated>2008-02-25T21:43:44.931-06:00</updated><title type='text'>A Java Developer's Guide to JavaScript - Functional Programming and JavaScript Mechanics</title><content type='html'>&lt;h2&gt;Homework Check&lt;/h2&gt;Last time we introduced the Prototype library. Hopefully by now you've at least looked over the Prototype API and are semi-comfortable with Firebug. If not, stop and take a few minutes to look around and write a short script or two.&lt;br /&gt;&lt;h2&gt;Functional Programming&lt;/h2&gt;Functional programming is one of those things we don't really do in Java, since Java lacks first class functions. Essentially, when you can pass functions around like any other variable, you often end up sticking them together ("composing" them) to create new functions. The result of one function gets fed into another, etc. Programming effectively in JavaScript requires recognizing that many patterns that are explicit in Java are implicit in a functional language like JavaScript.&lt;br /&gt;&lt;p&gt;There are several 'classic' functions that are usually the basis of any good functional programming library:&lt;br /&gt;&lt;/p&gt;&lt;dl&gt;&lt;dt&gt;&lt;span style="font-style: italic;"&gt;map/collect&lt;/span&gt;&lt;br /&gt;&lt;/dt&gt;&lt;dd&gt;A map function takes a value and returns a new value. It's complement is reduce/inject. Here's an example using Prototype's collect function:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var foo = [1,2,3,4,5];&lt;br /&gt;var bar = foo.collect(function(a) {&lt;br /&gt; return a * 2;&lt;br /&gt;}); // bar = [2,4,6,8,10]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/dd&gt;&lt;dt&gt;&lt;span style="font-style: italic;"&gt;reduce/inject&lt;/span&gt;&lt;br /&gt;&lt;/dt&gt;&lt;dd&gt;Takes two values (at least one is usually a collection, but they both can be) and combines them into one value. When called inject, the first value is usually the 'accumulator' and the second is a singular value. With Prototype, you'll use map/collect and inject on collections, but that's not the only way it is used. Map-Reduce is what powers Google searches. Here's an example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var foo = [5,4,3,2,1];&lt;br /&gt;var bar = foo.inject(1,function(a,b) {&lt;br /&gt; return a * b;&lt;br /&gt;}); // bar == 120&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A little explanation for this one. The first call, the parameters are (1,5), the next call is (5,4), then next is (20,3), etc. The above is how inject works in Prototype, other versions of reduce can pass two outputs of reduce instead of the previous output and the next input. e.g., it might do (1,5), then (4,3), (2,1), resulting in 5,12,and 2, then apply the reduce function on the results and so on until we have a single value. To see how map/reduce powers Google, read &lt;a href="http://www.joelonsoftware.com/items/2006/08/01.html"&gt;Can Your Programming Language Do This?&lt;/a&gt;&lt;br /&gt;&lt;/dd&gt;&lt;dt&gt;&lt;span style="font-style: italic;"&gt;select/findAll&lt;/span&gt;&lt;br /&gt;&lt;/dt&gt;&lt;dd&gt;Used to select/find a subset of a collection.  e.g.,&lt;br /&gt;&lt;pre&gt;[1,2,3,4,5].select(function(a) {&lt;br /&gt; return a % 2 == 0;&lt;br /&gt;}); // = [2,4]&lt;br /&gt;&lt;/pre&gt;&lt;/dd&gt;&lt;dt&gt;&lt;span style="font-style: italic;"&gt;all&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;any&lt;/span&gt;&lt;br /&gt;&lt;/dt&gt;&lt;dd&gt;Returns true if any or all of the elements in a collection match a given predicate. e.g.,&lt;br /&gt;&lt;pre&gt;[1,2,3,4,5].any(function(a) {&lt;br /&gt; return a == 4;&lt;br /&gt;}); // == true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With Prototype, if you do not pass a predicate, then the value is evaluated as a boolean. You could use this to detect if a collection contains all (or any) non-zero, non-false and non-empty string values.&lt;br /&gt;&lt;/dd&gt;&lt;/dl&gt;There are other common functions, but these cover the conceptual core. Most other functions will build off of these in some way. As you get to know the common functions, you'll discover uses for them that are extremely powerful.&lt;br /&gt;&lt;h2&gt;Manipulating Functions in JavaScript&lt;br /&gt;&lt;/h2&gt;Before we talk about design patterns, we need to quick take a look under the JavaScript hood and see how we can manipulate the scope and arguments of functions. Remember that when we call a function as a member of an object, the &lt;code&gt;this&lt;/code&gt; keyword lets us access variables in the scope of that object. But if you have only a reference to a function and you try to call it, &lt;code&gt;this&lt;/code&gt; will refer to the global (window) scope.  To allow us to set the scope of a function, we can use &lt;code&gt;call&lt;/code&gt;. Here's an example:&lt;br /&gt;&lt;pre&gt;var foo = { a: 1};&lt;br /&gt;function aPlus(b) {&lt;br /&gt; this.a = this.a + b;&lt;br /&gt; return this.a;&lt;br /&gt;}&lt;br /&gt;aPlus.call(foo,5); // == 6 &amp;amp;&amp;amp; foo.a == 6&lt;br /&gt;&lt;/pre&gt;This would be almost equivalent to&lt;br /&gt;&lt;pre&gt;foo.aPlus = aPlus;&lt;br /&gt;foo.aPlus(5);&lt;br /&gt;&lt;/pre&gt;However, the second example will overwrite &lt;code&gt;aPlus&lt;/code&gt; on &lt;code&gt;foo&lt;/code&gt;. If &lt;code&gt;aplus&lt;/code&gt; happens to be an existing variable or method, we've now overwritten it.  &lt;code&gt;&lt;br /&gt;&lt;br /&gt;call&lt;/code&gt; can be used whenever you know the exact number of arguments you'll be passing to a function, but what if you don't? You might say, "When would that happen?" What if you have a function that takes a function as an argument, and returns another function? This is something we do a lot in functional programming, so we need a way to keep our function producing functions &lt;acronym title="Don't Repeat Yourself"&gt;DRY&lt;/acronym&gt;.&lt;br /&gt;&lt;br /&gt;Before we discuss how you would call a function without knowing the number of arguments, we need to talk about a special variable: &lt;code&gt;arguments&lt;/code&gt;.  Inside any function, the &lt;code&gt;arguments&lt;/code&gt; variable is automatically defined. &lt;code&gt;arguments&lt;/code&gt; is an array-like structure that has all the arguments passed to the function. In JavaScript, the parameters you declare fo a function are just convenient labels for indecies into &lt;code&gt;arguments&lt;/code&gt;. The JavaScript interpreter doesn't care if you call the &lt;code&gt;function foo(a,b)&lt;/code&gt; with 1,2, or 7 arguments. &lt;code&gt;a = arguments[0]&lt;/code&gt; and &lt;code&gt;b = arguments[1]&lt;/code&gt;, and if &lt;code&gt;arguments[1]&lt;/code&gt; is undefined, so is &lt;code&gt;b&lt;/code&gt;.  Like an array, &lt;code&gt;arguments&lt;/code&gt; has a length, so you can iterate over it. e.g.,&lt;br /&gt;&lt;pre&gt;function sum() {&lt;br /&gt; var sum = 0;&lt;br /&gt; for(var i = 0; i &amp;lt; arguments.length; i++) {&lt;br /&gt;   sum += arguments[i];&lt;br /&gt; }&lt;br /&gt; return sum;&lt;br /&gt;}&lt;/pre&gt;Suppose we also have this function:&lt;br /&gt;&lt;pre&gt;function double(a) {&lt;br /&gt; return a * 2;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;and we want to create a function that takes the sum of 2 or more numbers and returns twice the result. To reuse our existing functions, we need some way of creating a function that passes all of it's arguments to &lt;code&gt;sum&lt;/code&gt; regardless of the number of arguments passed to it.  &lt;code&gt;apply&lt;/code&gt; to the rescue! Like &lt;code&gt;call&lt;/code&gt;, &lt;code&gt;apply&lt;/code&gt; lets you call a function and set the value of &lt;code&gt;this&lt;/code&gt;, but instead of taking the arguments from the 2nd argument on, it takes an array (or array-like object) as the second parameter. e.g.,&lt;br /&gt;&lt;pre&gt;function doubleSum() {&lt;br /&gt; return double( sum.apply(this,arguments) );&lt;br /&gt;}&lt;br /&gt;doubleSum(1,1,1,1,1); // == 10&lt;br /&gt;doubleSum(1,2,3); // == 12&lt;br /&gt;doubleSum(); // == 0&lt;br /&gt;&lt;/pre&gt;We haven't made use of Prototype here yet because we haven't needed it. However, you may have noticed that we keep referring to &lt;code&gt;arguments&lt;/code&gt; as an "array-like" object.  That's because it's not a real &lt;a href="http://www.w3schools.com/jsref/jsref_obj_array.asp"&gt;Array&lt;/a&gt; and doesn't have any of the instance methods you can expect an array to have. Prototype provides a utility function for just this purpose, &lt;code&gt;$A&lt;/code&gt;.  &lt;code&gt;$A(arguments)&lt;/code&gt; returns a true array with all of the arguments in it, so you can call all the standard Array methods and &lt;a href="http://www.prototypejs.org/api/array"&gt;Prototype&lt;/a&gt; methods on it. We can rewrite &lt;code&gt;sum&lt;/code&gt; like so:&lt;br /&gt;&lt;pre&gt;&lt;span&gt;&lt;span&gt;function sum() {&lt;br /&gt; return $A(arguments).inject(0,function(a,b) {&lt;br /&gt;   return a + b;&lt;br /&gt; });&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span&gt;&lt;span&gt;Using apply we can even write &lt;/span&gt;&lt;/span&gt;&lt;code&gt;call&lt;/code&gt;&lt;span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;span&gt;&lt;span&gt;function myCall(func,scope) {&lt;br /&gt;var args = $A(arguments).slice(2);  // creates a copy of arguments from index 2 on&lt;br /&gt; return func.apply(scope,args);&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt; &lt;span&gt;&lt;span&gt;That covers &lt;/span&gt;&lt;/span&gt;&lt;code&gt;call&lt;/code&gt;&lt;span&gt;&lt;span&gt; and &lt;/span&gt;&lt;/span&gt;&lt;code&gt;apply&lt;/code&gt;&lt;span&gt;&lt;span&gt;. Next time we'll see how we can use what we now know about functional programming and JavaScript mechanics to implement the design patterns we know and love from Java.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-8604114875347643988?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/8604114875347643988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=8604114875347643988' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/8604114875347643988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/8604114875347643988'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/02/java-developers-guide-to-javascript_13.html' title='A Java Developer&apos;s Guide to JavaScript - Functional Programming and JavaScript Mechanics'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-7959904256751606955</id><published>2008-02-18T14:30:00.002-06:00</published><updated>2008-02-18T14:43:24.639-06:00</updated><title type='text'>Techdirt: The Formula</title><content type='html'>&lt;script type="text/javascript" src="http://toonlet.com/embed/strip?i=5492"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;If you read &lt;a href="http://techdirt.com/"&gt;Techdirt&lt;/a&gt; very often, you know that they are the first to catch it when a corporation (or government, to be redundant) is trying to hang on to a business model that is losing relevance.  While I often find Techdirt insightful, they too often use the formula "Why doesn't $company stop wasting resources doing $X and do $Y instead?" Where $X is something like filing a lawsuit, which often involves a lawyer on retainer or a few thousand in legal fees (i.e., a drop in the bucket of a corporate budget), while $Y is something like investing millions and billions in building new cable/telephone infrastructure.  The implication is that $X is somehow keeping them from doing $Y, and that the two are comparable strategies, which is rarely the case. It would be like me saying: "Instead of whining about the flaws in corporate business strategies, Techdirt should fund startups to compete using their superior ideas."  &lt;br /&gt;&lt;br /&gt;That said, I like Techdirt most of the time and can generally count on them to be one of the first to break significant tech news, they could just use some fresh material.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-7959904256751606955?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/7959904256751606955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=7959904256751606955' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7959904256751606955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7959904256751606955'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/02/techdirt-formula.html' title='Techdirt: The Formula'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-1187545484821943502</id><published>2008-02-09T21:11:00.000-06:00</published><updated>2008-02-09T21:36:07.091-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='greasemonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='netflix'/><title type='text'>jQuery Greasemonkey Template &amp; Netflix Queue Shuffler</title><content type='html'>&lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; is quickly becoming my weapon of choice to do DOM manipulation/enhancement. I'm still a huge &lt;a href="http://www.prototypejs.org/"&gt;Prototype&lt;/a&gt; fan for general code, but jQuery really does the DOM well.&lt;br /&gt;&lt;br /&gt;So, when I set out to write a &lt;a href="http://www.greasespot.net/"&gt;Greasemonkey&lt;/a&gt; script to randomize the order of the movies in my &lt;a href="http://www.netflix.com"&gt;Netflix&lt;/a&gt; queue, I needed to find a way to include jQuery.  The end result is fairly brief:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// ==UserScript==&lt;br /&gt;// @name           &lt;br /&gt;// @namespace      &lt;br /&gt;// @description    &lt;br /&gt;// @include        &lt;br /&gt;// ==/UserScript==&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * @param {Function} func the function you want to execute &lt;br /&gt; * with jQuery. The only argument passed will be jQuery, so&lt;br /&gt; * your function should look something like this:&amp;lt;pre&gt;&lt;br /&gt; * withJQuery( function($) {&lt;br /&gt; *   $(".foo .bar")...&lt;br /&gt; * } );&lt;br /&gt; * &amp;lt;/pre&gt;&lt;br /&gt; */&lt;br /&gt;function withJQuery(func) {&lt;br /&gt;  if(!unsafeWindow.jQuery) {&lt;br /&gt;    var s = document.createElement('script');&lt;br /&gt;    s.src = 'http://code.jquery.com/jquery-1.1.2.js';&lt;br /&gt;&lt;br /&gt;    s.addEventListener('load',function() {&lt;br /&gt;      // lots of people like to have their own $ function&lt;br /&gt;      unsafeWindow.jQuery.noConflict(); &lt;br /&gt;      func(unsafeWindow.jQuery);&lt;br /&gt;    },false);&lt;br /&gt;&lt;br /&gt;    document.getElementsByTagName('head')[0].appendChild(s);&lt;br /&gt;  } else {&lt;br /&gt;    func(unsafeWindow.jQuery);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// your code goes here, use withJQuery when you need it&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The trick was figuring out that in a Greasemonkey script, you can't do &lt;code&gt;element.oneventname = handler&lt;/code&gt; (you have to use &lt;code&gt;addEventListener&lt;/code&gt;) and that once jQuery loaded, it would be in &lt;code&gt;unsafeWindow&lt;/code&gt;, not &lt;code&gt;window&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;If you came here for the &lt;a href="http://userscripts.org/scripts/show/22570"&gt;queue shuffle script&lt;/a&gt;, sorry to have bored you. I'll do another 'JavaScript for Java Devs' chapter soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-1187545484821943502?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/1187545484821943502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=1187545484821943502' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1187545484821943502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1187545484821943502'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/02/jquery-greasemonkey-template-netflix.html' title='jQuery Greasemonkey Template &amp; Netflix Queue Shuffler'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-3245735641014592360</id><published>2008-01-14T15:45:00.001-06:00</published><updated>2008-09-18T13:18:26.082-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dynamicweb'/><category scheme='http://www.blogger.com/atom/ns#' term='dwr'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Grails, DWR, and the dynamic web</title><content type='html'>This post used to be titled "Using DWR with Grails", because the Grails DWR plugin lacked support for custom converters and creators. I wrote &lt;a href="http://www.nabble.com/DWR-Plugin---Patch-to-enable-custom-creators-and-converters-p14544340.html"&gt;this patch&lt;/a&gt; (EDIT: Nabble screws up the patch formatting so that it doesn't take. You can download the patch &lt;a href="http://markmail.org/download.xqy?id=eebu3yeroa7nqv4k&amp;number=1"&gt;here&lt;/a&gt;) adding this functionality and I was going to blog about how to apply and use it. However, before I posted this, I did a bit of searching, and apparently my patch got &lt;a href="http://fisheye.codehaus.org/browse/grails-plugins/grails-dwr/trunk/src/groovy/grails/dwr/DwrConfigBuilder.groovy?r=3602"&gt;applied the same day I submitted it&lt;/a&gt;. It would have been nice if someone had told me they took my patch, but presumably this means that the next release will have the functionality. If you can't wait, I presume you can build from the trunk, or use my forum post. Enough of that.&lt;br /&gt;&lt;br /&gt;I'm not big on making predictions, but this one seems pretty obvious to me. The reason there are so many Java web frameworks is that they all &lt;a href="http://www.groovygrails.com/gg/blog/view/115514"&gt;suck at being web frameworks&lt;/a&gt;. There is no clear winner in the Java space.  We started with Servlets, which were terrible for web development because you couldn't tell what the heck the final HTML would look like.  Then we had JSP, which is better, but once you start trying to apply DRY, get into a templating system and tag libraries, you're suddenly just as removed from the final result as you were with Servlets. In both cases, if I want to know what is being produced, I have to fire up my JEE container and do a request. Not to mention that creating templates and tags requires some lovely combination of XML and Java code. I don't know about you, but that feels off to me.&lt;br /&gt;&lt;br /&gt;Why? XML doesn't give me much flexibility. DRY gets violated all the time because there is no mechanism in the design of XML for reasonable reuse. Java on the other hand lets me refactor and reuse to my heart's content, but as we've already established, it's crap for actually producing HTML.&lt;br /&gt;&lt;br /&gt;And what about Ajax? JSP is fine if your site uses tables for layout and all links result in a full page refresh or occasional popup window, but if you want to build a responsive, dynamic site (using say, &lt;a href="http://extjs.com/"&gt;Ext&lt;/a&gt;) you'll end up having rendering logic in two places, WhateverCrapFramework and JavaScript. The best possible outcome is that you hardly use JSP (or whatever your 'controller' is) and rely on your Ajax toolkits.&lt;br /&gt;&lt;br /&gt;Again why? Because &lt;strong&gt;static typing everything is not appropriate for user interfaces&lt;/strong&gt;. A user only has one input type available to them: text. They can't enter &lt;code&gt;FooBarDto&lt;/code&gt;s directly, they don't even know what one is. You have to take some text and convert and validate it. Granted, they can also click things, but HTTP seals the deal for the web because all data submitted &lt;em&gt;must&lt;/em&gt; be in text form.  Your types cannot help you until you have already converted and validated the data, at which point it's ready to pass on to your service layer. So why the heck do you need types everywhere in your controller? You don't, but Java forces them on you anyways.&lt;br /&gt;&lt;br /&gt;I think Java is great for web applications by the way. Spring+Hibernate remains my first choice for implementing a solid service and data access layer (I like Guice too).  Static typing is great for helping ensure that your services are solid, and your data remains valid.&lt;br /&gt;&lt;br /&gt;Back to Ajax. I made a big investment in JSF in graduate school. I nearly killed myself and my wife building a framework for creating Ajax enabled components for JSF. It took me a few months after finishing to realize that JSF still doesn't make Java web development any less like wearing plate mail while figure skating.&lt;br /&gt;&lt;br /&gt;When you get right down to it, the best language for developing a web UI is the language that was always meant for the web: JavaScript.  &lt;a href="http://getahead.org/dwr/"&gt;DWR&lt;/a&gt; completely bridges the gap between Java and JavaScript. It converts all that pesky string data into nice typed data for your Java service layer and then turns around and converts those types that the user doesn't know about into pleasant little strings for web browsers to gobble up. You can expose your Spring service beans directly, secure them with Acegi (you better be doing that anyway, if you're relying on your controller to secure access, you're using a sieve as an umbrella), and call them from JavaScript without even having to know how HTTP requests work, much less Ajax. &lt;br /&gt;&lt;br /&gt;In conclusion, we need real developers on the client side. Good designers/UX folk don't usually make the best technical developers, and the dynamic web (especially for enterprise) requires a solid, coherent client side codebase, and things like DWR make that easy. If you're a Java web application developer that's still afraid of JavaScript, you'd better learn to face your fears.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-3245735641014592360?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/3245735641014592360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=3245735641014592360' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/3245735641014592360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/3245735641014592360'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/01/grails-dwr-and-dynamic-web.html' title='Grails, DWR, and the dynamic web'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-8530263650831560770</id><published>2008-01-07T14:29:00.000-06:00</published><updated>2008-01-07T14:40:56.579-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='iesucks'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><title type='text'>The IE script load event</title><content type='html'>&lt;em&gt;This is just a short rant. I promise I'll post more about Grails latter.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;I really hate IE.  Take this code to create a &lt;code&gt;script&lt;/code&gt; tag and fire a callback once it's loaded:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var script = document.createElement("script");&lt;br /&gt;script.setAttribute("type","text/javascript");&lt;br /&gt;script.setAttribute("src", fileName);&lt;br /&gt;Event.observe( script, "load", function() {...});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Works great in Firefox. But in IE6? Never fires. You have to do this instead:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Event.observe( script, "readystatechange", function() {&lt;br /&gt;  if(script.readyState == "complete") {&lt;br /&gt;    ...do stuff...&lt;br /&gt;  }&lt;br /&gt;} );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It's not that there is extra functionality. It's that a decision was made to provide a complicated interface that can handle like two extra edge cases, but the much simpler, obvious and consistent 'onload' handler gets left out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-8530263650831560770?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/8530263650831560770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=8530263650831560770' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/8530263650831560770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/8530263650831560770'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/01/ie-script-load-event.html' title='The IE script load event'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-917633032823618212</id><published>2008-01-04T08:01:00.002-06:00</published><updated>2009-12-07T15:44:58.452-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='dwr'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='acegi'/><title type='text'>Custom DWR Converters</title><content type='html'>&lt;a href="http://getahead.org/dwr"&gt;DWR&lt;/a&gt; is great. If you're full bore into Ajax development, it eliminates the need for a &lt;a href="http://iamnoah.blogspot.com/2007/11/im-nerd-or-do-i-mean-geek-hi-my-name-is.html"&gt;awkward controller like JSF&lt;/a&gt; or Spring MVC.  You can write static DHTML that talks directly to your service layer, which keeps the UI code clear and simple.  Secure your services with something like Acegi, and you're almost there.&lt;br /&gt;&lt;br /&gt;I say almost, because the way DWR marshals your beans is either all or nothing.  You can tell DWR, convert only these classes, and only these properties and that's it.  What if you have different user roles that have different read permissions? e.g., detailed user info should be accessible to the admin and no one else. What if you want summary information when an object is nested inside another one? e.g., my Label BO has a name, description and a couple of flags associated with it. When I retrieve a labeled thing, say a message, I really only care about the label name so I can render a list of labels on the message. But when I retrieve a Label for editing, I need all the information about the label. Let's see if we can fix this.&lt;br /&gt;&lt;br /&gt;Because DWR is open source, I can browse around and find the source for &lt;code&gt;BeanConverter&lt;/code&gt;. It has a lot of hooks (including &lt;code&gt;isAllowedByIncludeExcludeRules&lt;/code&gt;, which would be helpful for role based filtering), but what we really need here is a hook to control what converter is used.  Because we have the source code, why don't we add one? I'll just create a subclass of &lt;code&gt;BeanConverter&lt;/code&gt; and override &lt;code&gt;convertOutbound&lt;/code&gt; like so:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public OutboundVariable convertOutbound(Object data, OutboundContext outctx)&lt;br /&gt;      throws MarshallException {&lt;br /&gt;  Map ovs = new TreeMap();&lt;br /&gt;&lt;br /&gt;  ObjectOutboundVariable ov = new ObjectOutboundVariable(outctx);&lt;br /&gt;  outctx.put(data, ov);&lt;br /&gt;&lt;br /&gt;  try {&lt;br /&gt;      for (Entry&lt;string,&gt; entry : (Set&lt;entry&gt;&lt;string,&gt;&gt;) getPropertyMapFromObject(&lt;br /&gt;              data, true, false).entrySet()) {&lt;br /&gt;          ovs.put((String) entry.getKey(), getPropertyValue(&lt;br /&gt;                  (Property) entry.getValue(), data, outctx));&lt;br /&gt;      }&lt;br /&gt;  } catch (MarshallException ex) {&lt;br /&gt;      throw ex;&lt;br /&gt;  } catch (Exception ex) {&lt;br /&gt;      throw new MarshallException(data.getClass(), ex);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  ov.init(ovs, getJavascript());&lt;br /&gt;&lt;br /&gt;  return ov;&lt;br /&gt;}&lt;br /&gt;&lt;/string,&gt;&lt;/entry&gt;&lt;/string,&gt;&lt;/pre&gt;&lt;br /&gt;The code is pretty much the same as in the superclass, but with 1 key difference. My version calls &lt;code&gt;getPropertyValue&lt;/code&gt;. In the template class, I keep the default behavior, loading the converter from the converter manager, but we'll create a subclass in a moment that takes a different approach.&lt;br /&gt;&lt;br /&gt;First, let's look at what &lt;a href="http://getahead.org/dwr/server/dwrxml"&gt;dwr.xml&lt;/a&gt; offers us in terms of configuration.  It looks like you can set properties on converter instances using param elements.  I prefer to use a concise format for configuration whenever possible, so our format will be something like "propertyName:includeExcludeProperty1,includeExcludeProperty2 otherProp:more,of,the,same".  Supposing this was an include, then when we create the converter for the otherProp property, it will include the more,of,the and same properties and no others. Got it?&lt;br /&gt;&lt;br /&gt;We need to provide parsing for our custom format in the converter:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class SubBeanConverter extends TemplateBeanConverter {&lt;br /&gt;&lt;br /&gt;protected Map&lt;string, beanconverter=""&gt; subInclude = new HashMap&lt;string, beanconverter=""&gt;();&lt;br /&gt;protected Map&lt;string, beanconverter=""&gt; subExclude = new HashMap&lt;string, beanconverter=""&gt;();&lt;br /&gt;&lt;br /&gt;public void setSubIncludes(String defs) {&lt;br /&gt;this.subInclude = parseIncludeExclude(defs, true);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setSubExcludes(String defs) {&lt;br /&gt;this.subExclude = parseIncludeExclude(defs, false);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private Map&lt;string, beanconverter=""&gt; parseIncludeExclude(String defs,&lt;br /&gt;boolean include) {&lt;br /&gt;Map&lt;string, beanconverter=""&gt; map = new HashMap&lt;string, beanconverter=""&gt;();&lt;br /&gt;for (String def : defs.split("\\s")) {&lt;br /&gt;String[] split = def.split(":", 2);&lt;br /&gt;BeanConverter bc = new BeanConverter();&lt;br /&gt;bc.setConverterManager(getConverterManager());&lt;br /&gt;if (include) {&lt;br /&gt;bc.setInclude(split[1]);&lt;br /&gt;} else {&lt;br /&gt;bc.setExclude(split[1]);&lt;br /&gt;}&lt;br /&gt;map.put(split[0].trim(), bc);&lt;br /&gt;}&lt;br /&gt;return map;&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;&lt;/string,&gt;&lt;/string,&gt;&lt;/string,&gt;&lt;/string,&gt;&lt;/string,&gt;&lt;/string,&gt;&lt;/string,&gt;&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;TemplateBeanConverter&lt;/code&gt; is our original subclass of &lt;code&gt;BeanConverter&lt;/code&gt;.  Since we're using the same format for includes and excludes, the same method is used to parse them both.  For each property we list, we create a &lt;code&gt;BeanConverter&lt;/code&gt; instance that we will use in place of the usual converter.&lt;br /&gt;&lt;br /&gt;The last step is to override &lt;code&gt;getPropertyValue&lt;/code&gt; and use our special &lt;code&gt;BeanConverter&lt;/code&gt; instances:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;protected OutboundVariable getPropertyValue(Property property, Object data,&lt;br /&gt;OutboundContext outctx) throws MarshallException {&lt;br /&gt;Object value = property.getValue(data);&lt;br /&gt;if (value != null) {&lt;br /&gt;BeanConverter exConverter = subExclude.get(property.getName());&lt;br /&gt;if (exConverter != null) {&lt;br /&gt;return exConverter.convertOutbound(value, outctx);&lt;br /&gt;}&lt;br /&gt;BeanConverter inConverter = subInclude.get(property.getName());&lt;br /&gt;if (inConverter != null) {&lt;br /&gt;return inConverter.convertOutbound(value, outctx);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;return super.getPropertyValue(property, data, outctx);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Easy right?&lt;br /&gt;&lt;br /&gt;Next time I'll talk about my experience using &lt;a href="http://grails.codehaus.org/"&gt;Grails&lt;/a&gt; with DWR.&lt;br /&gt;&lt;br /&gt;UPDATE: I mentioned role based filtering above, but I will leave that as an exercise to the reader. One hint: if you're using Acegi to control access to pages,&lt;br /&gt;&lt;pre&gt;org.acegisecurity.context.SecurityContextHolder.getContext()&lt;br /&gt; .getAuthentication().getAuthorities()&lt;/pre&gt; will get you the list of &lt;a href="http://www.acegisecurity.org/acegi-security/apidocs/org/acegisecurity/GrantedAuthority.html"&gt;granted authorities&lt;/a&gt; (AKA roles, e.g. ROLE_ANONYMOUS) for the current user.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-917633032823618212?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/917633032823618212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=917633032823618212' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/917633032823618212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/917633032823618212'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2008/01/custom-dwr-converters.html' title='Custom DWR Converters'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-2748113172508231108</id><published>2007-12-13T13:23:00.000-06:00</published><updated>2008-01-02T15:17:27.421-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='reflection'/><category scheme='http://www.blogger.com/atom/ns#' term='prototypal'/><category scheme='http://www.blogger.com/atom/ns#' term='ioc'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><title type='text'>More than you wanted to know about JavaScript object creation</title><content type='html'>I began this journey because I needed to create a new instance of a JavaScript class with a variable number of arguments.  Not knowing the number of arguments, I couldn't just write &lt;code&gt;new MyClass(arg[0],arg[1].. etc.)&lt;/code&gt;, so I had to figure out how to replicate the behaviour of &lt;code&gt;new&lt;/code&gt; in some other way.&lt;br /&gt;&lt;br /&gt;You may have heard that JavaScript inheritance is &lt;a href="http://javascript.crockford.com/prototypal.html"&gt;prototypal&lt;/a&gt;. If you don't know what that means, thin of it as one object inheriting from another by making a copy of the original object.  Everything in JavaScript is an object, including functions.  You may think that JavaScript has classes. It doesn't. It really just has functions.&lt;br /&gt;&lt;br /&gt;JavaScript is prototypal, but it wanted to appeal to programmers that were used to "classical" inheritance, so it included the 'new' keyword that we all love so much. That means you can do things like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function MyClass(arg1,arg2) {&lt;br /&gt;this.foo = arg1;&lt;br /&gt;this.bar = arg2;&lt;br /&gt;this.baz = 3;&lt;br /&gt;}&lt;br /&gt;var mine = new MyClass('foo','bar');&lt;br /&gt;// mine.foo == 'foo'&lt;br /&gt;&lt;/pre&gt;So what's going on? MyClass is called, but there is this 'this' object that isn't declared anywhere. Where did it come from? &lt;code&gt;new&lt;/code&gt; created it for us and put it into the scope of the MyClass function.  If a function called with 'new' doesn't have a return statement, it returns 'this' by default.  You could try to call MyClass by itself, but you would end up creating 3 global variables because &lt;code&gt;this&lt;/code&gt; defaults to &lt;code&gt;window&lt;/code&gt;.  So how do we redefine &lt;code&gt;this&lt;/code&gt;? There are two methods on all functions (remember, functions are objects, just like everything else) that let you control the value of &lt;code&gt;this&lt;/code&gt;: call and apply.&lt;br /&gt;&lt;pre&gt;var foo = { qux: '123' };&lt;br /&gt;MyClass.call(foo,'foo','bar');&lt;br /&gt;// foo.foo == 'foo' &amp;amp;&amp;amp; foo.qux == '123'&lt;br /&gt;// if you don't know the exact number of arguments you can use apply&lt;br /&gt;var args = ['foo','bar'];&lt;br /&gt;// apply takes an array for the arguments&lt;br /&gt;MyClass.apply(foo,args);&lt;br /&gt;&lt;/pre&gt;You might now be thinking that &lt;code&gt;MyClass.call({},'foo','bar')&lt;/code&gt; is the same as &lt;code&gt;new MyClass('foo','bar')&lt;/code&gt;. Well, &lt;code&gt;new&lt;/code&gt; does a bit more than that. Remember  the &lt;a href="http://javascript.crockford.com/prototypal.html"&gt;prototype&lt;/a&gt;?  Calling &lt;code&gt;new&lt;/code&gt; more or less creates a copy of the class's prototype, which is then used as &lt;code&gt;this&lt;/code&gt; when calling the function. e.g.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;MyClass.prototype.myFunc = function(a,b) { return a+b; };&lt;br /&gt;var mine = new MyClass(...);&lt;br /&gt;// mine.myFunc == function(a,b) { return a+b; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;One brief digression from our quest: John Resig blogged about a way to create classes that are &lt;a href="http://ejohn.org/blog/simple-class-instantiation/"&gt;instantiated correctly even if you forget &lt;code&gt;new&lt;/code&gt;.&lt;/a&gt; An interesting read, but not quite what we need since we may need to instantiate classes not under our control.&lt;br /&gt;&lt;br /&gt;So if you create a new object, copy all the properties of &lt;code&gt;MyClass.prototype&lt;/code&gt;, and then call &lt;code&gt;MyClass.apply(...)&lt;/code&gt;, is that the same as &lt;code&gt;new MyClass(...)&lt;/code&gt;? Nope. &lt;code&gt;new&lt;/code&gt; does some things behind the scenes that you cannot replicate without calling new. e.g., &lt;pre&gt;&lt;br /&gt;var mine = {};&lt;br /&gt;for(var i in MyClass.prototype) {&lt;br /&gt;mine[i] = MyClass.prototype[i];&lt;br /&gt;}&lt;br /&gt;MyClass.apply(mine,'foo','bar');&lt;br /&gt;// mine instanceof MyClass == false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So, what we have is an instance that is almost, but not quite identical to an instance created with &lt;code&gt;new&lt;/code&gt;.  If you know that the object will only be &lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;duck typed&lt;/a&gt;, then this is good enough. However, if it's possible that it might end up in an &lt;code&gt;instanceof&lt;/code&gt; or have some other low level type check, this isn't good enough.  The final trick that you need is &lt;code&gt;new&lt;/code&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function newInstance(type,args) {&lt;br /&gt;var f = function() {};&lt;br /&gt;f.prototype = type.prototype;&lt;br /&gt;var o = new f;&lt;br /&gt;return type.apply(o,args) || o;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;By creating a no-arguments function with the same prototype, we can safely use &lt;code&gt;new&lt;/code&gt; to get the prototype copying, and then call the constructor using apply. &lt;code&gt;instanceof type&lt;/code&gt; (and other checks, like &lt;code&gt;prototype.constructor&lt;/code&gt;) will return true, and the new instance will walk and talk like a duck of MyClass.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-2748113172508231108?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/2748113172508231108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=2748113172508231108' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/2748113172508231108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/2748113172508231108'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2007/12/more-than-you-wanted-to-know-about.html' title='More than you wanted to know about JavaScript object creation'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-5845595560451260000</id><published>2007-11-22T00:08:00.000-06:00</published><updated>2007-11-22T11:24:16.594-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='sun'/><category scheme='http://www.blogger.com/atom/ns#' term='extjs'/><category scheme='http://www.blogger.com/atom/ns#' term='slicehost'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>I'm a nerd. Or do I mean geek?... Hi, my name is Noah.</title><content type='html'>Aaaand it's Thanksgiving. I'm up late because I just got my &lt;a href="http://www.slicehost.com/faq"&gt;slice&lt;/a&gt; and I can't stop tinkering.&lt;br /&gt;&lt;br /&gt;I think my &lt;a href="http://jsftoolkit.com/"&gt;master's project&lt;/a&gt; is dead meat. Yes, JSF component creation is woefully painful and slow. Yes, a framework helps tremendously. Yes, my framework was good, and let you choose your Ajax implementation, and so on.&lt;br /&gt;&lt;br /&gt;The problem with all that is that the JSF Ajax implementations suck. And the learning curve for JSF (much less components) sucks.  It's just too quirky. Hopefully JSF 2.0 will make component creation easy, enable RESTful services, and will make it easier for newbies and old hands to just get things done.  I'd like to hope all of that, but the only positive things I tend to hear about 2.0 are from &lt;a href="http://weblogs.java.net/blog/edburns/"&gt;Ed Burns&lt;/a&gt;, who seems like a very nice guy, but whose rhetoric reeks of corporate "gotta toe the line/I think my company is the best ever, is not a dinosaur who is slowly and &lt;a href="http://www.apache.org/jcp/sunopenletter.html"&gt;inconsistently&lt;/a&gt; embracing open source, and is a bit too &lt;a href="http://jcp.org/en/home/index"&gt;bureaucratic&lt;/a&gt;  to be able to save Java." JavaScript is &lt;a href="http://steve-yegge.blogspot.com/2007/02/next-big-language.html"&gt;it&lt;/a&gt;, ya know.&lt;br /&gt;&lt;br /&gt;Which brings us to my next topic. Kevin at &lt;a href="http://www.optaros.com/"&gt;work&lt;/a&gt; is the new &lt;a href="http://grails.org/"&gt;Grails&lt;/a&gt; evangelist.  I have to admit, Groovy is a cool language. If not for the fact that JavaScript is the NBL, I think Groovy would be the weapon of choice. Optional static types, intuitive C like syntax, closures everywhere, functional programming, etc. It's a readable LISP, IMHO.  Since we'll probably be using &lt;a href="http://extjs.com/"&gt;Ext&lt;/a&gt; for my next &lt;a href="http://www.mckesson.com/"&gt;project&lt;/a&gt;, (in wonderful freezing cold Pittsburgh, no less...) I thought that I'd take the opportunity to get familiar with it by working up a sample project. It's going quite well, so I must remember to get a few entries out of it (yes the separate &lt;a href="http://jroller.co/page/noah"&gt;tech blog&lt;/a&gt; is pretty much dead).&lt;br /&gt;&lt;br /&gt;Groovy is a great complement to JavaScript/Ajax programming primarily because the thought processes are the same. There are some more syntactic niceties in Groovy, and there is sadly no &lt;a href="http://prototypejs.net/"&gt;Prototype&lt;/a&gt; for Groovy, but switching is completely effortless.  And if I need to, I can always turn the static types back on and write some Java code.  If you are a JEE developer and haven't looked at Grails yet, you need to.&lt;br /&gt;&lt;br /&gt;More bulletins as events warrant. Cheers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-5845595560451260000?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/5845595560451260000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=5845595560451260000' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/5845595560451260000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/5845595560451260000'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2007/11/im-nerd-or-do-i-mean-geek-hi-my-name-is.html' title='I&apos;m a nerd. Or do I mean geek?... Hi, my name is Noah.'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-6704598821862083741</id><published>2007-10-31T18:46:00.000-05:00</published><updated>2007-10-31T19:59:04.972-05:00</updated><title type='text'>In the swing of things</title><content type='html'>I'm finally starting to feel settled in Austin.  It helps to actually live here.  Working downtown is pretty cool, and I like the bus.  Despite the smells, it's usually a nice ride.  I get a lot of reading done; too much in fact. I need a side project, so I'm trying to revive my master's project.  We'll see how that goes.&lt;br /&gt;&lt;br /&gt;November 10th (Saturday), we are having a BBQ from 3ish to whenever I turn into an angry drunk and kick everyone out.  If you're reading this, you're invited. If you're not reading this, something is wrong, please stop before you destroy the universe.  Thanks.&lt;br /&gt;&lt;br /&gt;I need to read something intellectually stimulating, but I'd prefer fiction. Any ideas? Oh, and happy Halloween.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-6704598821862083741?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/6704598821862083741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=6704598821862083741' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/6704598821862083741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/6704598821862083741'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2007/10/in-swing-of-things.html' title='In the swing of things'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-2678494267207985089</id><published>2007-09-07T11:37:00.000-05:00</published><updated>2007-09-07T12:18:08.512-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='show'/><category scheme='http://www.blogger.com/atom/ns#' term='bike'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><category scheme='http://www.blogger.com/atom/ns#' term='austin'/><title type='text'>Living in Austin</title><content type='html'>There is so much to do here.  In the last month I've learned more about bikes, &lt;a href="http://www.austinyellowbike.org/"&gt;built my own road bike&lt;/a&gt;, taken the dogs to two of the &lt;a href="http://www.ci.austin.tx.us/parks/dogparks.htm"&gt;off leash dog parks&lt;/a&gt;, taken the bus downtown a few times (~30min in which I can read, write or just enjoy the scenery; in a car any of those will get you killed), and fixed 98% of the problems with the house, of which there were several dozen.  Oh, and I've been very, very lazy, played video games a lot, and spent probably a week's worth of time on &lt;a href="http://reddit.com/"&gt;reddit&lt;/a&gt;.  You may not believe it, but not having a job gets old after a while.&lt;br /&gt;&lt;br /&gt;Last night we saw &lt;a href="http://www.myspace.com/quietlovely"&gt;Quiet, Lovely&lt;/a&gt; for the first time in a few years, although we had to duck out early as H's stomach bug decided to grace us with one final encore.  As an aside, &lt;a href="http://www.mohawkaustin.com/"&gt;The Mohawk&lt;/a&gt; seems like a nice place to get a drink, but until they finish their outside stage, it's a bit small for a decent show. Also, why the heck would you &lt;span style="font-weight: bold;"&gt;start&lt;/span&gt; a show at 10 PM on a &lt;span style="font-style: italic;"&gt;Thursday night&lt;/span&gt;?!?!?!  People who like music sometimes have jobs, do you really think you'll sell more beer by forcing them to leave before the show is over? Tonight, &lt;a href="http://www.meryll.net/"&gt;Meryll&lt;/a&gt; plays at Stubbs. Going by last night, we should show up at about 3 AM.&lt;br /&gt;&lt;br /&gt;I fly to Boston on Sunday to start &lt;a href="http://www.optaros.com/"&gt;work&lt;/a&gt;.  According to my parents, I've been to Boston, but didn't get to see much as I was only -2 months old. Think about it.  I hope I like traveling as much as I think I do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-2678494267207985089?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/2678494267207985089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=2678494267207985089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/2678494267207985089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/2678494267207985089'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2007/09/living-in-austin.html' title='Living in Austin'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-7779869173389283243</id><published>2007-08-06T20:00:00.000-05:00</published><updated>2007-08-06T20:10:12.704-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grad school'/><title type='text'>it's not so bad...</title><content type='html'>One of my committee members dropped out. Since my defense was supposed to be tomorrow, that means postponing it a few weeks while we find another person and give them time to get up to speed.  Disappointing, but not that big a deal. We still move on Friday, I'll just have to make one last trip up to Hueco later this month.&lt;br /&gt;&lt;br /&gt;Yes, my life will be marginally more stressful between now and then, but there's nothing to do about it, and it's not too bad.&lt;br /&gt;&lt;br /&gt;Update: It's really not so bad at all. Another professor, hearing my plight, took pity on my poor soul and has undertaken the herculean effort of digesting my 68 page project document in less than two days.  It looks like he'll actually make it too!  My defense is postponed only until Wednesday.  That doesn't mean it's a sure thing, but it gives me a good shot.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-7779869173389283243?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/7779869173389283243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=7779869173389283243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7779869173389283243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/7779869173389283243'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2007/08/its-not-so-bad.html' title='it&apos;s not so bad...'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6713689.post-1052593299274798603</id><published>2007-08-05T20:37:00.000-05:00</published><updated>2007-08-06T11:25:30.611-05:00</updated><title type='text'>blog, blag, blech</title><content type='html'>Grad school doesn't leave a lot of room for a social life. Certainly nothing to write about, unless you care about my &lt;a href="http://jroller.com/page/noah"&gt;frustrations with technology&lt;/a&gt;. That should change soon.  That ends Tuesday, then we move to Austin, have a whole month off, and then start a job that sends me all over the country.  My first day is in Boston. That's pretty cool.&lt;br /&gt;&lt;br /&gt;Hopefully this will be a journal of cool stuff I do while traveling and when I'm home in Austin.  I'm sure I'll also resume a bit of the philosophical bent this blog had long ago, but probably with less of the bad poetry/stream of consciousness/"look how emo I am" content. Stupid emo kids.&lt;br /&gt;&lt;br /&gt;I'll be 25 this year. There's no avoiding it, I'm a grownup now.  But, that doesn't mean we have to &lt;a href="http://xkcd.com/150/"&gt;act like our parents&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6713689-1052593299274798603?l=iamnoah.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iamnoah.blogspot.com/feeds/1052593299274798603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6713689&amp;postID=1052593299274798603' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1052593299274798603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6713689/posts/default/1052593299274798603'/><link rel='alternate' type='text/html' href='http://iamnoah.blogspot.com/2007/08/blog-blag-blech.html' title='blog, blag, blech'/><author><name>noah</name><uri>http://www.blogger.com/profile/09697060488717104453</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ZS-2AgZmgD0/S1OC94pgpSI/AAAAAAAABDI/FytWFvKeXR4/s1600-R/755ad21d2059ac3970754edd621ba65b'/></author><thr:total>0</thr:total></entry></feed>
