Sunday, May 20, 2007

RailsConf 2007 - Day 1

I was primed and ready for RailsConf 2007 Day 1. The excitement was in the air, and the crowd was primed. We awaited a day absolutely packed with mind candy. Starting with Chad Fowler, David Heinemeier Hansson, Robert Martin, Adam Keys, Avi Bryant, and Ze Frank. Wow, what a lineup!

As Chad Fowler took the stage, his ukulele in hand, we eagerly awaited his opening remarks. Chad really did a great thing, by not just giving us the "feel-good rah-rah Rails is taking over the world" intro speech that most people probably expected. Instead, he took a higher path. The virtues of sharing are not limited to open source projects, but need to get into the real world. For example, using Rails to create applications that solve real problems that have not been tackled yet, due to the high cost of developing a solution. We as a community can also do a lot for the world outside of just developing software, no matter how cool it is. The Pragmatic Programmer fund-raising drive is a fantastic example of mobilizing the community, and Chad exhorted the crowd to keep those donations coming.

Is the Rails community more concerned with altruism and spirituality than other tech people? Or are we following the once again popular meme of greater social awareness and activism? That may be fodder for another posting some other time...back to the show.

His opening remarks finished, Chad played a little uke ditty, under a delightful beat poetry introduction given by Rich Kilmer for David Heinemeier Hansson. As David took the stage, we all wondered, "what would he spring on us this year? We just spent the last year RESTifying our applications, what MORE do you want from us?!"

And here is what he said:


Keynote - David Heinemeier Hansson

REST is where it is at, and Rails 2.0 doesn't alter that path. But there are 9 other things he really likes about Rails 2.0.

* Debugging with breakpoints
David showed the ability to put a breakpoint into your Rails controller that opened irb with all of the context and objects ready to be introspected. Although dropping to command line is not exactly what most of us want out of a debugging session, this could easily have a superior UI put on it.

* HTTP Performance
HTTP performance in an area where a couple of small changes can dramatically increase performance. His examples showed very easy combining of all CSS files, and separately all JS files together into a single file, and then compressing of each group of files into a gzip archive for quick download.

Another HTTP performance technique that 2.0 introduces is a way to get around the two connection limit that browsers enforce, by serving static assets from multiple host servers using the new :asset_hosts configuration option.

* Query Cache
Rails 2.0 can look at all of the SQL that ActiveRecord is executing, and if there have not been any inserts or updates, automatically caches that database query.

* Rendering
Rendering of a resource request has now been separated from the MIME type of the request. Now, it is much easier to handle multiple format requests like RSS or ATOM that both return XML.

* Configuration Initializers
Separates the config.rb into separate files, which reduces the effort and extracts the application unique config info into easier to read chunks.

* Sexy migrations
This plug-in, which simplifies the syntax for database migrations, started out as a Rails plug-in, but is so useful that it is now part of Rails core.

* HTTP Authentication
DHH didn't feel the pain of not having easy HTTP authentication till he started using his own ActiveResource. Then he realized that although human users with their web browsers might prefer a forms-based authentication, machine users that wabt to call the REST interface for an application would prefer HTTP authentication.

* MIT License
Generating a new Rails assumes that you want to use the MIT license. The MIT license being simple and appealing.

* Spring Cleaning
Removing things form Rails core, like ActiveWebService, that are not as commonly used by many Rails applications, and turning them into plug-is that can be added separately by applications that require them. In the case of ActiveWebService, DHH also wants to guide users away from SOAP and toward REST, and removing ActiveWebService from Rails core does so in a "subtle" way.

DHH is funny, smart, and yes, opinionated. The Rails community wouldn't have it any other way.

Bob Martin - Writing Clean Code

Next, I had the extreme pleasure of seeing the great Bob Martin. Getting to be up close and personal to a legend of software, who normally is a keynote speaker at massive conferences like SDWEST, was a special treat. And Bob certainly lived up to expectations. He had incredible energy, was funny, and very insightful. Here are some excerpts from his remarks.

*Ward Cunningham noticed that "it was too easy to make a mess in Smalltalk".
*Have you ever been significantly impeded by bad code?
*Why did you write it? - "don't have time to write it correctly"
*Due to the quality of the code, we end up with diminishing returns from productivity over time as the code bloats
*Only solution to the problem is to clean up your code

*So what do we do about bad code?

  • grand redesign in the sky, or

  • incremental improvement



* Grand redesign in the sky

  • all requirements are buried in the old system

  • most companies will create a tiger team

  • tiger team is hated by old team

  • both systems are still under development however, so

  • it takes years for the old system to be replaced by the new system

  • as a result, the new system needs to be redone by the time it replaces the old system



*Incremental improvement

  • always check in code better than when you checked it out

  • never let sun set on bad code

  • test first

  • provides necessary flexibility



*Elizabeth Hendrickson had given Uncle Bob a green wristband labeled "test-obsessed". He feels like he cannot take it off. Ever. Because if he does, he is not really committed to testing.

*How much code coverage should we have? We should attempt to reach 100%, asymptotically.

  • rspec is really good. Use it.
  • Open closed principle is violated by repeating code
  • Modules should open for extension, but closed for modification


*What do you do when it gets yucky?

  • Refactor quick when you smell the mess
  • Do not ignore these rules, or you will end up with a festering pile of code!
  • Remember, we cannot write the correct code the 1st time. Trying to is egomaniacal.


*Iterate, like your teacher showed you how to write your grade school papers. Start with a rough draft, then refine.

*One of the best ways to ruin a program is try to make massive changes all at once
*Keep it running at all times
*You are not allowed to make a change that breaks the system

*How do you refactor? You need tests!!!
*Stick to the principle of least surprise
*Make tiny incremental changes, always running tests each time, minute by minute
*Notice what happens when you shrink the granularity of your development
*Uncle Bob is not sure that designating class methods as private is worth it?
*Software design is about separation of concerns - volatile and non-volatile code should be separated

*What if you make a mess? Was it worth it?
*Bad code gets harder to clean - Clean as soon as it gets messy
*So what about time to market? Isn't that the most important thing? What is the fastest way to finish dinner? Once you are done eating, just leave everything on the table, get up, and walk away. However, the fastest way to finish dinner is also the slowest way to start dinner, as you will have to clean everything before you can start cooking, and the plates will be hard to clean.

*Bad code

  • Nothing has worse effect on a project than bad code
  • Schedule slips
  • Requirements missed
  • Team dynamics problems
  • Bad code rots and ferments
  • Becomes a weight that drags team down


*Professional behavior

  • Commitment like the "green band"
  • Pros write tests first
  • Pros clean their code
  • Pros know going fast means going well
  • Making the mess is NOT faster


*Like DHH said earlier today: "it's about making things a little bit nicer"


Standing On The Shoulders Of Giants

I was not really familiar with Adam Keys, but on the advice of a friend, I went to his session. Being a bit of a code archeologist myself, I looked forward to hearing Adam's thoughts about reading Ruby code. It was indeed worthwhile attending the session. Here are some notes of his remarks.

*Rails sucking all of the air in the web space has been a good thing...
*You need to listen or perform a composer's music to really know it...likewise we need to read the code to fully understand any piece of software.
*Reading code requires 5 times more effort than writing code
*We all write legacy code, if you look at a long enough timeframe
*Protect yourself from yourself, 5 days ago - going too fast with a pet technique

*Why reading code could be hard

  • Not a lot of tool support for reading ruby
  • Unfamiliar idioms
  • Code written by non-heros
  • You need a helmet with light on it - concentrate on only one part of code
  • Find the entry points and hooks
  • Don't chase rabbits into holes


Adam's guide to spelunking the code

  • Look at URL, look at routes
  • Controller
  • Controller filters
  • Controller actions
  • Method called by actions
  • templates and temp. helpers


Preface to spelunking

  • filters in application controllers or helpers in application helpers
  • model observers, validations
  • code in libs or plugins



Keynote Introduction
After a rather dry and not that well executed speech by Five Runs CEO Steve Smith, Joey deVilla aka AccordianGuy gave a brilliant rendition of Radiohead's "Creep" as "I'm A Noob" an absolutely hillarious ode to DHH.

Avi Bryant

Avi Bryant is the creator of DabbleDB which was built using Smalltalk and the Seaside framework. As a Smalltalk enthusiast, many people were confused as to why on earth he would be a keynote speaker at a Rails conference. Ah, how we limit ourselves by putting everything into a little conceptual box and leaving it there for the rest of our lives. Getting outside perspective is the only way we ever learn anything and grow.

Avi started out by telling us that "He comes from the future". What he really meant was that Smalltalk has already gone through a similar evolution as Ruby, but that he considers Smalltalk 10-20 years ahead as far as solving certain problems that the Ruby community is still working on.

Avi considers Ruby and Smalltalk really the same language, at the core level. He showed a couple simple examples of their similarities. Then, he explained why he was giving his talk: to help out Smalltalk.

He had a number of other points:

* Ruby's features make it inherently slow.
* Smalltalk was bought, sold, then bought again by Sun. The VM developed for Smalltalk ended up as the Java VM.
* No reason Ruby cannot have the same performance characteristics as Smalltalk
*Having proper REAL debugging is crucial
*Ruby needs better VM tech
*What if Ruby's ObjectSpace was:

  • transactional & persistent
  • transparently distributable
  • terabyte scale
  • no restrictions to storage location


*GemStone - Portland based VM company, that has a very high performance runtime for Smalltalk. Acording to Avi, GemStone supports over 1000 VM's sharing 100s of GB of object memory. GemStone is free up to 4GB of storage.

*Objects get better with age
*Object lifecycle
*create
*use
*save

During the Q & A at the end, Ola Bini asked Avi about using Rubinous. Rubinious is a runtime for Ruby that is actually written entirely in Ruby itself. I was impressed by the fact that Ola didn't ask what Avi thought about JRuby. Ola is really cool, and his question was right on target after Avi's criticism of Ruby being written in C, and not turtles all the way down. Avi's response included his opinion that the Smalltalk VM is so advanced it would take the Ruby community 10 years to develop, just like it took that long to write the Smalltalk VM.

Personally, I do not buy that argument. Just because it took them 10 years to develop their runtime engine doesn't mean that all such tasks will take the same length of time. But Avi's perspective is a bit more biased than Ola's, I think.

And then came Ze Frank...


Ze Frank

I like Ze's stuff, but I had no idea what we were in for. I knew he was witty and smart, but what I didn't know what that he was a total genius. Ze is to theory of online community what Why The Lucky Stiff is to Ruby. On the surface everything is very amusing, but if you dig in you can go deep. Very deep.

Ze started out with a hilarious bit on "Acceleration Anxiety". He had the crowd laughing so hard that tears were coming out, as he made fun of his own fear of flying, and the idiocy of so many everyday things like the safety instructions and vomit bags on airplanes.

And then, he told us about a second kind of "Acceleration Anxiety". Here are a few of his key points on socialogy and online community:

People are learning a new language (ours)

People are having a media conversation

What can you do with your audience if they do things you don't like
*ignore them
*control them
*shut them down

Facilitating conversation : cultivating the energy

At a really good dinner party, it about the focus of the experience. Most people asked would not remember what had been discussed, but they would have remembered enjoying themselves - all of the different kinds of guests need to engaged.

Ze then shared his history of how he started and become the net culture star that he is today. At first his communications were one-way. But then his audience started becoming participants. He showed us a few examples:

The show
Earth sandwich
Human baton

Complexity of narrative has become much more complex

Technology is a facilitator of basic human emotions

The Core Values
*Conversation
*Community
*Belonging

There are one to one online communication. And there is mss online communication. We we need to do is look to the middle.


All I can say is wow. During Ze's introduction, Chad Fowler said he didn't realize that Ze was like some kind of Malcolm Gladwell. Neither did I.

Saturday, May 19, 2007

RailsConf 2007 - Sessions (Day 0)

Well, I had just got back to my room after day 0 of RailsConf 2007, which was the tutorial sessions before the main conference began. After a fun evening of pizza and beer with the Pragmatic Programmers, I thought I would try to get down some thoughts about the day's events.

Yesterday, I attended "Scaling Rails From The Ground Up" followed by "Harnessing Capistrano". It is very hard to have tutorial sessions at a conference. They either are too basic to satisfy advanced users, or too complex for noobs. In the case of RailsConf 2007, they probably achieved both at the same time. Since the Pragmatics had the intro to Rails thing locked up, the other tutorials probably should have gone way advanced. Friday's sessions will be shorter and more focused, so I expect to get more out of them for myself personally. Not that they were bad, but many of us who were at last year's conference were hoping for more advanced material.

The real action was on IRC, of course. Just before last year's RailsConf 2006, my old notebook's screen died. As a result I was not connected to the hive mind where the really interesting communication. This year, my still mostly shiny MacBook Pro served me well, by letting me experience the full RailsConf experience. You could certainly tell who was connected to #railsconf, from the snickers that escaped from the occasionally brilliant witty commentary.

Scaling Rails From The Ground Up
This presentation was given by Jason Hoffman of Joyent. His presentation did indeed deal with scaling Rails from the ground up. Litterally, he mentioned the kind of flooring that you need for a minimal data center (concrete, if you must know). His talk went from 50000 foot view to a close-up view of a blade of grass, but he left out much of what goes in between during the first part of this presentation. Yes, he told us what kinds of power connectors they like to use at Joyent.

Here are a few excerpts from his talk:

*Moving parts of your Ruby code that are extremely performance sensitive to C extensions to Ruby is a very viable optimization technique.
*Power is a real limitation for building out a data center. There are large physical data centers that have a lot of empty rack space, due to being unable to access enough power to ad any additional servers.
*Compared to DNA sequencing, the amount of data on the web isn't that much.
*Scaling goes in both directions...you should be able to either up OR down. From running your app on a USB key, to running on a large server farm.
*Look for weak points in the architecture, for example a powerful box that has an OS limitation due to number of files in a directory.
*Scalable means "Lego"-like adding or removing of elements while keeping the integrity of the system intact.
*Rails is just one part of the scaling solution, the rest of the stack that Rails is running on needs to be well understood and kept as simple as possible, as it is easy to over-engineer fast.
*Use other data stores besides just relation databases where appropriate. His example was using LDAP for your user authentication, J-EAI for a message processing bus, and Postgres for the relational data.

One thing that impressed me was the amount of Java technologies in the stack that Joyent is espousing. For a community that spends so much time dissing Java, a whole lot of integration between Rails and Java has occurred over the last year.

Jason told some pretty amazing stories about hosting and colocation providers that they dealt with in the past that went out of business in spectacular ways. I'm not sure which was my favorite, trying to buy back their own servers from a bankruptcy proceeding in Sweden, or the one about the baker's racks with normal white box PC clones stacked on them when they were being charged for nice rack-mount servers. BTW, it is only legal to use backer's racks for electrical equipment in Texas. Zap!

Overall, the session was about half details about how Joyent has built their data center out, and about half scaring people into using some hosting provider, like Joyent, for example. Of course, can you blame him? That is a big part of what presenting at conferences is all about! Trading some useful information in exchange for getting to do some sales pitching to a crowd of likely customers.

Harnessing Capistrano

Jamis Buck, the erstwhile Rails committer and creator of Capistrano nee Switchtower gave the next session that I attended, an overview of Capistrano, including the upcoming 2.0 release.

Although most of us are using Cap as a deployment tool, it can be used for many other interesting things. Some examples are:

Ad-hoc monitoring
*Query all servers at once
*Uptime
*Operating system version (uname)
*Currently running processes (ps)
*Free disk space (df)
*Reading logs
*Searching logs

Query database server status
Server Maintenence
*nfs mount
*symlinks
*pkg_add $home/imgmagic

Troubleshooting
Custom tasks
Clearing cache files
Grep log files

Capistrano Assumptions:
Capistrano makes certain assumptions that are requirements for its use.
*SSH
*POSIX system
*Public keys or identical passwords on all servers

Other Interesting Things You Can Do With Capistrano
Gateways - when you cannot access the server directly over net, you can use set :gateway to tunnel through SSH to target server
set :gateway, "capistrano.demo"

Invoking Remote Commands
You can invoke arbitrary commands on a server using "cap -e invoke", and this does not even require CAP file. One drawback of invoke is that Cap needs to reconnect on each invocation.

An alternative to this is the "cap -e shell" command. This is similar to invoke, but caches connections, and can execute both tasks and commands.

Cap 2.0 adds namespaces for tasks. This is very important if you were using a third-party plugin that had its own Cap tasks.

Variables
Cap variables can be assign values passed in when Capistrano is called. They can be loaded either before or after recipes are loaded. If loading vars after recipies are loaded, any values assigned in the

Transactions
Cap allows you to wrap one or more deployment commands in a transaction. If a transaction is performed on multiple machines, and fails, Cap auto restores the state of each machine on failure
Example:
on_rollback { task_to_perform_when_transaction_fails }

Deployment Recipes
Capistrano 2 allows you to opt out of deployment recipes, for custom deployment recipes, or for non-deployment uses. The default deployment recipes in Cap do have several assumptions:
*Application code in under source control
*The app os a web application (Rails)
*Production environment is ready (all servers are setup and running)
*Using standalone FCGI listeners

How to Cap 2.0 Your App
Switching to Capistrano 2.0 should not be difficult, according to Jamis. The basic process is:
*goto your application base directory
*run "capify ."
*setup a minimal capfile

There are a couple situations where you might have troubles when upgrading to 2.0:
*3rd party ext. and libs
*Overridden or extended tasks without namespace

As a result, Cap 2.0 has a compatibility mode, which provides tasks with old names they need.

Conclusions
Despite the similarity of Rake and Capistrano syntax, they are nothing alike underneath, nor is Cap intended to replace Rake. The new Net::SSH and Net:SFTP gems give Cap even more power as a remote scripting tool to handle not just deployment, but all sorts of time-consuming tasks. The benefits of using Capistrano increase the more machines you are trying to get your software deployed on. And if you are not using it now, what are you waiting for?

Wednesday, May 16, 2007

Packing For RailsConf 2007

I am packing my stuff for RailsConf 2007, and I am pretty excited. Last year's conference was the best event I had been to in years! The growth in the momentum and enthusiasm in the Rails community has only accelerated in the last year, and I am giddy at the prospect of more fun brain candy!

I will be blogging from the conference, but not moment to moment like some quicker multitaskers. No, I prefer a more Christian Science Monitor approach, giving a complete picture of relevance sometime after events have taken place. Well, I will try to stay focused, but relevant or not here I come.

I was going to post my planned schedule for events I will be attending, but so is everyone else right now, and Dr. Nic's MyConfPlan is down at the moment.. Also, I will at Ezra'a Merb hackfest, and any parties I get invited to. Hint hint, all you companies hoping to sell me things, or sell me about things...feel free to try to influence me by buying me a beer.

Tuesday, May 15, 2007

The Robotic Revolution

The upcoming RailsConf 2007 is not the only revolutionary conference that is going on this week. At that epicenter of robotics and artificial intelligence research Boston, MA is the RoboBusiness Conference and Expo featuring everybody who is anybody in the biz such as iRobot.

CNET has a pretty good interview with Rodney Brooks, the CTO of iRobot. Despite the popularity of the Roomba, the robotics revolution has hardly begun. Brooks makes the interesting observation that not only will we see more autonomous robots wandering around like the Roomba, but even more embedded robotics like the self-parking feature on the Lexus.

Ultimately, he sees a cyborg society, where we are merged with our robots. It's a rather utopian vision, like that of Ray Kurzweil and the Singularity. I am also an optimist...at worst, the robots will keep us as pets.

Thursday, May 10, 2007

Why I Haven't Posted Anything Lately...

I have been enjoying some real world fun with my wife and son on the north shore of Hawaii the last few days, and so I have not had time or inclination to post anything.

But I am back in action now, and there will be lots of high-tech fun at RailsConf next week.

Oh, but island life is beautiful. I already miss it...

Tuesday, May 01, 2007

Become An Initiate Of The Bayesian Conspiracy

Jeff Atwood at the Coding Horror blog links to a great introduction to Bayes' Theorem.

If indeed as has been claimed "Google uses Bayesian filtering the way Microsoft uses the if statement," we should all be well versed in the work of the mysterious Reverend Bayes...

I have been playing around intermittently with an interesting application of Bayesian classification for a couple of years. Perhaps this will inspire me to actually finish it up enough to put it up on the web.

Thursday, April 26, 2007

Getting Your attachment_fu Back Out Of The Database

I have been busy the last few nights incorporating the brilliant Rails plugin called attachment_fu from Rick Olson aka technoweenie. If you do not know about attachment_fu, it is a complete solution to the problem of uploading image files attachments to include with your models.

First, I had to get past the initial hurdle of getting ImageScience and FreeImage correctly installed and working on my Mac. Despite the claims that Locomotive should have already had these in the bundle, I had to go thru a small process to get the prerequisites going.

I was then able to easily follow the careful instructions of Mike Clark, who has blogged at some length of how to get started with attachment_fu. In very short order, I had a working upload page, and another page displaying the automatically generated thumbnails. I was happily bragging to myself that "my attachment_fu has grown powerful, ha ha ha".

Then it occurred to me that using the :file_system option which stores uploaded files and thumbnails onto the web server's drive, typically into a special part of the "public" directory, was quick and easy, but not very scalable. Suddenly my attachment_fu is wimpy.

Luckily, attachment_fu supports the idea of "backends", which are code modules designed to communicate with the backend storage to be used for the images and thumbnails. The three provided backends are the file system, database, and Amazon's S3 storage. I decided that switching to the database storage was the best for my particular application. I changed the configuration option as described by Mike Clark, and ran my app expecting everything to just work...

Boom! Errors up the wazoo. OK, I wade in and discover that there is plenty of hidden away functionality in that plugin. First, the database storage backend requires an additional table called "db_files" not mentioned in mike clark's blog. The required additional migration is as follows:


t.column :db_file_id, :integer

create_table :db_files do |t|
t.column :data, :binary
end


You will need to add the "db_file_id" column to the table that stores your attachments. Then you need to create the "db_files" table to hold the actual binary data for the images and thumbnails.

I made the changes, ran the migration, and then I was able to upload the image. Almost there... However, I was shocked to see an error on the page that was supposed to display said image. Uh-oh!

It turns out that although the mechanism for displaying images which are stored in the file system or in S3 are exposed so they are web server accessible, the database storage engine is not yet fully implemented. Most importantly, the "public_filename" method is not there. So images get into the database, but there is no convenient way to display them.

At first I thought that I could use the "create_temp_file" method. However, a Ruby Tempfile deletes itself when it goes out of scope. Not the right thing, unless you don't mind images that disappear before they are actually displayed in the browser.

Anyhow, I went and after studying the code a bit, made a few changes to attachment_fu to provide better support. My solution was to add a method to the database backend to render the binary image data on the fly whenever it is requested.


def image_data(thumbnail = nil)
if thumbnail.nil?
current_data
else
thumbnails.find_by_thumbnail(thumbnail.to_s).current_data
end
end


To keep things nice and restful, I added support to my User controller to render the image when image format is requested:


def show
@user = current_user

respond_to do |format|
format.html # show.rhtml
format.xml { render :xml => @user.to_xml }
format.jpg do
picture = current_user.picture
image = picture.image_data(:thumb)
send_data (image, :type => 'image/jpeg',
:filename => picture.filename,
:disposition => 'inline')
end
end
end


Once this is all completed, displaying the image within a view is simple with a helper:


def user_thumbnail_tag(user)
image_tag("#{user_path(user)}.jpg")
end


And there you have it. The nice thing about this solution is you can deploy on multiple web servers behind a load balancer without concern. Thanks to the awesome power of attachment_fu...you have been warned.

Wednesday, April 25, 2007

Growing The Code

Kevin Barnes over at Code Craft has a cool posting comparing software development to gardening. I agree with him that it is a fantastic analogy!

It really rings true to me in a couple of fun ways:

  • Gardening cannot be done once and for ever. It takes constant work to keep it both healthy and tidy.

  • There is a big difference in both purpose and aesthetics within different gardens. Consider a typical traditional backyard garden vs. Noguchi Gardens. Or a small family farm vs. a large industrial combine. Each is in theory intended to fulfill a similar purpose, but does so in radically different ways.

  • Some people seem to have a knack for gardening, while others cannot help but kill even a hardy plant. And of course, the only way to tell if a gardener is any good, is to look at some gardens they have tended recently.


The problem with applying any real-world analogy to a virtual thing, is it will inevitably fall apart at some point. But this one is pretty sturdy at first glance.

Monday, April 16, 2007

Silverlight and Ruby?

Today, Microsoft announced their Silverlight technology platform. I will not bore you, kind reader, with yet another recap of what has already been written by so many others already.

However, there are a couple of curious details that have piqued my interest. John Lam, of RubyCLR fame, made an interesting comment on his blog earlier today about Silverlight:

This was a major reason why I moved my family to the other side of the continent...


Even more interesting, is a bit from Chinese news site CSDN, which is poorly translated here:

6, in addition, Silverlight designers and developers to provide a large number of development tools and development support. 对设计者来说,Expression Design和Expression Blend软件可以创建可重用界面,Expression Web使得在符合W3C标准的网站开发中可以使用XHTML、XML、XSLT、CSS以及ASP.NET等工具。To the designers, Expression and Expression Blend Design software can be re-established use interface Expression Web made in the development of the website with W3C standards can be used XHTML. XML, XSLT, CSS and ASP.NET tools. 对开发者来说,基于Visual Studio的Web开发支持包括ASP.NET AJAX在内的技术,并支持JavaScript,C#,VB,Ruby以及Python等多种开发语言。For developers, Visual Studio's Web-based support, including the technical AJAX ASP.NET and support JavaScript, C #, VB, Ruby and Python and other development languages.


So what is up? Is Ruby the programming language for Silverlight? Or at least one programming language option? Will dynamic languages take over the new desktop?

Tuesday, April 10, 2007

My New MacBook Pro Rocks For Rails Development

The last week or so I have been very busy playing with and setting up my new MacBook Pro. This is, in fact, my first post from it. After spending some time with it, I have to say that I am still extremely pleased! I have my Ruby on Rails environment all setup and working spendidly. I have my primary dev toolset CocoaMySQL, Locomotive, TextMate, and SVNx and now everything is pretty dialed in. I was able to grab one of my rails projects from my SVN repository, and run it successfully, after tweaking a few file permissions.

Wow, this baby can cook! Not just the temp, but the performance is great. I installed Parallels and couple versions of Windows XP for testing. It seems funny to me, having XP in one window, bash in another, and a stylish OSX app in a third. I know I could have done more with virtual OS stuff before I had this Mac, but now it's just so fun and easy!

Anyhow, now that I have come back to the Mac side, I sure feel a whole lot better! I guess you really CAN have it all nowadays...

Wednesday, March 28, 2007

E Is For Editor Envy

I love it when I find out about a cool new tool. In this case, it is E, a Windows clone of the ubiquitous Mac text editor TextMate. Looks like this project has been around for awhile, but I just heard of it thanks to a blog entry about creating a Mac-like environment under Windows.

Installing E is not a small task, although it is not a difficult one. This is due to the fact that E relies heavily on Cygwin to support "bundles" which is how TextMate creates their oh-so-useful macro and template collections. I have installed it on two machines now, and I had trouble with cygwin on both of them. Sigh! After a few missteps, I managed to get Cygwin installed and E working mostly correctly.

Having a text editor that supports changing themes without a massive amount of pain is really nice for a guy like me who likes that retro black background thing. And having the same basic macro capabilities as TextMate under Windows is awesome! I have TortoiseSVN installed, and E's project view lets me see the change status and commit or diff changes. All of your basic needs in a Ruby on Rails editing tool are there.

But basic compatibility is all you get at this point. E does support TextMate "bundles", but there are plenty of differences in the bundles on each platform (Mac vs. Windows), enough so that plenty of things don't work. On each of the two machines I tried E on, I had different problems with the more advanced bundle abilities of bothe the Ruby and the Rails bundles.

The author of E is working closely with the author of TextMate, being as they are both Danes and very open minded, and is planning on a Unix version to join the Windows version. Even with the weirdness and slowness of the Cygwin install, E is rocking, so on Ubuntu, for example, E could become a cornerstone of a slick development platform. At this point, the real TextMate on the Mac is still the optimal route to programming glory. If you need to work under Windows, E is worth trying out, just be ready for some rough edges.

Monday, March 26, 2007

The Ruby.NET Interview From Down Under

An interview with Dr. Wayne Kelly has been put up on Channel 9, Microsoft's video interview site. Dr. Kelly is head of the Ruby.NET compiler project at the Queensland University of Technology in Australia. As always, I am eager to see progress on the .NET side of the Ruby language wars. I drank my coffee, and put on my phones for the 15 minute interview.

After watching the video, I must say I am a little underwhelmed. Not to disparage the fine work of the good doctor on this worthy project, far from it. But I was not impressed by his comments about his lack of familiarity with the Ruby language itself. "If I was going to do any real Ruby programming, I would have to have the pickaxe book at my side to help me with the syntax, " says Dr. Kelly midway thru the interview.

Compare that to a zealous Ruby language fan like Ola Bini with the JRuby team. And I say this as a long time detractor of Java! How DARE they flaunt their superiority.

There were a couple of interesting points, one of which was the trouble with implementing the Ruby.NET compiler by directly matching Ruby language methods to CLR methods. The collection of CLR methods for an assembly being set at compile time, vs. Ruby class and instance methods which are a very fluid and wonderful thing and can be created at any time.

It was also curious that he said they are not using any of the .NET techniques being pioneered by the IronPython team, like use of dynamic delegates and Lightweight Code Generation. I was really expecting that they would be. At least I would be, if I were them.

Dr. Kelly was apologetic over his team's missing their self-imposed monthly delivery of updated code. He was so understated, that by the end of the interview I got the feeling that "under promise and over deliver" wasn't just cliche, but it was this guy's personal mantra. I hope I got the correct impression.

Let's see some bits, boys! Keep those updates coming...the race isn't over yet.

Wednesday, March 21, 2007

I Have Seen The Future

The amazing artistic visions of computer science researcher Andrei State combine both grace and utility. I am reminded of how I felt first seeing the original Apple Knowledge Navigator video...a peek just around the corner into the future.

Check out Andrei's technical section of the really neat ARTA GRAFICA website. Thank you to my friend Dan Rasmus and his cool "Future of Information Work" blog for turning me on to this...

Wednesday, March 14, 2007

I Speak For The Code

Recently I was in a client meeting with a bunch of managers to discuss some very complex changes that were being proposed for an existing system. I was invited to the meeting so I could "speak for the code", which to them meant that I could validate the ideas of the group based on my knowledge of the code base.

After the meeting ended, I kept mulling over that phrase "speaking for the code". The more I did, the more I realized the parallels between "speaking for the code" as an architect or lead developer, and the Lorax "speaking for the trees" in the Dr. Seuss story of the same name.

So here goes my attempt to illustrate some lessons about best practices in software development, inspired by the story of the Lorax...


At the far end of town where the Grickle-grass grows and the wind smells slow-and sour when it blows and no birds ever sing excepting old crows...is the Street of the Lifted Lorax.
And deep in the Grickle-grass, some people say, if you look deep enough you can still see, today, where the Lorax once stood just as long as it could before somebody lifted the Lorax away.

Our story begins looking at what remains of a once thriving software application, now gone to ruin. What went wrong?

What was the Lorax?
Any why was it there?
And why was it lifted and taken somewhere from the far end of town where the Grickle-grass grows?
The old Once-ler still lives here.
Ask him. He knows.

Perhaps the Lorax was the original system architect. But he is gone now, leaving behind Once-ler who is now in charge of the project.

You won´t see the Once-ler.
Don´t knock at his door.
He stays in his Lerkim on top of his store.
He stays in his Lerkim, cold under the roof,
where he makes his own clothes
out of miff-muffered moof.
And on special dank midnights in August,
he peeks out of the shutters
and sometimes he speaks
and tells how the Lorax was lifted away.
He´ll tell you, perhaps... if you´re willing to pay.
Then he hides what you paid him away in his Snuvv,
his secret strange hole in his gruvvulous glove.
Then he grunts, I will call you by Whisper-ma-Phone,
for the secrets I tell you are for your ears alone.

The Once-ler is the swamp guide project manager or developer who remains behind, holding on tightly to the secrets of the system.

Now I´ll tell you, he says, with his teeth sounding gray,
how the Lorax got lifted and taken away...
It all started way back... such a long, long time back...

Way back in the days when the grass was still green
and the pond was still wet
and the clouds were still clean,
and the song of the Swomee-Swans rang out in space...
one morning, I came to this glorious place.
And I first saw the trees! The Truffula Trees!
The bright-colored tufts of the Truffula Trees!
Mile after mile in the fresh morning breeze.

And under the trees, I saw Brown Bar-ba-loots
frisking about in their Bar-ba-loot suits
as they played in the shade and ate Truffula Fruits.

From the rippulous pond came the comfortable sound
of the Humming-Fish humming while splashing around.

The original system was a fine merger of art and science. It provided for all of the inhabitants of its software ecosystem (users, developers, testers, etc.) by using practices that conserved the ecology of the system. It was able to successfully grow from its origin to a useful level of functionality while preserving the environment of the code base.

In no time at all, I had built a small shop.
Then I chopped down a Truffula Tree with one chop.
And with great skillful skill and with great speedy speed,
I took the soft tuft. And I knitted a Thneed!

The instand I´d finished, I heard a ga-Zump!
I looked.
I saw something pop out of the stump
of the tree I´d chopped down. It was sort of a man.
Describe him?...That´s hard. I don´t know if I can.

He was shortish. And oldish.
And brownish. And mossy.
And he spoke with a voice
that was sharpish and bossy.

Mister! he said with a sawdusty sneeze,
I am the Lorax. I speak for the trees.
I speak for the trees, for the trees have no tongues.
And I´m asking you, sir, at the top of my lungs--
he was very upset as he shouted and puffed--
What´s that THING you´ve made out of my Truffula tuft?

The Once-ler took the original application in a direction that it was not architected to take, in a way that disturbed the equilibrium enough to attract the ire of the Lorax, who is the guardian for the system's logical integrity.

Look, Lorax, I said. There´s no cause for alarm.
I chopped just one tree. I am doing no harm.
I´m being quite useful. This thing is a Thneed.
A Thneed´s a Fine-Something-That-All-People-Need!
It´s a shirt. It´s a sock. It´s a glove. It´s a hat.
But it has other uses. Yes, far beyond that.
You can use it for carpets. For pillows! For sheets!
Or curtains! Or covers for bicycle seats!
The Lorax said,
Sir! You are crazy with greed.
There is no one on earth
who would buy that fool Thneed!

The Once-ler is utterly convinced of his own ideas regarding the directions for the system, and is not interested in listening to the warnings of the Lorax. He thinks he knows what the users need, and how to make the system fill that need. Or perhaps he is using the wrong design patterns, or too many different patterns, or some classic anti-patterns.

And, in no time at all,
in the factory I built,
the whole Once-ler Family
was working full tilt.
We were all knitting Thneeds
just as busy as bees,
to the sound of the chopping
of Truffula Trees.

Then...
Oh! Baby! Oh!
How my business did grow!
Now, chopping one tree
at a time
was too slow.

So I quickly invented my Super-Axe-Hacker
which whacked off four Truffula Trees at one smacker.
We were making Thneeds
four times as fast as before!
And that Lorax?... He didn´t show up any more.

Now the Once-ler is scaling up the project, using all of his old buddies. Now four times more staffing than before. Not only that, but with such confidence in his vision that he doesn't miss the fact that the crucial architectural knowledge of the Lorax is no longer guiding the project.

But the next week he knocked on my new office door.
He snapped, I´m the Lorax who speaks for the trees
which you seem to be chopping as fast as you please.
But I´m also in charge of the Brown Bar-ba-loots
who played in the shade in their Bar-ba-loot suits
and happily lived, eating Truffula Fruits.
NOW...thanks to your hacking my trees to the ground,
there´s not enough Truffula Fruit to go ´round.
And my poor Bar-ba-loots are all getting the crummies
because they have gas, and no food, in their tummies!

They loved living here. But I can´t let them stay.
They´ll have to find food. And I hope that they may.
Good luck, boys, he cried. And he sent them away.

I, the Once-ler, felt sad as I watched them all go.
BUT... business is business! And business must grow
regardless of crummies in tummies, you know.

The Once-ler is willing to do anything at all to the code base, including losing the architectural consistency of the system, in order to implement his new vision for the project. Or lose anyone at all on the project team, for that matter, to maintain control over the project. Too bad Once-ler doesn't realize that once the tipping point of architectural instability is reached, a system can become unreliable and unmaintainable very quickly.

And then I got mad. I got terribly mad.
I yelled at the Lorax, Now listen here, Dad!
All you do is yap-yap and say, Bad! Bad! Bad! Bad!
Well, I have my rights, sir, and I´m telling you
I intend to go on doing just what I do!
And, for your information, you Lorax, I´m figgering on biggering
and BIGGERING and BIGGERING and BIGGERING,
turning MORE Truffula Trees into Thneeds
which everyone, EVERYONE, EVERYONE needs!

And at that very moment, we heard a loud whack!
From outside in the fields came a sickening smack
of an axe on a tree. Then we heard the tree fall.
The very last Truffula Tree of them all!

Did you see THAT coming? Of course you did! Once the technical debt of the system exceeded the available resources, the application went bankrupt.

No more trees. No more Thneeds. No more work to be done.
So, in no time, my uncles and aunts, every one,
all waved me good-bye. They jumped into my cars
and drove away under the smoke-smuggered stars.

Now all that was left ´neath the bad-smelling sky
was my big empty factory... the Lorax... and I.

Once the project's future prospects are bleak, project funding or company revenues dry up. As a result, key resources leave. When this vicious cycle begins, there may be no stopping it.

The Lorax said nothing. Just gave me a glance...
just gave me a very sad, sad backward glance...
as he lifted himself by the seat of his pants.
And I´ll never forget the grim look on his face
when he heisted himself and took leave of this place,
through a hole in the smog, without leaving a trace.

And all that the Lorax left here in this mess
was a small pile of rocks, with one word...
UNLESS.

If you are an architect or dev lead, you are probably sympathizing with the Lorax as you sometimes feel like you are "defending" your system. If you are a hiring manager or recruiter reading this blog, perhaps at this point in the story you are getting a idea about why it is hard to recruit and retain the best system architects and developers to work on toxic projects.

But now, says the Once-ler,
Now that you´re here, the word of the Lorax seems perfectly clear.
UNLESS someone like you cares a whole awful lot,
nothing is going to get better. It´s not. SO...
Catch! calls the Once-ler. He lets something fall.
It´s a Truffula Seed. It´s the last one of all!
You´re in charge of the last of the Truffula Seeds.
And Truffula Trees are what everyone needs.
Plant a new Truffula. Treat it with care.
Give it clean water. And feed it fresh air.
Grow a forest. Protect it from axes that hack.
Then the Lorax and all of his friends may come back.

System architects, let a thousand flowers bloom. Fight for your systems.

RIP, Dr. Seuss. We miss your wisdom.

Tuesday, March 13, 2007

CruiseControl.rb: Continuous Integration Is About To Get Beautiful

At last, Ruby has a real Continuous Integration system, not just some crazy hacked-together solution. Nothing against crazy, hacked-together solutions, but your CI system is not the place for such madness. From those wonderful folks at Thoughtworks, we now have CruiseControl.rb, to join the CruiseControl and CruiseControl.NET offerings for Java and .NET projects respectively.

I have been a constant user of CruiseControl.NET for all of the MS-platform projects for the last couple of years, and having a powerful, flexible system has been great. However, having to pay heavily of the angle-bracket tax to create the XML for the NAnt build scripts, CC.NET config files, and pretty much everything else has been a real pain. The pleasure has been the real-time integration with the CCTray notification program (shows up red in your system tray, and pops up a balloon notification when a build has been broken).

Now, a pure Ruby solution has been created. Although a very young offering, the incredible simplicity of Ruby allows a far easier extensibility than the other CruiseControl options. Here are a few of the interesting features:


  • All CruiseControl.rb config files are Ruby, for nice DSL-ish syntax

  • Uses Rake by default for builds, but can support NAnt, Ant, MSBuild or anything other build tool. In other words you CAN use CruiseControl.rb as your CI systems for any target language or environment, not just for Ruby or Ruby on Rails projects.

  • Build messages can be sent via IM using Jabber

  • The same CCTray system tray application can monitor CruiseControl.rb servers as well as CruiseControl.NET servers.



CruiseControl.rb looks to have the core features required for a decent, even an amazing CI system. However, being such a new tool it still lacks some really cool and useful add-on things like integration with Fitnesse, Simian code analysis, and the other neat add-ons that can easily integrate with CruiseControl.NET. Given that the CruiseControl.rb is pure Ruby, and the prolific nature of the Ruby open source community, I would not be surprised if those gaps are filled very quickly.

Rock on, Thoughtworks!

Monday, March 12, 2007

Aptana + RadRails = Much Web Development Goodness?

AptanaIt was a couple of weeks ago when the RadRails team acknowledged that the ship had started to wander off course. Without any revenues, and with too few project contributors, the project was looking adrift. Could this be the end?

Do not fear, gentle reader. Last week, the announcement came at EclipseCon that the RadRails project is now part of the Aptana project. Up until this announcement, I had never heard of Aptana. What is this, I said. AJAX IDE, JavaScript debugging, support for every major JS library from the now ubiquitous Prototype to my current personal favorite jQuery. Of course I had to immediately download and install it, and try out the RadRails integration.

Despite some initial hitches with the install that required a retry or two, and a weird error message when opening RHTML files, I think that I will spend some more time with it to really put it thru its paces. I like what a good IDE can give you, and so am willing to put up with a bit to see if Aptana can deliver what it promises. I will be posting here with my results...

Monday, March 05, 2007

JRuby Has Won The Rails Race vs. .NET

So now it is official. The latest build from the JRuby team is now running Ruby on Rails in the JRuby runtime. Great work from that team! The Sunsters up top must be gloating right now.

And Microsoft is still MIA. Despite some hopeful signs of life, the silence is deafening from Ray Ozzie and the .NET camp (is that a band?). MS had better have some damn strong announcement at MIX vis-à-vis Ruby.NET or some top secret John Lam project if they want to stay in the game.

In the meantime, I still think that YARV will be the runtime for me, based on sheer performance alone. Not to mention that is now part of the Ruby SVN tree.

Thursday, March 01, 2007

Now Computerworld Jumps In On The Rails Lovefest

According to Computerworld today, Ruby on Rails is the number one of the "five most important technologies that you need to know about in 2007." Oh yeah! As I wrote a couple of days ago, now even the oldest of the old school enterprise publications are showing the love for Ruby and for Rails.

That in itself is quite exciting. Another interesting point to note, is learned by looking over the list of the other four hot technologies. Three are hardware related, and and the fourth is grid computing. So Rails is the ONLY important new application development technology right now, according to Computerworld? So it would seem...

I cannot say I disagree, but I am still amazed!

Monday, February 26, 2007

Even eWeek Is Falling For Ruby

Even that stanch old "enterprisey" publication eWeek has been giving some love to Ruby and Ruby on Rails. Today's most recent article is entitled "Ruby, Ruby, When Will You Be Mine?". Was this supposed to run on Valentine's Day? I'm definitely feeling the love in the title.

Anyhow, the author is all over the JRuby project. Messrs. Nutter et. al. have been building up the energy at the same time as the code base. Microsoft is notably receiving less coverage, no doubt due to providing no visibility as to what they are up to. I almost hate to give Sun props over Microsoft, after spending so many years arguing the opposite, but Sun is allowing the JRuby team to keep up the enthusiasm in the community. MS is giving the appearance of stagnation, even if they are just as active with development of Ruby.NET/RubyCLR/etc. For example, the Ruby.NET team is saying "This is a preliminary beta release. It is knowingly incomplete and contains many bugs. We therefore ask that you do not submit bug reports at this stage." Talk about the Wow...not. Meanwhile the JRuby team is involving the community in the entire dev process just like a real open source project does.

Based on the initial performance numbers from Antonio Cangiano, I'm probably not really looking at either one of those options for a production application any time soon. Can you say YARV?

Saturday, February 24, 2007

RailsConf 2007 Is Sold Out

My dear friends, if you don't have your ticket for RailsConf 2007, you have missed the boat. All 1200 passes have now been sold out!

I suspect that most conferences have a short peak of sales right when the passes first go on sale, then sell the bulk of their registrations in the last few days before the start of the conference, if conferences are anything like concerts. Since most conference don't have the draw of a big musical headliner, conferences sell discounted registrations for a short period of time, to encourage early registrations and guarantee that the conference sells the minimum number of attendees to break-even. If this is true, and given that RailsConf 2007 is still 3 months away, this is pretty amazing. They never even got to the end of the discounted registration period before they sold out.

If you have your position secured, then see you at RailsConf on Beer. Otherwise, well, guess I won't see you unless you somehow get thru the waiting list.

This is going to be fun...

Friday, February 23, 2007

The Wigglebot Cometh

I saw this very interesting robot today. Not only can it crawl, shimmy, roll, and walk, but it does so by combining a small group of autonomous, modular, self-reconfiguring bots that operate together as a unit. Very cool!

Transformers, indeed. Have I mentioned that I want a set of Lego Mindstorms NXT for my birthday? I would love to mess around with ruby-nxt or the Microsoft Robotics Studio.

Gazing Into The ORM

Jeremy Miller has an interesting post today regarding Object Relation Mapping (ORM). Droves of developers are now flocking to ORMs via Ruby on Rails, Castle, or one of the other many projects in this space, so it is good to have people like Jeremy exploring from a real implementation perspective.

Anyhow, his post really is concerned with applications that use an existing database, have a large amount of logical processing. Simply applying an ORM without considering the logical implications of the data, not only fails to take advantage of the power of ORMs, but falls into a bit of a quagmire, with potentially a very non-DRY result.

Some of the specific examples he cites are:


  • Big tables don't map to a single object.  I don't think it's possible that a class with a 100 different properties can possibly be cohesive.  We'd be much better off in terms of writing business logic if that 100 column table is modelled in the middle tier by a half dozen classes, each with a cohesive responsibility.  It may make perfect sense to have only one table for the entire object hierarchy, but big classes are almost always a bad thing.
  • Data Clump and Primitive Obsession code smells.  A database row is naturally flat.  I want to do a bigger post on this later, but think about a database table(s) with lot's of something_currency/something_amount combinations.  There's a separate object for Money wanting to come out.  If you make your business objects pure representations of the database you could easily end up with a large amount of duplicate logic around currency and quantity conversions.
  • Natural cases for polymorphism in your object model.  I think the roughest part of O/R mapping is handling polymorphism inside the database.  Check out Fowler's patterns on database mappings for inheritance.



He then goes on to make an important point regarding the role of the database in the software architecture of your application. Basically there are only two perspectives that make any sense:

  • The database is paramount, and the system is expressed and understood in terms of the tables and rows in the database.  The application code and even user interface is just a conduit to get information back and forth into the database.  You design the database first and then build the business and data layers to match the database.  In the .Net world we might just consume raw DataSet's in the application, effectively just working with the database tables offline.
  • The behavior of the system, primarily in the middle tier and user interface, is paramount, and the database is "just" a means to persist the state of the system.  The database is either built to match the business classes or designed somewhat independently.



So in the case of an application that has significant business logic, it would seem to me that the second case is quite preferable. However, in the case where a legacy database is involved, how can we really avoid the first? I have seen many applications get stuck in that quagmire myself, and one real problem is that the business logic becomes a lot harder to represent cleanly when having to preserve the existing database schema's problems. Especially when trying to achieve a very DSL like approach for business service layers. The less that the domain experts have to understand the database, and can just speak in terms of domain concepts, the better!

Monday, February 19, 2007

Format Ruby Code On Your Blog Postings Like The Cool Kids

I had noticed that almost all of the cool people post nicely formatted, color coded, beautiful looking Ruby code whenever they post.

Well, some of the cool people use a style of formatting that defies description...but I digress.

Anyhow, I looked at my poor pitiful postings, and felt like a second, or even third class citizen. Everybody's code is looking better than mine! What can be done?! Extreme makeover, Ruby CSS edition.

Mac developers who are using TextMate already have a built-in way to get back nicely formatted HTML. Does this mean they have built-in coolness? Yes it does. But for others who are using a different OS, or maybe an IDE like RadRails, there is also a solution.

On the Ruby Advent calendar site from last year, is a cool posting from Peter Cooper that allows you to submit some Ruby code thru a web page, and get back formatted HTML. Add a little bit of CSS to your page, and you too can be one of the cool people.

I had to modify the suggested CSS for my ultra-retro TTL terminal look that I usually set my editors up with. So my Ruby code went from this:


class Animal < DSLThing
attr_accessor :name

def initialize(name=nil)
@name = name
end
end


To this:
class Animal < DSLThing
attr_accessor :name

def initialize(name=nil)
@name = name
end
end


With my new CSS, I can now hopefully masquerade as one of the cool kids, and maybe even sneak into the club.

Wednesday, February 14, 2007

Ruby Blocks, Closures, and Continuations

Recently, while blogging about the Ruby.NET project, it was pointed out to me that I was incorrect about Ruby.NET not supporting closures. Brendan noted that in fact continuations are what is not yet supported. I quickly realized that I was not entirely clear about the differences between a closure and a continuation, except that they both used code blocks. I decided that it must be time that I figured it out.

When in doubt about any aspect of Ruby, it is best to go back to Matz. I found an interview with Matz conducted back in 2003 by Bill Venners. First, let us get Matz's definition of a block:


Yukihiro Matsumoto: Blocks are basically nameless functions...Basically, you can pass a nameless function to another function, and then that function can invoke the passed-in nameless function. For example, a function could perform iteration by passing one item at a time to the nameless function. This is a common style, called higher order function style, among languages that can handle functions as first class objects...In Ruby, the difference is mainly a different kind of syntax for higher order functions. In other languages, you have to specify explicitly that a function can accept another function as an argument. But in Ruby, any method can be called with a block as an implicit argument. Inside the method, you can call the block using the yield keyword with a value.


OK, so far so good. Any beginning Rubyist has seen the fun with blocks:

class Array
def find
for i in 0...size
value = self[i]
return value if yield(value)
end
return nil
end
end

puts [1, 3, 5, 7, 9].find {|v| v*v > 30 }

The block in the above example is used to pass a function used to tell the the "find" method how to determine when the search is complete.

SO what is a closure? Matz, enlighten us:


Yukihiro Matsumoto: ...we can create a closure out of a block. You can pass around a nameless function object, the closure, to another method to customize the behavior of the method. As another example, if you have a sort method to sort an array or list, you can pass a block to define how to compare the elements. This is not iteration. This is not a loop. But it is using blocks...

Bill Venners: What makes a block a closure?

Yukihiro Matsumoto: A closure object has code to run, the executable, and state around the code, the scope. So you capture the environment, namely the local variables, in the closure. As a result, you can refer to the local variables inside a closure. Even after the function has returned, and its local scope has been destroyed, the local variables remain in existence as part of the closure object.


Alright, so that sounds like a pretty good definition of a closure. The Wikipedia page for Ruby has a nice, simple closure example:

# In an object instance variable (denoted with '@'), remember a block.
def remember(&a_block)
@block = a_block
end

# Invoke the above method, giving it a block that takes a name.
remember {|name| puts "Hello, #{name}!"}

# When the time is right (for the object) -- call the closure!
@block.call("John")
# => "Hello, John!"

So storing a block of code into a variable makes it a closure. It can then be called later on using the "call" method.

So what is a continuation, then? A short perusal of the comp.lang.ruby group led me to this video from RubyConf 2005 where Chad Fowler and Jim Weirich explain continuations.

According to them, "A continuation is whatever happens after a block is done executing". In other words, a continuation is an object that can restore the entire context of a program back to where it was when the continuation was saved. Sounds simple enough, but the ramifications can be a little brain boggling.

To summarize a little from Jim Weirich’s blog on Ruby:


Ruby provides continuation functionality in the form of the callcc method. The continuation is passed to a block, and within the block we can do anything we want to with the continuation. Calling it will immediately cause the callcc call that created the continuation to return the value given to the continuation.


Jim provides a nice simple code example, too:


def level3(cont)
cont.call("RETURN THIS")
end

def level2(cont)
level3(cont)
return "NEVER RETURNED"
end

def top_level_function
callcc { |cc|
level2(cc)
}
end

answer = top_level_function
puts answer # => "RETURN THIS"


The block passed into the "callcc" method has a parameter which is also a block. This parameter block is a bit of code that returns control back to the original calling code, immediately after the "callcc" method was called, along with restoring the entire context from when the original call was made.

For example, in the code example above, when the level3 method hits the line with cont.call("RETURN THIS"), the code returns to the top_level_function to immediately after where the callcc method was called in the first place. The parameter passed into the call method within the level3 method is returned by the callcc function, then returned by top_level_function. This is why "RETURN THIS" is displayed by the above code snippet.

Continuation are very cool and powerful, but I can see why most people don't get them. A little search of Krugle shows very few matches for either "callcc" or "Continuation" within the Ruby projects indexed there. It would appear very few people are using them. No wonder they might be dropping them from Ruby 2.0.

Ruby.NET and REXML: Not Yet

I finally had a chance to play around with the latest download of the Gardens Point Ruby.NET compiler. At first, I was excited, as my little DSL test application was able to run perfectly. Blocks, instance_eval, singleton classes all worked fine for me. Very cool!

Then I decided to experiment with the REXML ruby parser. I did so despite the fact that the compiler authors have stated in their project goals that "We do not however plan to implement the other Ruby libraries that commonly ship with the Ruby distribution, such as CGI and DBM (except for those implemented 100% in Ruby)". Since REXML is however completely implemented in Ruby, I thought I would give it a try. Unfortunately, I discovered that the Ruby.NET authors did not lie when they said that "Implementation is not yet complete but we have now implemented the vast majority of Ruby's builtin classes and modules. We have fixed large numbers of existing bugs, but many still remain."

I tried to run the simplest possible REXML sample:


require "rexml/document"
doc = REXML::Document.new File.new("mydoc.xml")


But here was my result:


loading rexml/document
loading rexml/element
loading rexml/parent
loading rexml/child
loading rexml/node
loading rexml/parseexception
finished loading rexml/parseexception
finished loading rexml/node
finished loading rexml/child
finished loading rexml/parent
loading rexml/namespace
loading rexml/xmltokens
finished loading rexml/xmltokens
finished loading rexml/namespace
loading rexml/attribute
loading rexml/text
loading rexml/entity
loading rexml/source
loading rexml/encoding
finished loading rexml/encoding
finished loading rexml/source
finished loading rexml/entity
loading rexml/doctype
loading rexml/attlistdecl
finished loading rexml/attlistdecl
finished loading rexml/doctype
finished loading rexml/text
finished loading rexml/attribute
loading rexml/cdata
finished loading rexml/cdata
loading rexml/xpath
loading rexml/functions
finished loading rexml/functions
loading rexml/xpath_parser
loading rexml/syncenumerator
finished loading rexml/syncenumerator
loading rexml/parsers/xpathparser
finished loading rexml/parsers/xpathparser
finished loading rexml/xpath_parser
finished loading rexml/xpath
finished loading rexml/element
loading rexml/xmldecl
finished loading rexml/xmldecl
loading rexml/comment
finished loading rexml/comment
loading rexml/instruction
finished loading rexml/instruction
loading rexml/rexml
finished loading rexml/rexml
loading rexml/output
finished loading rexml/output
loading rexml/parsers/baseparser
finished loading rexml/parsers/baseparser
loading rexml/parsers/streamparser
finished loading rexml/parsers/streamparser
loading rexml/parsers/treeparser
loading rexml/validation/validationexception
finished loading rexml/validation/validationexception
finished loading rexml/parsers/treeparser

Unhandled Exception: System.MissingMethodException: Method not found: 'System.Ob
ject Ruby.Eval.ivar_defined(System.String)'.
at Ruby.Compiler.AST.PROGRAM.ExecuteMain(PEFile Assembly, String[] args)
at Ruby.Compiler.RubyMain.Main(String[] args)


Oh well! Maybe next month's release will be ready for REXML...

Monday, February 12, 2007

Just Say No To Vista?

Security expert Bruce Schneier says not to use Windows Vista, due to the flaws of the Digital Rights Management (DRM) incorporated into the OS. No, really. One of, if not THE, top security expert says not to use Microsoft's newest OS.

To quote Mr. Schneier:


Windows Vista includes an array of "features" that you don't want. These features will make your computer less reliable and less secure. They'll make your computer less stable and run slower. They will cause technical support problems. They may even require you to upgrade some of your peripheral hardware and existing software. And these features won't do anything useful. In fact, they're working against you. They're digital rights management (DRM) features built into Vista at the behest of the entertainment industry.

And you don't get to refuse them.

The details are pretty geeky, but basically Microsoft has reworked a lot of the core operating system to add copy protection technology for new media formats like HD-DVD and Blu-ray disks. Certain high-quality output paths--audio and video--are reserved for protected peripheral devices. Sometimes output quality is artificially degraded; sometimes output is prevented entirely. And Vista continuously spends CPU time monitoring itself, trying to figure out if you're doing something that it thinks you shouldn't. If it does, it limits functionality and in extreme cases restarts just the video subsystem. We still don't know the exact details of all this, and how far-reaching it is, but it doesn't look good.

Microsoft put all those functionality-crippling features into Vista because it wants to own the entertainment industry. This isn't how Microsoft spins it, of course. It maintains that it has no choice, that it's Hollywood that is demanding DRM in Windows in order to allow "premium content"--meaning, new movies that are still earning revenue--onto your computer. If Microsoft didn't play along, it'd be relegated to second-class status as Hollywood pulled its support for the platform.


Schneier then goes on to explain why story is even worse then just controlling what music or movies you can play:


Microsoft is reaching for a much bigger prize than Apple: not just Hollywood, but also peripheral hardware vendors. Vista's DRM will require driver developers to comply with all kinds of rules and be certified; otherwise, they won't work. And Microsoft talks about expanding this to independent software vendors as well. It's another war for control of the computer market.

Unfortunately, we users are caught in the crossfire. We are not only stuck with DRM systems that interfere with our legitimate fair-use rights for the content we buy, we're stuck with DRM systems that interfere with all of our computer use--even the uses that have nothing to do with copyright.


And then finally the big kicker:


In the meantime, the only advice I can offer you is to not upgrade to Vista. It will be hard. Microsoft's bundling deals with computer manufacturers mean that it will be increasingly hard not to get the new operating system with new computers. And Microsoft has some pretty deep pockets and can wait us all out if it wants to. Yes, some people will shift to Macintosh and some fewer number to Linux, but most of us are stuck on Windows. Still, if enough customers say no to Vista, the company might actually listen.


That is a pretty dark picture you paint, Bruce...

Friday, February 09, 2007

Ruby.NET Lives!

It has been radio silence for quite a while from the Ruby.NET project. Well, the eagle had landed. There is a new beta release.

Here is what they have to say for themselves:


We are pleased to announce the release of a new Beta (version 0.6) of the Gardens Point Ruby.NET compiler. Implementation is not yet complete but we have now implemented the vast majority of Ruby's builtin classes and modules. We have fixed large numbers of existing bugs, but many still remain. We have not yet implemented continuations or Ruby threads but support most other language features.

In addition to passing all 871 tests in the samples/test.rb installation test suite of Ruby 1.8.2, we are now able to support the standard Ruby test unit library and pass most of the 1864 assertions in the test/ruby test directory.

We have just started work on getting Ruby on Rails to run on Ruby.NET and have started work on adding interoperability features to allow .NET programs written in other languages to conveniently use Ruby components and vice versa. We hope to include some of these features in the next public release.

Our plan now is to perform public releases more frequently, approximately once a month. Once we have stabilized the major design choices (including those required for interop) we will move to a more traditional open source type model where others can contribute directly to the code base. We expect this to happen in the second half of this year.


They do not have closures yet, so how will they run Rails? It would appear that the JRuby team is still much further ahead, but will the .NET people catch up? I look forward to playing around with the new Ruby.NET regardless, but it doesn't sound like it will be useful to me...yet.

Thursday, February 08, 2007

Switching Back To The Mac Side Of The Force

Once upon a time, I did really cool things at Apple Computer...

It was during the reign of Jobs the First, and all was well with the world. Except for the installed base of Macs, and trying to sell businesses on buying Macs. Shareholder were incensed, board members impatient.

Even after the coup, and various poorly executed attempts to rectify the situation by the imposters Scully and Gassee could not change, and the kingdom was greatly endangered. Many of us who bled in five colors left the kingdom for greener pastures where we could make our livings under the Pax Microsoft. I feared that someday from my new vantage, I would see the final end of the great dream.

But Jobs was brought back from exile, and in due course has returned the kingdom, not only to its former glory, but stong enough to challenge the Microsoft empire.

Diehard Windows users have seen the Vista, and rejected it for the Mac Way.

Look at the slow pace of innovation in the important areas of developer tools (how many years between releases?), and software rollouts in general. Combine this with the pointless MS-centricness. Why did Visual Studio 2005 have to reinvent well respected open source tools like NUnit and NAnt, with just different for difference's sake tools MSTest and MSBuild?

With so many troubles within the diehard loyalists, mercs, and vassals, the Microsoft Empire in clearly in decline. I have seen the future, and MS is really in grave trouble. Call me opportunist, but I for one, am switching back to Mac the first chance I get! I will run Windows XP SP2 under Parallels, and have the best of both worlds.

Iteration At Jet Speed

Jeff Atwood's blog has some excellent points about agile software development, based on a cool article by Roger Sessions from MSDN.

Sessions notes the concept of the iconoclastic Col. John Boyd that speed of iteration beats quality of iteration.

Boyd decided that the primary determinant to winning dogfights was not observing, orienting, planning, or acting better. The primary determinant to winning dogfights was observing, orienting, planning, and acting faster. In other words, how quickly one could iterate. Speed of iteration, Boyd suggested, beats quality of iteration.


Jeff Atwood riffs further on this idea:

You'll find this same theme echoed throughout every discipline of modern software engineering:


  • Unit tests should be small and fast, so you can run them with every build.

  • Usability tests work best if you make small changes every two weeks and quickly discard what isn't working.

  • Most agile approaches recommend iterations no longer than 4 weeks.

  • Software testing is about failing early and often.

  • Functional specifications are best when they're concise and evolving.


When in doubt, iterate faster.

Wednesday, February 07, 2007

Time For A Little Story

Brian Marick has a great example of how to break a software feature up into user stories.

Note how looking at smaller units of granularity make it so much easier to understand, then just trying to identify an entire feature all at once.

Also note how much value even the simplest pictures add to the stories. However, a picture is not enough. I personally love to see video of the whiteboard conversations for documenting the user stories.

Tuesday, February 06, 2007

RailsConf 2007 Will Have Good Beer

Portland has good beer. There, now I've said it. One of the key benefits of holding the RailsConf 2007 conference in Portland has to be easily obtaining really good beer.

The McMenamins on Broadway is the closest place to the convention center to go where "Classics such as raspberry-tinged Ruby, medium-bodied Hammerhead and dark, strong Terminator Stout are always available."

In between the fun of learning all about Rails 2.0, Capistrano 2.0, scalability, more scalability, still more scalability, let us not forget to take the time to drink a really good beer together! Or more than one, perhaps...

Update: It's official...here is the link for RailsConf on Beer

Friday, February 02, 2007

I Will Be At RailsConf 2007

I just checked my email, and saw that registration has just opened for RailsConf 2007. I went to last year's conference, and it was the most interesting and exciting event in the software industry I had been to in years!

If you are interested in going, I suggest that you register immediately. Last year's event sold out in a couple days. When they added 100 additional spots last year, those sold out in hours!

This year's is looking to be even more amazing...be there, or spend all your time reading blogs to figure out what happened!

Thursday, February 01, 2007

Telecommuting as energy saver

The Christian Science Monitor has an opinion piece called Telecommuting as energy saver which is nicely done.

Here are a few juicy excerpts:


This new work freedom, properly handled, has the power to transform business, government, and home life. Telecommuters – those who work at home or on the road with no office at all – now number between 28 million and 32 million, according to some estimates...

Cutting out that round-trip commute to the office – which averages about 23 miles – can save nearly $1,000 a year in gasoline and avoid putting more than 6,000 pounds of carbon dioxide into the atmosphere...

Recent hearings in Congress focused on telecommuting as a way to deal with traffic, terrorism, oil dependency, and global warming. Some participants noted that remote employees make it possible for offices to operate during a serious storm, terrorist attack, or other emergency.


That last point is especially interesting. Setting up a teleworkforce plan before disaster strikes is just good business. And once you have it setup, why not just execute on the plan NOW? Look at thoses stats on CO2 emmissions reduction!