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!