Advertisements

The Alexandria project (http://alexandria.rubyforge.org/), a project
to develop a book-and-other-media management application written in
Ruby for Gnome, is undergoing a minor renaissance after going dormant
for a while. Halted at version 6.1 since mid-2005, the project is
seeking to take the currently unstable repository code and release a
stable version 6.2 suitable for inclusion in major distributions. After
this release, the assembled development team will pursue ambitious plans
to increase the utility and visibility of Alexandria, with the ultimate
goal of default inclusion in major distributions. Some ideas that have
been discussed:
* integration with deskbar-applet/beagle.
* integration with OpenOffice for bibliography management.
* network-shareable book libraries (similar to iTunes DAAP)
* ability to access public library borrowing systems.
* new client/server architecture
* social/collaborative book rating/suggestion
Alexandria is an excellent example of a well-designed, fully-conceived
Ruby-Gnome2 application (thanks to the great work of Laurent Sansonetti and
others) that has the potential to match and surpass other closed-source
applications in this application niche, and to become a showcase product
for Linux/Gnome and Ruby-Gnome2.
The project currently needs Ruby developers of all shapes and stripes.
We welcome any short-term assistance to help us bugfix for the 6.2 release,
and any assistance and design input for the future.
In addition, there is a sub-project leadership position for anyone who
would like to resurrect the (already mostly implemented) RubyCocoa MacOS port
of Alexandria.
A first step if you are interested in helping is to introduce yourself on the mailing list:
http://rubyforge.org/mailman/listinfo/alexandria-list

Fixturease is a console-based Rails fixtures design tool which simplifies fixtures creation process greatly.
Gem installable
http://rashkovskii.com/articles/2007/1/17/easy-fixtures
http://rashkovskii.com/articles/2007/1/18/better-fixturease
I think my NubyGems series has gone over pretty well, so I figured I’d try my luck with something else.
This new series, digging deep, will be targeted towards the more experienced developer, or at least folks who want to know a little more about some deeper concepts in Ruby. I’m going to do what I can to make these as clear as possible, but I’m relying on input from gurus and skeptics to help improve these posts and make them a good resource for folks.
So this post will focus on a recent topic on RubyTalk, the merit of using Mixins as a suitable replacement for multiple inheritance.
If you haven’t worked with multiple inheritence before, or aren’t familiar with object oriented programming, this article isn’t going to be super helpful. However, as a quick review, the core concept of multiple inheritance is that an object can have more than one parent class. For example, perhaps you have a Student class, and you want to say Joe is a student, but he’s also a musician and a rubyist. Single inheritence would not let you have this kind of structure without awkward hackery, so multiple inheritence would make life easier.
Though I’m sure there are folks out there who can explain why Java’s interfaces help simplify things in some cases, this sort of thing is a notorious source of annoyance in Java. A lot of times single inheritance just doesn’t do the trick. So often when folks hear that Ruby is single inheritance, they get sort of nervous.
On the gripping hand, there are plenty of languages in which incorrect use of MI can really bite you. C++ and Perl would be common culprits, and I have to be honest, a ten foot pole isn’t long enough to keep me away from object oriented Perl 5.
Ruby I suppose is lucky enough to be able to happily steal good ideas and throw away the bad ones. With this in mind, I think the Mix-in idea really fits the language.
A short definition of a Module would likely be ‘a ruby class that cannot be instantiated and does not live within the class hierarchy’. It wouldn’t be 100% complete, but it’s enough to work with.
This at first sounds inconsequential. But the semantic power that such a construct provides is rather vast. David Black mentioned that he likes the idea of having both a noun like construct as well as an adjective like construct available for modeling.
That’s is a pretty good way to put it. This object is an Array. It is Enumerable.
If you look closely, you’ll see the distinction. The relationship is not really an ‘is a’ for the latter, but more describes some behavior the object has. It’s noun vs. adjective, when it all boils down.
For a quick example of modules in action, have a look at this use of Comparable. To get all your usual comparision operators(,==,>,=,>=,!=) in ruby, you just need to implement one method, the comparison operator(or spaceship).
>> class A
>> attr_accessor :data
>> def =>(other)
>> data => other.data
>> end
>> include Comparable
>> end
=> A
>> a = A.new
=> #
>> a.data = 78
=> 78
>> b = A.new
=> #
>> b.data = 10
=> 10
>> a b
=> false
>> a > b
=> true
>> b.data = 78
=> 78
>> a > b
=> false
>> a == b
=> true
Since Fixnums are Comparable, i can just delegate on down to get the right behavior. By including the Comparable module into my class, I get all those methods for free as promised.
This should be sufficient to show that we can avoid that interface problem. But it’s not going to tell you much about how mixins might save some headaches that MI introduce, so let’s get on to that, and luckily, this gives me an excuse to play with OmniGraffle.
It might be tempting to just box off the idea of mix-ins as a direct comparison to multiple inheritance, but that’d be a misconception. The core difference between multiple inheritance and single inheritance is the former turns your hierarchy into a digraph where the latter preserves a tree structure. Since Ruby is single inheritance, the use of mix-ins prevents the issues associated with a more loosely arranged network of paths.
Python 2.3 has a very good implementation of multiple inheritance, and this is mostly due to the fact that if a cycle forms in the graph, it is considered illegal. (Which helps make method resolution sane). Please refer to this paper if you’re interested in the details, as they’re a little beyond the scope of this article.
However, this might be best explained graphically. I’m not a particularly graphical person, so bear with me :)

So the graphs on the left are meant to represent a situation where the leftmost path from D to A is the ‘main path’, and the other paths represent orthogonal concerns. (Think of them of doing things similar to Ruby’s Comparable or Enumerable). On the right hand side, you see the same idea, but the overlapping orbs represent modules ‘mixed in’ to D.
One of these clearly has a single linear path back to the root. The other would depend on how your language implemented its method resolution. Hopefully you can look at this and abstract the idea that no matter what, even when we mix modules into other modules, the results are a single component with no hierarchy attached to it. In this way, introducing new modules is much less likely to cause conflicts than introducing new parent classes, considering that it is rare in complex systems to know the entire topology well enough to avoid problems. I’m pretty sure this is the biggest case for the mix-in model, and it’s tough to find many situations in which its capabilities fall short of multiple inheritance.
Basically, if you’re already familiar with modeling multiple inheritance in a sane way, the leap to mix-ins will be relatively small. However, if you’re new to the concept, it might take a little extra leap. Going back to David’s analogy, classes are our Noun component and modules our adjective.
Perhaps we have a Record construct and we want to be able to add tags to these records( a la folksonomy ). This is an ideal time to say an object with the ability to be tagged is Taggable, which is a nice adjective, and makes a nice module.
The following example is from Ruport’s source, and shows an actual use of modules:
module Ruport::Data
module Taggable
def tag(tag_name)
tags tag_name unless has_tag? tag_name
end
def delete_tag(tag_name)
tags.delete tag_name
end
def has_tag?(tag_name)
tags.include? tag_name
end
def tags
@ruport_tags ||= []
end
def tags=(tags_list)
@ruport_tags = tags_list
end
end
end
Nothing really surprising or fancy. However, both our Records and Tables are taggable, and they're not related to each other directly. This is what modules let us do, and it sure can be handy.
Hopefully this will bring folks who haven't been really thinking much about what modules are for closer to understanding how they work. Also, it might provide some insight for folks who are missing multiple inheritance, or for people who have been looking for a construct like this but didn't quite find it yet.
I hope this explanation has been helpful, but if you have questions, please do ask them. Also, if you have some suggestions on how to make this more clear or notice any mistakes, let me know as well. Hopefully future articles in this series will help expose some of the deeper concepts within Ruby to those who are interested!

Dear readers,
As you can see, Slash7 is almost back to its former beautiful glory. Once I write some custom liquid plugins for Mephisto to handle the rest of the sidebar, and customize some section templates, it’ll be all the way better… and perhaps even better than before.
So you wanna be a convert…
If you’re curious about switching from Typo to Mephisto, there’s never been a better time....
Check out Slash7 for more -- and let me know what you think!
What better way is there to learn than to look at what you shouldn’t do?
Lush isn’t just a nice word for “borderline alcoholic,” it’s the name of a global company. Lush makes its millions selling juicy bath-stuffs, shampoos, lovely soaps, and “bath bombs” which splutter bubbles and foam and tasty smells when dropped into water.
The Set Up
Let me start off by saying that the Lush stores and...
Check out Slash7 for more -- and let me know what you think!
I totally forgot to blog this!
http://rubyforge.org/projects/parsetree
ParseTree is a C extension (using RubyInline) that extracts the parse
tree for an entire class or a specific method and returns it as a
s-expression (aka sexp) using ruby's arrays, strings, symbols, and
integers.
http://rubyforge.org/projects/seattlerb
ruby2ruby provides a means of generating pure ruby code easily from
ParseTree's Sexps. This makes making dynamic language processors much
easier in ruby than ever before.
Changes:
heckle version 1.2.0 has been released!
http://www.rubyforge.org/projects/seattlerb by Ryan Davis and Kevin Clark
This one is huge. Heckle is turning into the test tool I always wanted for ruby.
Heckle is a mutation tester. It modifies your code and runs your
tests to make sure they fail. The idea is that if code can be changed
and your tests don't notice, either that code isn't being covered or
it doesn't do anything.
Now that rubygems are open again:
sudo gem install heckle
or, because you're a good person:
sudo gem update
What’s up with this job posting which demands a Gemini, Leo, Libra, Sagittarius or Aquarius?
The most ambitious Ruby on Rails project calls for a Rail’s guru to lead team as Co-founder
This is a wonderful entrepreneurial position for the humanitarian keen on facilitating emotional fulfilment for humanity.
*Birthday must fall between;
January 20 and February 18
May 21 and June 20
July 23 and August 22Sept. 23 and Oct. 22
November 23 and December 21
Is this a phenomenon common to Germany? I’m sorry, the stars just aren’t aligned for you to code for us today. (Seen on onslaught.)

A photographer took a picture of Steve Job’s booklet from his recent Macworld Keynote where he unveiled the iPhone.
Apart from the interesting way in which he organizes his thoughts, its also very interesting to see which parts of the presentation are scripted and which are not (ordering 4000 lattes is on the list). What strikes me is just how gorgeous the booklet looks however.
Luckily, a avid jobs fan over at digg took the opportunity to recreate a template for Apple’s Pages which makes it easy to create such booklets yourself.
Begins: Sat, 27 Jan 2007 at 11:00 AM
Ends: Sat, 27 Jan 2007 at 2:00 PM
Location:
Mall between 3rd and 7th Streets
Washington, DC 20002
USA
Link: more info
Mark your calendars, and let me know if you need a place to stay...

On the heels of the recent release galore here’s one more:
script.aculo.us 1.7 is final!—download away!
So what’s new? Basically, the new stuff is all about Effect.Morph and all the goodness you can read about here and here.
Of course, we’re on Prototype 1.5 final now.
As always, get the fine print from the CHANGELOG.
Now, if script.aculo.us only had an API documentation like the new one for Prototype. The wiki is great, but a more complete, up-to-date and coherent resource would be even better. Well, let’s see about that… ;)
Of course thanks to the contributors. And yeah, I know that there are quite a bunch of tickets and patches pending—let’s get this one out first and get all that love in the next version. :)
NOTE: This is not the version included in Rails 1.2.1.—. You can use this version with Rails 1.2.1, just download and overwrite the files provided by Rails! The next Rails release will include this, of course. :)

Blocks are one of Ruby’s greatest assets. Every newcomer to Ruby is immediately introduced to their power when they learn how to do basic iteration, but there is a more powerful aspect to blocks than that. They are invaluable in refactoring code to remove duplication. Consider the classic example of the difference assertions proposed by the Projectionists. You want to know whether a particular bit of code increases the number of rows in a particular table or not. The brute-force approach is not very DRY at all:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 |
def test_create_user
count = User.count User.create(...) assert_equal count+1, User.count end def test_delete_user count = User.count users(:jamis).destroy assert_equal count-1, User.count end # ad nauseam... |
By recognizing that the inner code is all that changes significantly, you can write a helper method that executes the outer code, and yields at the appropriate place(s):
| 1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
# from http://project.ioni.st/post/218#post-218 def assert_difference(object, method, difference=1) initial_value = object.send(method) yield assert_equal initial_value + difference, object.send(method) end def test_create_user assert_difference(User, :count) { User.create(...) } end def test_delete_user assert_difference(User, :count, -1) { users(:jamis).destroy } end |
This can be handy in a variety of situations. I recently was working on a method that did a bunch of setup and teardown, and in the middle it invoked find.
| 1
2 3 4 5 6 |
def find_with_extra_stuff(*args)
# a bunch of setup code here result = some_collection.find(*args) # a bunch of teardown code here return result end |
The problem was that I found myself wanting to do a variation on the find call, but with the exact same setup and teardown stuff. Rather than duplicate all the code, I refactored it into a separate method and used yield right there in the middle:
| 1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
def find_with_extra_stuff(*args) setup_with_extra_stuff { |collection| collection.find(*args) } end def setup_with_extra_stuff # a bunch of setup code here result = yield some_collection # a bunch of teardown code here return result end # this allows me to use that abstract method with any # method of the collection I want: setup_with_extra_stuff { |c| c.find_all_by_name("Joe") } |
Blocks rock.
I had previously been using rb_iterate and a call to Proc.new to build a block in C. But that takes two function calls while the undocumented rb_proc_new is just one.
require 'rubygems'
require 'inline'
module Kernel
inline do |ext|
ext.prefix %{
static VALUE sum(VALUE args)
{
return rb_funcall(rb_ary_entry(args, 0), rb_intern("+"), 1,
rb_ary_entry(args, 1));
return Qnil;
}
}
ext.c %{
VALUE sum_block()
{
return rb_proc_new(sum, 0);
}
}
end
end
p sum_block[13, 2]
p (0..20).inject(0, &sum_block)
Most of the time rb_iterate is what you need. But, you know, in case you actually want a Proc object.
I’ve written before about how cool it is to see the JRuby and rubinius guys working together (Nick Sieger also posted a piece about it). (It can be mind-bending to follow a discussion across multiple irc channels though.) I’m even more encouraged to see that Kevin Tew (the Cardinal hacker) and SASADA Koichi (the YARV hacker) have joined the fray.
In his recent post about tail call optimization for YARV on JRuby, Ola Bini wrote:
This work goes forward very fast, and it’s funny to see progress happen this quickly. Yesterday SASADA Koichi visited the #jruby and #rubinius IRC channels, and we had some very interesting discussions on further collaboration. The future looks bright indeed, and this weekend I’ll probably have time enough to take a first crack at a YARV compiler for JRuby.
What’s going to happen next? Maybe one of the big-name Perl folks will start answering questions on ruby-talk — naah, that’ll never happen.
(correction): fixed Upton Sinclair quote it is ’salary’ not ‘job’ (thanks for the correction)
Even with all the buzz, it is still a tough sell. If you’ve suggested Rails as an alternative to (Java|.NET) at work, you’ve probably experienced some reactionary pushback. Convincing a set of established “Enterprisy” engineers that Rails is worth paying attention to it is like convincing a Texas oil baron that he should purchase a Subcompact hybrid vehicle and become a Vegan. Why is convincing a highly paid (Java|.NET) programmer to look at Rails that difficult? I’ll steal a quote from Al Gore’s Inconvenient Truth that he, in turn, stole from Upton Sinclair:
“It is difficult to get a man to understand something when his salary depends on not understanding it.” - Upton Sinclair (1878 - 1968)
In an effort to convince, you may have sent people to some of the good Ruby on Rails blogs. This might have escalated the resistance. Asking your fellow enterprise developers to read DHH’s loudthinking.com, is like asking (the other) O’Reilly to sit down with Colbert - Mr. Enterprise isn’t going to appreciate the message because he’ll be focused on the ridicule. Rails, rightly so, is positioned as the challenger, and it makes good use of hyperbolic ridicule to gain converts. This works for most of us, but I’ve also seen it push some entrenched Java developers further away.
Common Responses
So, you are in “The Big Planning” meeting, and your boss says something like, “There is no time to finish this project, we’re going to have to tell the customer we won’t meet the deadline.” You wearily offer up the suggestion: “We might be able to deliver something on time if we used Rails to implement the web application”. And, an entire room full of Java programmers is now trying to tell you every reason from here to the North Pole why your suggestion is naïve. Here are some of the common responses:
Let’s take each one individually…read on…
Myth #1: Too Much Freedom
“My developers are not disciplined enough for a scripting language, we need the structure that a platform like .NET provides.”
Answer: If your developers really do lack discipline, then they should probably not be programming in something as complex as .NET. Or, Java, let’s take Java as an alternative, Java is a powerful language, but it is a language based on choice: you can create a web application using one of 30+ web frameworks, you can deal with persistence using Hibernate, iBatis, or just direct JDBC. And, if you are using the Spring Framework, you are really defining your own custom architecture as you go. If you need this level of flexibility, use Java, but, IMO, you have to be a bit more disciplined to create a good architecture in Java than you would to follow the bright lights in a Rails application.
The real answer to Myth #1: “If your developers are not very disciplined, you can’t afford to not be using a tool like Ruby on Rails. If your developers are disciplined enough to learn Struts + Spring + Hibernate + WebSphere, then I’m surprised you can’t expect them to learn ActiveRecord. Who are these people? I don’t believe you, what’s the real reason?”
Myth #2: Rails isn’t “Rigorous”.
Scripting languages do not provide an adequate level of “structure”.
“Our systems are serious and require a much more rigorous approach.”
Answer: Myth #2 is born of a belief that systems built-atop scripting languages can be difficult to maintain, and this Myth is closely related to Myth #1. The problem with this myth is that it has absolutely nothing to do with scripting languages and everything to do with a universal industry truth - Bad Code is Difficult to Maintain Regardless of the Language. Anyone who’s had an encounter with bad Perl code in the past is going to appeal to this myth, but the real truth is that, again, it is less a specific problem with Ruby and more a fear of the unknown. I’ve seen .NET systems designed with all the rigorous process-driven, test-first, pattern-inspired magic you will find, but they were still a quagmire of logic.
The other reason someone might offer this up is because they are frightened of not having compile-time type safety (or just frightened of not having a compiler at all). Compile-time type-safety isn’t so bad when we’re talking about the Solid Rocket Booster or a FIX gateway for the London Stock Exchange. But, with enough testing, this argument doesn’t make sense for something like a Web UI.
The real answer to Myth #2: “Right! Let’s go back to the customer and tell them that even though we could deliver something on time, we’re not going to because it’s not a rigorous technical solution and that our developers are not disciplined enough to program in Ruby on Rails. What makes Ruby less ’serious’ than Java? You guys could still draw UML diagrams of model objects to your heart’s content, and, if you really need me to, I could generate just as many gantt charts and word documents about the code we write in Ruby.”
Myth #3: Performance
“It just ain’t fast enough…”
Answer: What isn’t fast enough? Rails? Well optimize your deployment, figure out what a materialized view is. Think about the database a little bit, are you querying a table with 10 million rows? and do you know what an index is? Have you thought about database partitioning? Start using memcache, get faster hardware, use 40 instances of Mongrel. Don’t just stand there, fix it. You’d do the same for your .NET application. Myth #3 usually translates to, “I just don’t want to use Rails, and someone told me it isn’t fast enough.” In my experience Rails scales as long as you apply some brain power to your performance problems. If you just expect Rails to scale without taking any steps to achieve scaleability then you’ve really just staged a show trial for Rails. This myth is offered from people who want to Rails to break a leg out of the gate. If this is your reason, don’t tell me you didn’t have to go through a dog and pony show to optimize every other platform in your production network. Performance optimization is a black art regardless of the language or platform.
Compared to Java: From the perspective of real cost, the cost of scaling a Ruby application is on par with a similar Java application. It takes about the same hardware to scale a big J2EE application as it would take to scale a large Ruby on Rails deployment. We’re talking about a few commodity servers running Mongrel with lots of memory. IMO, it might be a lttle easier to setup Apache + mod_proxy + mongrel + Capistrano + memcached, than it is to go through the motions of installing JBoss or Tomcat and then dealing with the lack of OS integration that most Java servers suffer from. In other words, if you are creating an application and attempting to scale horizontally, you’ll probably end up paying just about the same $$ to scale a well designed Java app or a Ruby app (assuming your container is free). You may end up buying an extra one or two servers for your Ruby application, but you are going to make up the cost in development.
The real answer to Myth #3: “So, we’re not going to meet our deadline because you feel that Ruby on Rails just ‘isn’t fast enough’ in an abstract sense. You haven’t used it yet, we haven’t tested an application, or sized a real production deployment. No one has done an apples to apples comparison, all we’re going on now is your belief that Ruby doesn’t scale? Before you go on, let’s agree to at least study the issue, and the next time we talk let’s discuss specific numbers.”
Myth #4: Flexibility
“We can’t afford to follow the database naming conventions ActiveRecord demands”
Answer: You don’t have to use the ActiveRecord naming conventions. (I’ve heard this more than a few times, “we can’t use rails because of our database…”) Sure, it is marginally easier if your database tables follow the naming conventions, but let me assure you Rails can work with almost any database no matter how strange. To prove this I’ll use a Siebel database as an example. A Siebel database is definitely not designed for ActiveRecord. Every table has a MS_IDENT column which is the primary key….then every table has a ROW_ID column which happens to be the application specific identifier. Column names of the foreign keys do not match the names of the tables they references. Foreign keys don’t really reference the real primary key, they reference the application specific id which isn’t just a simple autoincrementing integer. There are hundreds of tables, and, my favorite, no define FK constraints. Did I mention that all of the table and column names are somewhat cryptic. It took a little bit of effort, a module and some before_create methods, but if I can get a Siebel database to work with Rails, you can use ActiveRecord with anything.
Compared to Java: …turn the tables on this one. EJB3 annotations in Java has the same “default naming assumption” behavior. If you don’t supply column names and table names, EJB3 will just assume them from the names of the columns and tables. If someone rules out Rails because of database naming conventions force them to hold Java (or .NET) to the same standard. Also, anyone who has been using Hibernate will tell you that Hibernate certainly has problems with oddly conceived databases - I’ve spent days trying to work with 3-way mapping tables in Hibernate only to find out that there’s some really mysterious bug with @MapKey.
The real answer to Myth#4: “You are mistaken. If you read more than the first 40-pages of the “Agile Web Development…” book, you would know this.”
Conclusion: When Reason Fails to Persuade…
Sneak it into the organization if your arguments fail. Eventually someone will notice, and there’s a good chance you’ll get in trouble. But, there’s always a chance that your transgression will go unnoticed and your boss can go on happily believing that he is using a “Real Platform”. J
But do us all a favor, if you are going to employ Rails behind hostile territory don’t turn into to one of those O’Reilly Radar-reading cool kids who is constantly throwing around references to Paul Graham and talking about how cool Web 2.0 is. Take your time, know your enemy, and work slowly. Use the language of your corporate masters
Wrong: “Ruby is a revolution, dude, it’s going to change the way you think about coding. Rails will run circles around your fancy SpringMVC or ASP.NET applications. Coding Rails is fun!”
Right: “Mr. Supervisor, sir, may I speak freely?”…..”I think we could leverage Ruby as a competitive advantage. For our next low-risk web application I propose that we engage in a feasibility study to assess the impact of a lightweight rapid application development framework. There is a real possibility that Ruby could encourage the productivity increase which will allow us to finish Q3 well under budget. It would be a great addition to our Enterprise’s ‘knowledge portfolio’.”
Today the Rails Core Team released Ruby on Rails 1.2. The long awaited new version is of course full of features and fixes. The thing we’re most excited about is the inclusion of ActiveSupport::Multibyte. But it doesn’t stop with multibyte support, Rails now ships with UTF-8 as a default in all parts of the framework, something we couldn’t have dreamed of a year ago.
by Robert Dober
Command Line Interfaces very often support command abbreviations The purpose of this quiz is to automatically dispatch to methods on unambiguous abbreviations, ask the user for clarification in case of ambiguous abbreviations and raise a NoMethodError in case of an abbreviation that cannot be matched to any command.
Behavior of other methods defined in a class shall not be altered.
Be creative about the interface and about behavior. I have OTOH defined a small test suite that makes assumptions about the interface and behavior. But the test suite is only there for your convenience.
What is said below applies to the test suite and shall in no way inhibit any alternative ideas.
ruby class Mine abbrev :step, :next, :stop abbrev :exit end Mine.new.e # should resolve to exit Mine.new.st # should prompt the user Mine.new.a # should still raise a NoMethodError
Abbreviation targets themselves are not expanded.
ruby class Nine abbrev :hash abbrev :has end Nine.new.ha # => [:hash, :has] Nine.new.has # => NoMethodError class Nine def has; 42; end end Nine.new.has # => 42
In order to allow for automated testing the test code shall not prompt the user in case of an ambiguous abbreviation but return an array containing all (and only all) possible completions as symbols. Note that the test suite sets the global variable $TESTING to a true value for your convenience.
The aforementioned Rails Cookbook from O’Reilly, to which I made a minute contribution, has been released… including Rails 1.2 relevant content like ActiveResource and RESTful development.
Go getcha one.
(Here is a full TOC for the curious amongst you)
A few weeks ago I got a call from O’reilly publishing asking me to write the REST chapter introduction for their upcoming Rails Cookbook. Apparently, some people found my effusive soliloquy on Rails’ upcoming Active Resource and Simply RESTful support actually useful and thought I could reproduce my intellectual facade for them.
After the first stab, in which I found out that writing a blog entry does not an author one make, I think I got something useful to them. But beyond my meager contribution I got to take a look at the rest of the book. I’ve always been a fan of the cookbook format and this looks to be no different. A lot of tasty recipes including some great post-development stuff like performance, security and deployment.
You can check out the rough cuts version at O’Reilly now or wait a lil bit until it hits bookshelves – which Amazon says will be Dec. 1st. Look for the book that has some sort of stray feline with a killer rash on its stomach…
And don’t forget the original entrant in the Rails cookbook market, Chad Fowler’s Rails Recipes.
tags: rubyonrails, rails, rails cookbook, REST
by Bob Showalter
(Taken from the puzzle by William Wu at http://www.ocf.berkeley.edu/~wwu/riddles/cs.shtml)
[Editor's Note: This was also a code golf problem a few months back: http://codegolf.com/oblongular-number-spirals --JEG2]
Write a Ruby program to print out a "spiral" of numbers that fill a NxN square. Your program will take a single argument to specify the dimensions of the square (1 or higher). The number zero represents the center of the spiral, and the succeeding integers spiral out in a clockwise (or counterclockwise; your choice) direction from the center until the square is filled.
Your program should write the output line by line, without using an array to build up the data first.
Here's the output for an 8x8 spiral:
56 57 58 59 60 61 62 6355 30 31 32 33 34 35 3654 29 12 13 14 15 16 3753 28 11 2 3 4 17 3852 27 10 1 0 5 18 3951 26 9 8 7 6 19 4050 25 24 23 22 21 20 4149 48 47 46 45 44 43 42
Much of the beauty of ActiveRecord associations is in the collection methods that are provided for you when you define has_many relationships.
For instance, when we say:
class Organization < ActiveRecord::Base
has_many :people
end
We now have an organization.people method that returns the collection of associated people within the organization. Easy enough. We also get nice little methods on the collection of people like organization.people<<, organization.people.build, organization.people.create and organization.people.find (among others). Well what if you wanted to define your own method on this auto-magically provided collection method? You do this through Association Extensions which let you define methods to add to the collection. You can define an association extension either with a block or a module – we’ll use a block provided to the has_many call here as it’s the most common way to do so:
class Organization < ActiveRecord::Base
has_many :people do
def find_active
find(:all, :conditions => ["active = ?", true])
end
end
end
I’ve defined a find_active method which will retrieve all people in the organization that have the active column set to true. This can be invoked very intuitively with:
organization.people.find_active
This is a great way to provide convenience finder methods for common retrievals on the associated collection.
If you want to define an extension as a module just provide the :extend option in your has_many definition:
module FindActiveExtension
def find_active
find(:all, :conditions => ["active = ?", true])
end
end
class Organization < ActiveRecord::Base
has_many :people, :extend => FindActiveExtension
end
You can customize to your heart’s content – these are just some simplistic examples of how to plug into this nifty feature. I just recently stumbled upon it and thought it might be worth spreading the word since I found myself smitten by it.
tags: rails, activerecord, rubyonrails

Duane Johnson and Neal Harmon are a programmer at and the president of FamilyLearn, a small company using Ruby, Rails, and Amazon's S3 and EC2. They've ported their applications from PHP to Ruby on Rails, and have recently started a Public Beta of their iMemorybook tools. I've invited them to share some of their experiences in this interview.
To start things off, would you two please tell us

rubypodder is a very simple podcast aggregator in the spirit of bashpodder. Feedback welcome.
Added support for GNU style options.
Better docs (now on rubyforge).
Some minor bug fixes.
Happy versionday to Duby! Today's menu: faster, faster, and prettier. I am starting to lack icing on the cake.
RubyRoom is ready. Just You, Your Text, and Yourself. Perfect for concentration.
RubyRoom is a fullscreen text editor (using gtk2 for the interface) with as less distractions as possible.
rcodetools is a collection of Ruby code manipulation tools for automagic Test::Unit(RSpec) assertion generation, code annotation, 100% accurate code completion, code and documentation browsing, precise method information (rcodetools is meta-programming aware)...
rcodetools can be used with any editor, but it ships with emacs and vim support.
More info at http://eigenclass.org/hiki.rb?rcodetools
RDIL is a Domain-Specific Language for Requirements Definition and Illustration. Initial source, tests and specs imported on RubyForge SVN.
ruby2ruby version 1.1.4 has been released!
ruby2ruby provides a means of generating pure ruby code easily from
ParseTree's Sexps. This makes making dynamic language processors much
easier in ruby than ever before.
Changes:
== 1.1.4 / 2007-01-15
* 4 minor enhancements:
* Added some extra rewriting code and tests for various bmethods. Ugh.
* Added support for splatted block args.
* Refactored class/module and dsym/dstr.
* Short if/unless statements are now post-conditional expressions.
* 4 bug fixes:
* Finally fixed eric's nebulous proc code-in-goalposts bug.
* Fixed dasgn_curr so block's dasgn vars decl goes away (bug 7420).
* Fixed dmethod. I think the tests were bogus before.
* Fixed improper end in method rescues (bug 7396).

Nathan de Vries recently posted a neat tip for using Capistrano to determine whether or not your remote machines have all your expected dependencies installed. We could have used something like this recently at work when we were having some strange issues that turned out to be due to some out-of-date dependencies on a few of our boxes. Good stuff! I love seeing the things people are doing with Capistrano.
Ruby does not support multiple-inheritance. Personally, I have mixed feelings about that, but the fact of the matter is, you can accomplish almost exactly the same thing using modules.
Consider this ActiveRecord scenario. In Basecamp, we allow files to be attached to both messages, and comments. One way to do this would be to have both messages and comments inherit from a common ancestor, via single-table inheritance. Alas, the two models (in our case) are different enough that STI is not a viable option here.
Instead, we employ “concerns” (as David has started calling them). A “concern” is simply a module that we mix in to both the message and comment models, which sets up the common “file attachment” functionality. We’ll call this module “Folder”, to denote that any of its clients essentially become a container for files. Observe:
| 1 2 3 4 5 6 7 8 9 10 11 |
module Folder
def self.included(base) base.has_many :files, :as => :owner, :dependent => :destroy end # This returns the path where files are to be uploaded # for this specific "folder". def attachment_path "/path/to/files/for/#{id}" end end |
Then, we mix the Folder concern into whichever models we want to allow files to be attached to:
| 1 2 3 4 5 6 7 8 9 |
class Message < ActiveRecord::Base include Folder #... end class Comment < ActiveRecord::Base include Folder #... end |
Because of the included hook, defined in the module, each class that receives this module will automatically gain a “has_many :files” association. Also, because the module is mixed into the class, you can put as much or as little extra functionality there as you want to share between the classes.
This has proven to be a very powerful pattern. To accommodate it, we’ve recently taken to creating an “app/concerns” directory in our projects, and adding that to the load path in config/environment.rb:
| 1 |
config.load_paths += %W(#{RAILS_ROOT}/app/concerns) |
Our modules then go in that directory.
This is mainly a big fix release. The 0.9.0 release had a bad app skeleton. I have fixed this problem.
I also added support for freezing the merb framework into your app for portability. Just deploy the entire app and no need to install the merb gem on your server.
A few refactors and updates go in as well. Gem install merb in a few hours when the gem propogates.

Qtodo version 0.2 has been released. It features nice color-coding to quickly see which tasks are late, postponing of a whole tree (don't abuse it ;-) !), several improvements in the text editor and in the way settings are stored from one session to another.
Enjoy !
Ever since the initial announcement of the documentation effort, we’ve been busy planning and preparing Prototype for its rebirth. Along with the official 1.5 release, we’d like to welcome you to the official home of Prototype. This site will serve as the center of our community and help developers everywhere become familiar with Prototype and its continued progress.
We’ve been squashing some nasty bugs getting ready for the 1.5 release. You can get the full scoop on all the fixes and improvements in the CHANGELOG.
While there has always been some great documentation on Prototype, we’ve been the victim of a famous quote from *“The Man Who Shot Liberty Valance”:
When the legend becomes fact, print the legend.
We’re moving past those times, however. We’ve worked really hard to fully document the API. This is something we’ll be improving over time, but it’s a great start. Here are some of the features:
The documentation site has guessable URLs. For instance, if you’re looking for documentation on Element.show, then you can find that documentation at a url like: http://prototypejs.org/api/element/show. If you’re looking for Form.Element.focus you can find it at: http://prototypejs.org/api/form/element/focus.
Each Object has its own atom feed. This opens the doors for integrated documentation. For instance, if you want the XML file for Form.Element, you can find it at: http://prototypejs.org/feed/api/form/element/atom.xml. This feed will always contain the most up-to-date documentation for Form.Element.
We’ve also added an article section where you can find tips, tutorials, and a variety of articles for Prototype. We plan on adding many more articles to this area over time, so keep your eyes peeled.
We’ve added three new core members to our team. Chris, Mislav, and Tobie were already avid contributors to Prototype, and they were the driving force behind the documentation effort. We all worked really hard on it, but these guys deserve most of the credit.
We’re not perfect, so if you catch any spots in the documentation that are incorrect, or if you’d like to improve parts of the documentation shoot one of us an email. We’ll try to get an official email posted later so you can send in improvements or additions to the documentation. Until then, please enjoy the site!
Update: Rails 1.2 has been announced and includes Prototype 1.5 with the release! Congrats to the Rails team.

Since we’re all celebrating new releases, it seems only fair to point out that Haml, an alternative markup format to Rails’ RHTML templates, has reached the lofty version of 1.0. It even comes with a plugin for seamless integration with Rails applications, so you really have no excuse not to give it a try. If you’re looking for an alternative to RHTML, Haml may just be you. Check it out!

The simplest way to deploy your application and tie that release to a specific Rails version is to put Rails in your vendor directory as an svn:external dependency. That’s fine, but it’s not very efficient, and Mike Clark has posted an excellent writeup of the alternatives. If you’ve been wondering if there is a better way, you could do a lot worse than to read what he’s got to say.
Good stuff, Mike!

Prototype 1.5 shipped together with Rails 1.2 today. But that’s not all that’s been happening at the JavaScript sugar mill. Today also marks the official unveiling of prototypejs.org. A brand new site dedicated to promoting and teaching Prototype. It comes complete with API documentation, a blog, and a guide on how to contribute. Congratulations to Sam, Justin, and the rest of the team behind the site.
Get out your party balloons and funny hats because we’re there, baby. Yes, sire, Rails 1.2 is finally available in all it’s glory. It took a little longer than we initially anticipated to get everything lined up (and even then we had a tiny snag that bumped us straight from 1.2.0 to 1.2.1 before this announcement even had time to be written).
So hopefully it’s been worth the wait. Who am I kidding. Of course it’s been worth the wait. We got the RESTful flavor with a new encouragement for a resource-oriented architecture. We’re taking mime types, HTTP status codes, and multiple representations of the same resource deadly serious. And of course there’s the international pizzazz of multibyte-safe UTF-8 wrangling.
That’s just some of the headliner features. On top of that, there’s an absolutely staggering amount of polish being dished out. The CHANGELOG for Action Pack alone contains some two hundred entries. Active Record has another 170-something on top of that. All possible due to the amazing work of our wonderful and glorious community. People from all over the world doing their bit, however big or small, to increase the diameter of your smile. That’s love, people.
Get out your party balloons and funny hats because we’re there, baby. Yes, sire, Rails 1.2 is finally available in all it’s glory. It took a little longer than we initially anticipated to get everything lined up (and even then we had a tiny snag that bumped us straight from 1.2.0 to 1.2.1 before this announcement even had time to be written).
So hopefully it’s been worth the wait. Who am I kidding. Of course it’s been worth the wait. We got the RESTful flavor with new encouragement for resource-oriented architectures. We’re taking mime types, HTTP status codes, and multiple representations of the same resource serious. And of course there’s the international pizzazz of multibyte-safe UTF-8 wrangling.
That’s just some of the headliner features. On top of that, there’s an absolutely staggering amount of polish being dished out. The CHANGELOG for Action Pack alone contains some two hundred entries. Active Record has another 170-something on top of that.
All possible due to the amazing work of our wonderful and glorious community. People from all over the world doing their bit, however big or small, to increase the diameter of your smile. That’s love, people.
As always, you get a hold of the latest and greatest through gems:
gem install rails --include-dependencies
...or if you prefer to freeze it straight up, you can:
rake rails:freeze:edge TAG=rel_1-2-1
If you go with the gems, remember to change your version binding in config/environment.rb. Otherwise, you’ll still be tied to whatever old version you were using before.
Do note, though, that this is a massive upgrade. A few major components of Rails were left for scraps and entirely rewritten (routing and auto-loading included). We’ve tried our very best to remain backwards compatible. We’ve run multiple release candidate sessions to everyone help achieve that goal.
But it may not be perfect — heck, what is — so you’d be best advised to give your application a full and thorough work-out before contemplating a deployment. But of course, you’ve been such a good little tester bee that all what is needed is a single “rake” to see if everything passes, right?
How to get started learning all about Rails 1.2
With the fanfare out of the way, I point your attention to a rerun of the RC1 release notes on the new features. This rerun only contains the highlights, though. Real fans will want to peruse the CHANGELOGs themselves from the API.
For everyone else, there’s of course also the much easier path of just picking up the second edition of Agile Web Development with Rails. This edition was written to be spot on with 1.2 and contains a lot more elaborate guidance than you’ll find in the CHANGELOGs.
So it’s no wonder that the 2nd edition sold out the 15,000 copies of the first print run in a mere three weeks. Rest assured, though, the second run should already be available in stores. And for instant gratification, nothing beats picking up the PDF+Book combo off the Pragmatic book site.
REST and Resources
REST, and general HTTP appreciation, is the star of Rails 1.2. The bulk of these features were originally introduced to the general public in my RailsConf keynote on the subject. Give that a play to get into the mindset of why REST matters for Rails.
Then start thinking about how your application could become more RESTful. How you too can transform that 15-action controller into 2-3 new controllers each embracing a single resource with CRUDing love. This is where the biggest benefit is hidden: A clear approach to controller-design that’ll reduce complexity for the implementer and result in an application that behaves as a much better citizen on the general web.
To help the transition along, we have a scaffold generator that’ll create a stub CRUD interface, just like the original scaffolder, but in a RESTful manner. You can try it out with “script/generate scaffold_resource”. Left with no arguments like that, you get a brief introduction to how it works and what’ll create.
The only real API element that binds all this together is the new map.resources, which is used instead of map.connect to wire a resource-based controller for HTTP verb love. Then, once you have a resource-loving controller, you can link with our verb-emulation link link_to "Destroy", post_url(post), :method => :delete. Again, running the resource scaffolder will give you a feel for how it all works.
Formats and respond_to
While respond_to has been with us since Rails 1.1, we’ve added a small tweak in 1.2 that ends up making a big difference for immediate usefulness of the feature. That is the magic of :format. All new applications will have one additional default route: map.connect ':controller/:action/:id.:format'. With this route installed, imagine the following example:
class WeblogController < ActionController::Base
def index
@posts = Post.find :all
respond_to do |format|
format.html
format.xml { render :xml => @posts.to_xml }
format.rss { render :action => "feed.rxml" }
end
end
end
GET /weblog # returns HTML from browser Accept header
GET /weblog.xml # returns the XML
GET /weblog.rss # returns the RSS
Using the Accept header to accomplish this is no longer necessary. That makes everything a lot easier. You can explore your API in the browser just by adding .xml to an URL. You don’t need a before_filter to look for clues of a newsreader, just use .rss. And all of them automatically works with page and action caching.
Of course, this format-goodness plays extra well together with map.resources, which automatically makes sure everything Just Works. The resource-scaffold generator even includes an example for this using format.xml, so /posts/5.xml is automatically wired up. Very nifty!
Multibyte
Unicode ahoy! While Rails has always been able to store and display unicode with no beef, it’s been a little more complicated to truncate, reverse, or get the exact length of a UTF-8 string. You needed to fool around with KCODE yourself and while plenty of people made it work, it wasn’t as plug’n’play easy as you could have hoped (or perhaps even expected).
So since Ruby won’t be multibyte-aware until this time next year, Rails 1.2 introduces ActiveSupport::Multibyte for working with Unicode strings. Call the chars method on your string to start working with characters instead of bytes.
Imagine the string ‘€2.99’. If we manipulate it at a byte-level, it’s easy to get broken dreams:
'€2.99'[0,1] # => "\342"
'€2.99'[0,2] # => "?"
'€2.99'[0,3] # => "€"
The € character takes three bytes. So not only can’t you easily byte-manipulate it, but String#first and TextHelper#truncate used to choke too. In the old days, this would happen:
'€2.99'.first # => '\342'
truncate('€2.99', 2) # => '?'
With Rails 1.2, you of course get:
'€2.99'.first # => '€'
truncate('€2.99', 2) # => '€2'
TextHelper#truncate/excerpt and String#at/from/to/first/last automatically does the .chars conversion, but if when you need to manipulate or display length yourself, be sure to call .chars. Like:
You've written <%= @post.body.chars.length %> characters.
With Rails 1.2, we’re assuming that you want to play well with unicode out the gates. The default charset for action renderings is therefore also UTF-8 (you can set another with ActionController::Base.default_charset=(encoding)). KCODE is automatically set to UTF-8 as well.
Watch the screencast. (but note that manually setting the KCODE is no longer necessary)
Unicode was in greatest demand, but Multibyte is ready handle other encodings (say, Shift-JIS) as they are implemented. Please extend Multibyte for the encodings you use.
Thanks to Manfred Stienstra, Julian Tarkhanov, Thijs van der Vossen, Jan Behrens, and (others?) for creating this library.
Routes
Action Pack has an all new implementation of Routes that’s both faster and more secure, but it’s also a little stricter. Semicolons and periods are separators, so a /download/:file route which used to match /download/history.txt doesn’t work any more. Use :requirements => { :file => /.*/ } to match the period.
Auto-loading
We’ve fixed a bug that allowed libraries from Ruby’s standard library to be auto-loaded on reference. Before, if you merely reference the Pathname constant, we’d autoload pathname.rb. No more, you’ll need to manually require 'pathname' now.
We’ve also improved the handling of module loading, which means that a reference for Accounting::Subscription will look for app/models/accounting/subscription.rb. At the same time, that means that merely referencing Subscription will not look for subscription.rb in any subdir of app/models. Only app/models/subscription.rb will be tried. If you for some reason depended on this, you can still get it back by adding app/models/accounting to config.load_paths in config/environment.rb.
Prototype
To better comply with the HTML spec, Prototype’s Ajax-based forms no longer serialize disabled form elements. Update your code if you rely on disabled field submission.
For consistency Prototype’s Element and Field methods no longer take an arbitrary number of arguments. This means you need to update your code if you use Element.toggle, Element.show, Element.hide, Field.clear, and Field.present in hand-written JavaScript (the Prototype helpers have been updated to automatically generate the correct thing).
// if you have code that looks like this
Element.show('page', 'sidebar', 'content');
// you need to replace it with code like this
['page', 'sidebar', 'content'].each(Element.show);
Action Mailer
All emails are MIME version 1.0 by default, so you’ll have to update your mailer unit tests: @expected.mime_version = '1.0'
Deprecation
Since Rails 1.0 we’ve kept a stable, backward-compatible API, so your apps can move to new releases without much work. Some of that API now feels like our freshman 15 so we’re going on a diet to trim the fat. Rails 1.2 deprecates a handful of features which now have superior alternatives or are better suited as plugins.
Deprecation isn’t a threat, it’s a promise! These features will be entirely gone in Rails 2.0. You can keep using them in 1.2, but you’ll get a wag of the finger every time: look for unsightly deprecation warnings in your test results and in your log files.
Treat your 1.0-era code to some modern style. To get started, just run your tests and tend to the warnings.
Kevin Clark: This might be the longest post with the least substance I’ve read in a long time. Why would you use this space to tout your history? How did you get post access on the O’Reilly Ruby Blog?
Let the blogging contests begin!!
We’ve worked really hard getting the official Prototype site up and running and it’s finally here, not to mention we’re also releasing 1.5!

I have it on authority that working on something like Shopify is tons of fun. Now you can experience the thrill as well ;)
They give you a 30 days deadline which should be plenty. Considering that some people can write something like Shopify in C in a few days
this should be plenty.

Prototype users, your days of longing and sexy (and not-so-sexy) nail-biting are over... There's now an official site. With docs. Yes, docs! Loads of them!
Congrats (and a huge thanks!) to all the folks who made it happen.
Check out Slash7 for more -- and let me know what you think!

Prototype 1.5.0 has arrived. Besides tons of additions, this release marks the unvealing of the all-new Prototype site, available at:
Thanks to the heroic efforts of foremost Justin Palmer and the rest of the Prototype core team we now present complete API docs, one of the things that has been missing from this great library.
Enough talk, head over to the official site to read the details, and get Prototype 1.5.0 today.
Don’t forget to digg this.
It seems Mr. Webb had it out for me and has bestowed upon me the 5 things meme. I’m not that interesting, but here goes.

ActiveRecord’s associations let you specify just about every option that ActiveRecord#find accepts. Want your account’s people returned in sorted order? Just specify ”:order => ‘name’” in the association.
| 1 2 3 |
class Account < ActiveRecord::Base
has_many :people, :order => "name" end |
What could be simpler? Alas, there are all kinds of hidden pitfalls in this approach.
Note that any query scoped by that association is going to use that order, whether you need (or even want) it or not. One consequence of this is that if your scoped find uses an index that doesn’t include the sort key (“name”, in this case), you’re going to be taxing your database unnecessarily. Let’s assume that your “people” table has an index on “account_id” and “name”, so that the default query is nice and performant:
| 1 2 3 4 5 6 7 8 9 10 11 |
# SELECT * FROM people WHERE (people.account_id = 1)
# ORDER BY name account.people # SELECT * FROM people WHERE (people.account_id = 1 # AND (admin = 1)) ORDER BY name account.people.find(:all, :conditions => ["admin = ?", true]) # SELECT * FROM people WHERE (people.account_id = 1) # ORDER BY role, name account.people.find(:all, :order => "role") |
Note that last example, in particular. Specifying a sort order in a scoped query appends to the sort order of the scope. In other words, the query will now work the database harder, unless you just happen to have an index on all three of “account_id”, “role”, and “name”. There is not (currently) an easy way to reach into the parent’s scope and alter (or even “switch off”) the existing order.
This gets even uglier if your association happens to specify a default :include clause:
| 1
2 3 |
class Account < ActiveRecord::Base has_many :people, :include => :email_addresses end |
Now, if you try and scope the query, the scope will always inherit the requirement that the email_addresses table must be joined in. Now, sometimes you want that join. But all the time? On every scoped query? Are you sure? Not only does this make your database work harder (since queries involving multiple tables require more work than queries against a single table, in general), but it increases the risk of name clashes if you specify conditions or order keys without fully qualifying the table names:
| 1
2 3 4 5 6 7 |
# May cause problems if email_address also have a 'role' column account.people.find(:all, :order => "role") # The safer way to do it, but you wouldn't know that # unless you were well acquainted with how the people # association is defined. account.people.find(:all, :order => "people.role") |
So, what are your options? I would recommend doing like I’ve discussed in other articles, and like Koz and I have pointed out on The Rails Way: either set up a separate association that includes the sorts and includes, or use an extension method. Then, you can use the unadorned version of the association to do your scoped queries safely and efficiently, having a much better idea of what they are going to be doing to your database.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class Account < ActiveRecord::Base
# Option #1, using a second association. Allows you to do: # account.people # account.people_by_name has_many :people has_many :people_by_name, :class_name => "Person", :order => "name" # or, using extension methods, you can do: # account.people # account.people.by_name has_many :people do def by_name @by_name ||= find(:all, :order => "name") end end end |
Either way, you can rest easily knowing that the vanilla “people” association will let you query the database without any scoped assumptions about order. In fact, the only assumption you’ll get at all is the assumption that the query needs to include the “account_id” comparison.
Which is right.
Finally, the much anticipated RubyGems version 0.9.1 is now available.
This release includes a number of new features and bug fixes.
The most important change in RubyGems 0.9.1 is that RubyGems no longer allows files to be installed outside of the installation directory. A separate security bulletin with full details will be posted shortly.
RubyGems 0.9.1 is a required update. The RubyForge gem repository will soon disallow installation by older versions of RubyGems. Manual installation will still be allowed.
While require_gem was deprecated in 0.9.0, the bin stubs are still using it (oops!). To get rid of the warnings printed by rake or other bin stubs simply run 'gem pristine --all'.
Major changes include:
Minor changes include:
many proxy installation improvements
gem cert improvements
RubyGems is now easier to use as a library
extension building enhancements
error reporting enhancements (less odd exceptions)
require now loads .jar files
Bug fixes:
RubyGems is a package management system for Ruby applications and
libraries. RubyGems' one command download makes installing Ruby software
fun and enjoyable again.
Many gems are available for download from the RubyForge site. Browse
the list of gems with a "gem list --remote" command and download what
you need with a simple "gem install <name-of-gem>". RubyGems takes care
of the details of installing, not only the gem you requested, but also
any gems needed by the software you selected.
If you are interested in finding out when new gems are released, I
maintain an RSS feed at http://onestepback.org/gemwatch.rss.
If you have a recent version of RubyGems (0.8.5 or later), then all
you need to do is:
$ gem update --system # you might need to be admin/root
$ gem pristine --all # ... here too
(Note: You may have to run the command twice if you have any previosly
installed rubygems-update gems).
If you have an older version of RubyGems installed, then you can still
do it in two steps:
$ gem install rubygems-update # again, might need to be admin/root
$ update_rubygems # ... here too
$ gem pristine --all # and here
If you don't have any gems install, there is still the pre-gem
approach to getting software, doing it manually:
For RubyGems 0.9.2 the RubyGems team is looking to add:
Contributors to this release include:
Anatol Pomozov, Gavin Sinclair, David Lee, Ryan Davis, Robert James, Chris Morris, Sylvain Joyeux, Sava Chankov, Tom Pollard, Kevin Clark, Andy Shen.
Keep those gems coming!
Today, the International Kayak Consortium celebrates Camping (a Microframework)’s 1st birthday. They have honored the paragraph of code by awarding it the Annual First Place in Birthdaying Special Day Award and So Brave.
The commissioner of kayaking LeBrock Mitchell gave an acceptance speech on behalf of Camping at this morning’s banquet. His sentiments were brief, but stirring:
I have written two speeches for today, a long one and a short one. However, the pages for both got wet inside my kayak. Yes, I tried blow-drying them. But as I held that that cylinder of hot air, I realize that I couldn’t say anything as brief as Camping itself.
And he held up a printout of Camping from trunk and he wept exactly 4k of tears. We, in fact, measured with a graduated cylinder.
Here is Camping today.
%w[active_support markaby tempfile uri].map{|l|require l}
module Camping;Apps=[];C=self;S=IO.read(__FILE__).sub(/S=I.+$/,'')
P="Cam\ping Problem!";module Helpers;def R(c,*g);p,h=/\(.+?\)/,g.grep(Hash)
(g-=h).inject(c.urls.find{|x|x.scan(p).size==g.size}.dup){|s,a|s.sub p,C.
escape((a[a.class.primary_key]rescue a))}+(h.any?? "?"+h[0].map{|x|x.map{|z|C.
escape z}*"="}*"&": "")end;def URL c='/',*a;c=R(c,*a)if c.respond_to?:urls
c=self/c;c="//"+ [at] env [dot] HTTP_HOST+c if c[/^\//];URI(c)end;def/p;p[/^\//]?@root+p :
p end;def errors_for o;ul.errors{o.errors.each_full{|x|li x}}if o.errors.any?end
end;module Base;include Helpers;attr_accessor:input,:cookies,:env,:headers,:body,
:status,:root;def method_missing*a,&b;a.shift if a[0]==:render;m=Mab.new {},self
s=m.capture{send(*a,&b)};s=m.capture{send(:layout){s}} if /^_/!~a[0].to_s and m.
respond_to?:layout;s end;def r s,b,h={};@status=s;@headers.merge!h;@body=b end
def redirect*a;r 302,'','Location'=>URL(*a)end;Z="\r\n";def to_a;[@status,@body,
@headers]end;def initialize r,e,m;e=H[e.to_hash];@status,@method,@env,@headers,
@root=200,m.downcase,e,{'Content-Type'=>"text/html"},e.SCRIPT_NAME.sub(/\/$/,'')
@k=C.kp e.HTTP_COOKIE;q=C.qsp e.QUERY_STRING;@in=r;if%r|\Amultipart/form-.*boun\
dary=\"?([^\";,]+)|n.match e.CONTENT_TYPE;b=/(?:\r?\n|\A)#{Regexp::quote("--#$1"
)}(?:--)?\r$/;until [at] in [dot] eof?;fh=H[];for l in@in;case l;when Z;break
when/^Content-D.+?: form-data;/;fh.u H[*$'.scan(/(?:\s(\w+)="([^"]+)")/).flatten]
when/^Content-Type: (.+?)(\r$|\Z)/m;fh[:type]=$1;end;end;fn=fh[:name];o=if
fh[:filename];o=fh[:tempfile]=Tempfile.new(:C);o.binmode;else;fh=""end;while l=@in.
read(16384);if l=~b;o<<$`.chomp;@in.seek(-$'.size,IO::SEEK_CUR);break;end;o<<l
end;C.qsp(fn,'&;',fh,q) if fn;fh[:tempfile].rewind if fh.is_a?H;end;elsif@method==
"post";q.u C.qsp(@in.read)end;@cookies,@input= [at] k [dot] dup,q.dup end;def service*a
@body=send(@method,*a)if respond_to?@method;@headers["Set-Cookie"]= [at] cookies [dot] map{
|k,v|"#{k}=#{C.escape(v)}; path=#{self/'/'}"if v!=@k[k]}-[nil];self end;def to_s
a=[];@headers.map{|k,v|[*v].map{|x|a<<"#{k}: #{x}"}};"Status: #{@status}#{Z+a*Z+
Z*2+@body}"end;end;X=module Controllers;@r=[];class<<self;def r;@r;end;def R*u
r=@r;Class.new{meta_def(:urls){u};meta_def(:inherited){|x|r<<x}}end;def M;def M
end;constants.map{|c|k=const_get(c);k.send:include,C,Base,Models;r[0,0]=k if
!r.include?k;k.meta_def(:urls){["/#{c.downcase}"]}if !k.respond_to?:urls}end;def
D p;r.map{|k|k.urls.map{|x|return k,$~[1..-1]if p=~/^#{x}\/?$/}};[NotFound,[p]]end
end;class NotFound<R();def get p;r(404,Mab.new{h1 P;h2 p+" not found"})end end
class ServerError<R();def get k,m,e;r(500,Mab.new{h1 P;h2"#{k}.#{m}";h3"#{e.class
} #{e.message}:";ul{e.backtrace.each{|bt|li(bt)}}}.to_s)end end;self;end;class<<
self;def goes m;eval S.gsub(/Camping/,m.to_s).gsub("A\pps=[]","Cam\ping::Apps<<\
self"),TOPLEVEL_BINDING;end;def escape s;s.to_s.gsub(/[^ \w.-]+/n){'%'+($&.
unpack('H2'*$&.size)*'%').upcase}.tr(' ','+')end;def un s;s.tr('+',' ').gsub(
/%([\da-f]{2})/in){[$1].pack('H*')}end;def qsp q,d='&;',y=nil,z=H[];m=proc{|_,o,n|o.u(
n,&m)rescue([*o]<<n)};q.to_s.split(/[#{d}] */n).inject((b,z=z,H[])[0]){|h,p|k,v=un(p).
split('=',2);h.u k.split(/[\]\[]+/).reverse.inject(y||v){|x,i|H[i,x]},&m}end;def
kp s;c=qsp(s,';,')end;def run r=$stdin,e=ENV;X.M;k,a=X.D un("/#{e[
'PATH_INFO']}".gsub(/\/+/,'/'));k.new(r,e,(m=e['REQUEST_METHOD']||"GET")).Y.
service *a;rescue Object=>x;X::ServerError.new(r,e,'get').service(k,m,x)end
def method_missing m,c,*a;X.M;k=X.const_get(c).new(StringIO.new,H['HTTP_HOST',
'','SCRIPT_NAME','','HTTP_COOKIE',''],m.to_s);H.new(a.pop).each{|e,f|k.send(
"#{e}=",f)}if Hash===a[-1];k.service *a;end;end;module Views;include X,Helpers
end;module Models;autoload:Base,'camping/db';def Y;self;end;end;class Mab<
Markaby::Builder;include Views;def tag!*g,&b;h=g[-1];[:href,:action,:src].map{
|a|(h[a]=self/h[a])rescue 0};super end end;H=HashWithIndifferentAccess;class H
def method_missing m,*a;m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m]:raise(
NoMethodError,"#{m}")end;alias_method:u,:regular_update;end end
More recently:
Update: If all of you can get out your copy of the Camping core team’s group picture, Indian Chief Skittles McQueeny has just sent me the following legend:

Update from Air Force Staff Sargeant Guds Mandragon:

We try to keep a lid on it, but some pilot folklore has infiltrated our ranks. The tale goes that if you eject from your plane on Camping’s birthday that you will be visited in the night by a red fairy who will grant you a free batch of caramel apples, answering to any quantity you provide. In some permutations of the rumor, she grants an infinite quantity. Four aircraft have been ditched, two have struck earth, one crushing a cereal factory. I am told Grape Nuts. Please dispell this rumor forthrighly.
Hmm, interesing stuff. Thanks, Guds!
Update: 
Update: The latest Camping trunk lets you add a query string to your routes by adding a Hash argument.
>> a "version 2", :href => R(Show, page.title, :version => 2)
=> "<a href='/wiki/title?version=2'>version 2</a>"

Why Not Find?
After posting FindInCode, someone legitimately asks: “Why not just use Find?”
Good question! Find is a Ruby supplied module to recursively search
directories. So why not use it instead of Rake. Then your script
won’t have a dependency on Rake.
Well, in short:
egrep is a FileListgrep methodThe find version has one advantage over the Rake version in that it
does not need to pull in the entire list of files into memory at once.
That may be important to you.
Here’s the original version again:
require 'rake'
FileList["**/*.rb"].egrep(Regexp.new(ARGV.first))
And here is the Find version:
require 'find'
RE = Regexp.new(ARGV[0])
Find.find('.') do |fn|
next if fn =~ /(^(\.svn|CVS)$)/
next unless fn =~ /\.rb$/
open(fn) do |file|
lines = 0
file.each do |line|
lines += 1
puts "#{fn}:#{lines}:#{line}" if line =~ RE
end
end
end
James Edward Grey II points out that my find example could use a
little makeover. First, the regex that causes .svn
directories to be skipped is incorrect, it only skips the actual
directory, not the contents of the directory. Removing the ”$” from
the match will fix that, but he provides a better solution. Replace
that entire line with:
Find.prune if fn =~ /(^(\.svn|CVS)$)/
I totally forgot about prune.
A minor correction is the use of the lines counter. He
suggests either using each_with_index (I should have
thought of that), or better yet, use file.lineno.
Thanks James!
I’ve been exploring using Rake as a Ruby Library.
Lately, I’ve been experimenting with using Rake as a normal library in
regular Ruby scripts (rather than in Rakefiles). It turns out there
are some very useful things you can do.
For example, to locate a particular piece of code in a not so small
Ruby project, I often use the following command line:
$ find . -name '*.rb' | xargs grep -ni "snippet of code"
This quickly searches all my Ruby files and displays matching lines
with file names and line numbers. However, the line is long to type
and won’t work in windows (unless you have cygwin installed).
So I wrote the following Ruby program and saved it in a file called “fic” (Find In Code):
#!/usr/bin/env ruby
require 'rake'
FileList["**/*.rb"].egrep(Regexp.new(ARGV.first))
This proved so useful, that I enhanced the code to allow for searching
for files ending in arbitrary extendsions and to handle more matching
options on the command line.
Here’s the enhanced version:
#!/usr/bin/env ruby
# -*- ruby -*-
exts = ['.rb']
if ARGV[0] =~ /^\.[a-zA-Z0-9]+$/
exts = []
while ARGV[0] =~ /^\.[a-zA-Z0-9]+$/
exts << ARGV.shift
end
end
ext = "{" + exts.join(',') + "}"
if ARGV.size < 1
puts "Usage: #{File.basename($0)} [.ext ...] pattern ..."
exit 1
end
require 'rake'
FileList["**/*#{ext}"].egrep(Regexp.new(ARGV.join('|')))
If you are using Emacs, and you have my “visit source” code loaded,
all you need to do is put the cursor on the line you are interested in
and press F2.
Oh, you would like to see the elisp code for “visit source”? Let’s
see, where did I put that?
$ cd .elisp/
$ fic .el jw-visit-source
ini/ini-cust.el:131:(defun jw-visit-source ()
ini/ini-zkeys.el:7:(global-set-key [f2] 'jw-visit-source)
Now, I move the cursor to the first line and press F2, and I find:
;;; Source File Visiting =============================================
(defun jw-current-line ()
"Return the current line."
(let
((bol (save-excursion (beginning-of-line)(point)))
(eol (save-excursion (end-of-line)(point))))
(buffer-substring bol eol) ))
(defun jw-extract-file-lines (line)
"Extract a list of file/line pairs from the given line of text."
(let*
((unix_fn "[^ \t\n\r\"'([<{]+")
(dos_fn "[a-zA-Z]:[^\t\n\r\"'([<{]+")
(flre (concat "\\(" unix_fn "\\|" dos_fn "\\):\\([0-9]+\\)"))
(start nil)
(result nil))
(while (string-match flre line start)
(setq start (match-end 0))
(setq result
(cons (list
(substring line (match-beginning 1) (match-end 1))
(string-to-int (substring line (match-beginning 2) (match-end 2))))
result)))
result))
(defun jw-select-file-line (candidates)
"Select a file/line candidate that references an existing file."
(cond ((null candidates) nil)
((file-readable-p (caar candidates)) (car candidates))
(t (jw-select-file-line (cdr candidates))) ))
(defun jw-visit-source ()
"If the current line contains text like '../src/program.rb:34', visit
that file in the other window and position point on that line."
(interactive)
(let* ((line (jw-current-line))
(candidates (jw-extract-file-lines line))
(file-line (jw-select-file-line candidates)))
(cond (file-line
(find-file-other-window (car file-line))
(goto-line (cadr file-line)) )
(t
(error "No source location on line.")) )))
Uncle Bob has a couple examples of why performance tuning almost
always has surprises in store for you.
Bob Martin (Uncle Bob)
relates
a couple of stories on performance tuning and why your expectations
are nearly always wrong.
The moral of the story … measure, measure, measure whenever you have
a performance problem. The root cause is prabably not where you
expect it to be.

This is exciting. I have been wanting to talk about this for some
time. Well, the time has finally come and I’m happy to announce that
the Pragmatic Programmers are putting together a series of regional
conferences called The Rails
Edge.
The conference will be a single track, so all the speakers at the
conference will be available for interaction at all the talks, not
just during their own presentation. The speaker selection is great (I
feel humbled to be a member of the group). We are hoping that it will
a dynamic experiance with the speakers interacting, not only with the
audience, but with the other members of the staff.
So, if you didn’t make it into the “Lucky 250” club going to RubyConf
this year, here is another chance to meet and greet Rubyists in your
area.
I hope to see you there.
Update: You can read the official Pragmatic Programmer’s Announcment too.
The Ruse wiki software gets some updates.
I’ve been really pleased with the way Ruse has been handling wiki
related spam on the Ruby Garden site. Now that Ruse has been deployed
for a while, I’ve tweaked a few things to make it even easier to clean
up spam.
One technique that has proved very useful in preventing spam is the
content filtering that Ruse is able to do. We download the “bad url”
list from chonqged.org nightly and will reject all posts URL that
match that list. Currently, we can add additional URLS to the
blacklist by editting a configuration file on the server. Future
versions of Ruse might add a web interface to the local blacklist.
We had some fireworks on the 4th of July … Unfortunately
they weren’t the usual kind.
It is a tradition in the US to fire off fireworks on the 4th of July
in celebration of Independence day. Well, the Weirich household had
some fireworks, but it’s not what you would expect.
What we thought at the time was a really loud firecracker from the
neighbors turned out to be a close lightening strike, probably hitting
the phone line. I discovered later that my DSL router (attached to
the phone line) was dead (as in no lights, no power).
After a picking up a new DSL router on Wednesday from the phone
company, it still didn’t connect and the phone company promised to
send a technician out one Friday. Arrgh! Three days with no
internect! Sigh.
The technician arrives Friday, checks out the wiring and decides to
upgrade the “system”. Part of the upgrade is another new DSL router
(different model from the replacement unit I picked up Wednesday). We
connect up the laptop to the DSL router and everything looks great.
So once the phone guy leaves, I start hooking up the rest of the
network: firewall router, network hub, wireless base station, and the
other computers in the house.
And nothing works.
It looks like the lightening not only took out my DSL router, but it
also got the firewall, network hub and wireless base station.
Fortunately, I have another firewall and hub in my spare parts box.
I’m not certain of the total extent of the damage yet. The cables
running to the other computers in the basement seem to be bad now
(tested by against my working laptop). Since I don’t have long enough
replacement cables, I haven’t checked out the network cards in two of
the computers yet.
I am a bit surprised by the cables going bad. I understand delicate
electronic equipment fried by lightening, but the cables are just
wires and connectors. For them to be bad must mean the strike was
strong enough to short them out somehow. And that doesn’t sound good
for the network cards at the other end of the cable. Sigh.
On the good side, the my desktop computer that sits right next to the
network equipment is up and running on the network. So one would that
the network card in it is ok. However, it does seem to be a bit slow
when browsing web pages. I mean really slow. I timed it against
my laptop. What loads two seconds on my laptop takes over 20
seconds on the desktop. But that sounds more like a network
configuration error than a hardware issue. Sigh, more work to do.
At any rate, it looks like there will be a run to the local computer
store soon.
Several people have been having RubyGems issues.
Several people have been reporting problems where RubyGems doesn’t
find a gem on RubyForge, or gives other strange errors. It seems
there was a gem on RubyForge that gave the Gem indexing software some
headaches. And as a result, the gem index was corrupted. If you
downloaded the corrupt index, then you may be experiencing strange
problems as well.
The good news is that the problem is easy ot fix. Just delete the gem
index file. You can find it in the directory reported by the “gem env
gemdir” command. For example:
$ gem env gemdir
PATH_TO_DEFAULT_GEM_REPOSITORY
$ rm PATH_TO_DEFAULT_GEM_REPOSITORY/souce_cache
Where PATH_TO_DEFAULT_GEM_REPOSITORY is your default gem repository.
If you run on a Unix system, you default gem repository is probably
non-writable from your regular user account. In that case, you will
need to use “sudo” (or its equivalent) on the “rm” command. You will
probably also have a secondary writable cache in your .gem directory
that you will want to delete.
$ rm $HOME/.gem/source_cache
The next time you run gems, will will refresh the cache by downloading
the index from scratch.
We Need Proposals
David A. Black is asking for
proposals
for RubyConf 2006. If you have an idea for a talk, please feel free
to propose it for the conference (and you can use this
page). The deadline is June 30th,
so don’t delay.
RubyConf has always been one of my favorite conferences to attend. If
you are thinking going, then consider this my personal invitation
to attend. I hope to see you there.
It’s a bit hard to dig up, but I did figure out how to do UDP packet multicasting in Ruby.
I’ve been playing around with some network peer to peer discovery
techniques and wanted to try some of them out in Ruby. The trick to
self discovery is the ability to send network packets without knowing
the address of the receiver. To do this, you either have to broadcast
or multicast.
Because broadcasted packets are received by every device on the local
network, it is generally considered good manners to not use
broadcasted packets.
Multicasting, on the other hand, is only received by hosts that
explicitly express an interest in the multicast address. Although
abuse of multicasting is still bad manners, it is a better option than
broadcasting.
The IP addresses 224.0.0.0 through 239.255.255.255 are reserved for
multicast messages. Simply sending a UDP messsage to an address in
that range is sufficient.
One minor refinement is to set the TTL (Time To Live) option on the
socket. My understanding is that this controls how far the packet is
propagated. As polite net-citizens, we don’t want our multicast
packets travelling too far abroad, so we set the TTL value to 1 (we
need the ugly packing stuff because the value is passed directly to
the C level setsockopt() function with no interpretation by
Ruby).
So the Ruby code to send a multicast message is:
require 'socket'
MULTICAST_ADDR = "225.4.5.6"
PORT= 5000
begin
socket = UDPSocket.open
socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, [1].pack('i'))
socket.send(ARGV.join(' '), 0, MULTICAST_ADDR, PORT)
ensure
socket.close
end
Receiving a multicast message is a bit tricker. Since multicast
messages are generally ignored unless someone has explicitly
registered an interest in a particular address, there is a bit of
setup that needs to be done.
Here’s the code for receiving multicast messages:
require 'socket'
require 'ipaddr'
MULTICAST_ADDR = "225.4.5.6"
PORT = 5000
ip = IPAddr.new(MULTICAST_ADDR).hton + IPAddr.new("0.0.0.0").hton
sock = UDPSocket.new
sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ip)
sock.bind(Socket::INADDR_ANY, PORT)
loop do
msg, info = sock.recvfrom(1024)
puts "MSG: #{msg} from #{info[2]} (#{info[3]})/#{info[1]} len #{msg.size}"
end
The tricky part was figuring out the right setsockopt options and
values needed to register interest in our multicast address. I had to
do a little reading in the Unix man pages on the C level
setsockopt() function call. The third option to the C
function is a structure that contains two 4-byte IP addresses. The
first IP address is the multicast address, and the second IP address
is the address of the local host adapter that we wish to use to listen
for the multicast. The 0.0.0.0 address means use any of the local
network adapters. IPAddr handles parsing the human readable form of
the IP address and returns a string of 4 bytes in the order needed by
the C level setsockopt() function.
Save the above code in files named send.rb and
rcv.rb. In one console window, type:
ruby rcv.rb
In another console window on the same or different machine (on the
same local network), type:
ruby send.rb This is a test.
For more fun, bring up several receive windows and all will receive
the messages send by the send script.
I can think of all kinds of fun things to do with this.
I added the Time To Live option on send.
When I checked the wiki last night, I found that over 100 pages had been updated.
So I started checking out exactly what had changed. It seems that almost
all changes were by a single anonymous individual. Over the coourse
of 7 hours he touched over 100 pages and reverted them to the earliest
possible version. What’s up with that?
It may not be spam, but it certainly counts as destructive behavior.
So, I threw him in the tarpit and all his changes into the tarit. In
20 seconds I wiped out his seven hours of hard work.
I hope he had a good day. I certainly did.
And in other news, we have a new Ruse Wiki logo:


Thanks to Ed Burnette for this link.
I gave what turned out to be a slightly controversial keynote
at RailsConf. In it, I pointed out that people (like me) who can use
Rails on green-field projects are incredibly privileged. We get to code
using cool technologies in an incredibly agile, reactive environment,
producing applications that just work.
But, at the same time, there are a whole lot of people who don’t get
to enjoy the world of Rails.
I see these people regularly: I talk at No Fluff symposia around the
country, a great set of shows aimed at Java developers. I’m the
outsider, normally giving a full day’s worth of talks on Ruby and
Rails. And, in a way, it makes me sad to do it, because I often see folks
get really excited about the possibilities present in Rails only then to
realize that they’ll be going back to work on Monday with no real
hope of using what they’d just seen. These folks come to me during
the breaks and talk about how bad their world currently is, and how much
better it would be if only they could use Rails. If only…
Sometimes, the things that block these people are not technical issues:
companies have policies dictating that all work is done in Java (or .NET,
or whatever). But many times the road blocks are technical. In their
particular environment, with legacy code and legacy databases, they need to
be able to do things that Rails just doesn’t support out of the
box—more complex schemas, staged deployment, and so on.
So, in my keynote, I asked a simple question. Can we, as a community, do
anything to make the lives of these developers easier. Can we find a way of
bringing them in out of the cold?
Clearly, I believe the answer is yes. As I said in Chicago, the answer is
not to change Rails. Instead, the answer is to use the fact that Rails is
based on Ruby, and Ruby gives developers incredible power to extend
existing code in directions not anticipated by the original developers. I
asked the community to consider creating extensions to Rails to allow
currently disenfranchised developers to join the party.
This seems to have touched people’s nerves. Some have reacted
violently against the idea, others have welcomed it. It’s an
interesting, although ultimately sterile, debate. If people need changes to
Rails, Ruby will let them do it.
An interesting example is Greg Houston’s recent blog post, Let
ActiveRecord support Enterprise Databases. (Uh oh! He used the
enterprise word). He describes a problem he faces trying to use
Active Record migrations to maintain a legacy schema. The database-neutral
migrations didn’t give him the kind of control he needed, so his post
describes how he extended Active Record to do what he wants (including a
very simple but nicely powerful trick to make migrations spit out SQL,
rather than execute it). And, importantly, he did all this as a regular
user of Rails: he didn’t need any changes to the framework or any
endorsement of his work by the core team. (He does, however, make a good
point at the end of his post. If Active Record had an extension API it
would make it easier for these kinds of plugins to survive changes to the
core code base.)
Greg’s post is a basic experience report: he took what he needed from
Rails, extended it where necessary, and solved a business problem. By
blogging, he’s shown other developers just how to solve this category
of problem. A .NET developer needing to manage a legacy SqlServer schema
could read his post and realize that something that seemed impossible in
Rails is actually fairly easy. One more person can join the party.
You could argue that the stuff in Greg’s post is just a simple matter
of coding. There’s nothing stopping any .NET developer downloading
Rails and making the simple changes he’s suggesting.
But the reality is that you have to have a good idea that this kind of
thing is possible before you invest time in the exercise. If you’re a
Java or .NET developer looking for salvation, and you spend some time
looking at Rails, you’ll currently come across a lot of information
explicitly telling you that Rails is never going to address the issues you
face—Rails is explicitly not "enterprise." And so
you’d move on. And you’d be missing an incredible opportunity.
And this is one of the challenges I’d like us, the Rails and Ruby
communities, to address. While keeping the Rails core focused on new ways
of writing web applications, I’d like others of us to find ways of
educating corporate software developers, showing them that they can also
bring our technologies into their daily lives—using Ruby as an enterprise glue
language and Rails as a viable enterprise web development platform.
Should Rails be everything to everyone?
No.
Should Rails be "marketed" as a replacement for J2EE or .NET?
God forbid.
But there are a whole group of people out there who could be using
Rails now but aren’t, simply because they don’t know that it is
up to their challenges. And I’d like to try to help these folks.
Let’s not be the only people having fun.
I’m about 3 weeks into the rewrite of the Active Record chapters for
the new Rails
book. In the book, I try to demonstrate Active Record with real, live
code. At the same time, I don’t want to run every single piece of
code in the context of a Web application. So, I use Active Record
stand-alone, without having the rest of Rails loaded. All my demonstration
files start:
require "rubygems"
require_gem "activerecord"
and then include a call to establish_connection to connect to the
database.
At this point, I’m up and running, and I can play with all the Active
Record functionality. But… I still wanted to create tables in the
underlying database. In the first edition, I used DDL to do this, but in
the second I wanted to use migrations.
My first hack was to use the fact that the various schema definition
methods are defined both for migrations and in every database connection
object. That let me use the following in my code:
ActiveRecord::Base.connection.instance_eval do
create_table children, :force => true do |t|
t.column :parent_id, :integer
t.column :name, :string
t.column :position, :integer
end
end
I was pretty chuffed with this until Jamis Buck (who else) pointed out a
more elegant way:
ActiveRecord::Schema.define do
create_table children, :force => true do |t|
t.column :parent_id, :integer
t.column :name, :string
t.column :position, :integer
end
end
As I see more and more people start to use Ruby (and Active Record) as
enterprise glue, being able to bring these kinds of Rails goodies to
non-Rails applications is a win all around.
A couple
of blog posts ago, I commented on the dangers of converting database
decimal columns into Ruby floats. And, five months early, Santa
delivers. In the Rails trunk, numeric and decimal database columns with a
scale factor are now converted into Ruby BigDecimal objects. If the scale
factor is zero, they instead become integers.
Migrations now support decimal columns too, with the addition of two new
attributes, precision and scale.
add_column :orders, :price,
:decimal, :precision => 8, :scale => 2
I just spent a day reworking all the Depot chapters to use this, and it
seems to work great. (And, no, the updated PDF isn’t released yet.
I’m also half-way thought the ActiveRecord chapter rewrite, and need
to get that finished before the next release.)
I’d be interested to hear[1] from folks currently using BigDecimal
for financial calculations. Is there a preferred rounding mode? Any
gotchas?
In the meantime, thanks core team.
LtU has a link to Pluvo, a language which seems like a
cross between Python, JavaScript, Ruby, and Lisp. It has some interesting
ideas (coordination is a fun one) and the basic system (written in Python)
is currently less than 50k to download.
In the second edition of AWDwR, I changed
the Depot application to store money in integral cents, rather than
floating point dollars and cents. Some folks pushed back on this, saying it
overly complicated the application.
This morning, while working on some code to migrate some legacy data, I
bumped into a problem that boiled down to the following (on my
PPC—your results may differ)
dave[store/migrate 9:00:57] irb
irb(main):001:0> Integer(77.85 * 100.0)
=> 7784
Obviously it’s possible to do rounding (although even that’s
trickier than you might first code if you have to handle negative numbers).
I still feel that Rails should convert decimal(x,y) columns into
BigDecimal format in Ruby, giving us scaled, exact, representations. Until
that day, stick with integers for amounts that you need to be exact.
RailsConf 2006 is in its final day,
and I just realized that I hadn’t blogged on Rails Guidebook.
The Guidebook was a preconference event. For a day before the conference
proper started, attendees got an introduction to all the stuff that’d
be hearing about in the following days. It was a combination of a tutorial
and a glossary. We didn’t charge. Instead, the cost of admission was
a contribution to charity.
This is wonderful stuff, and Mike and I thank everyone who made it
possible: the Ruby Central folks who agreed to add a day to the agenda, Jay
Zimmerman for organizing the facilities, the core team members and other
experts who turned up to help, Mike and Nicole for doing all the Guidebook
logistics, and, more importantly, the folks who turned up and contributed.
If you’re already organizing a conference, adding a guidebook day
ahead of it isn’t a great incremental cost. So, here’s a
challenge to conference organizers. Let’s start a tradition of these
types of charitable events. Let’s make a point of sharing some of our
success with others. Not only does it do some good—it’s fun.
Back in the old days of computing—those days where I could
still see my knees when standing up—folks used to talk about
languages such as Perl as glue languages. What did they
mean?
Well, Perl is a great general purpose programming language. But it
is exceptional at doing something that no previous language could
do well: Perl made it easy to glue together other stuff. Data,
programs, external systems—all these things could be
integrated using Perl. Thanks to its integration with the
underlying operating system, and its amazing support for text
processing, Perl made a name for itself as an integrator par
excellence. Want to take the last 20 lines of an error log,
convert them to HTML, and upload the result to your web server? Perl
could do that in a handful of lines of code. Need to screen-scrape a
book's sales rank from Amazon and writing it into a local MySQL
database. Perl to the rescue.

Perl let us glue stuff together. It was magic.
But there was a problem. Perl is a great language. It was my
scripting language of choice before I discovered Ruby. But even on
my most charitable days I could never really claim that these Perl
programs were exemplars of readability. And, in turn, this lack of
readability made it hard for me to pick one of them up six months
after I'd written it and make some change—even small
alterations could involve long periods of head-scratching as I tried
to work out exactly what the entries in my hash of arrays of
hash references9 actually contained.
As a result, I found that the longer it was since I last looked
at a program, the harder it was to maintain and extend it. The
programs effectively became less malleable and more viscous. It
became stickier; I got mired in a gooey mess of details. Leave a
program long enough, and I'd often decide to rewrite it rather than
attempt some piece of surgery: the program had become totally
inflexible.
The glue had set.
Now Ruby is also a glue language. Just like Perl, Ruby works and
plays incredibly well with external data, resources, and programs. I
can do everything with Ruby that I used to do with Perl—I can
use it to integrate all kinds of stuff just as easily as I used to
be able to with Perl. But, there's a major difference. I've
discovered that, over time, my Ruby programs stay malleable and easy
to change. Ruby is the glue that doesn't set.
That's all very well, but what does writing little utility scripts
have to do with real-world web programming? A whole lot, as it turns
out.
As we move into a world where the network is the computer,
applications change in character. Rather than writing free-standing
islands of code, developers are increasingly writing programs that
knit together other, existing web resources. Want to annotate a map
with pictures of famous landmarks? Maybe you'll want to use the
Google Maps and Flikr APIs to carry most of the load for you. Want
to let your readers know when their product has shipped? Why not
generate the information as RSS and let their aggregator client do
all the gruntwork of displaying the result? As we move forward, more
and more of our applications will be less and less like one-man
bands and more like orchestra conductors.
Our applications are increasingly becoming glue code. And, if that's
the case, I'd rather write them using a glue that doesn't set over
time.
Mike Clark has
announced The Rails
Edge, a set of small, regional Rails conferences. The first will
be November 16-18 in Denver.
I'm really pleased with the way he's put these together. He's
selected a stellar group of speakers, all with deep, practical Ruby
and Rail experience.
Then he's organized it as a single track event. I know this was a
hard decision. But having one track means that everyone shares the
experience, and everyone can build on each session during the breaks
and in the evenings. It means we have a critical mass of folks, and
all the more experience to share.
And what I like most of all is the instructions he's given the
speakers. Unlike events where one person speaks and the other
speakers head off to pick up e-mail and work on projects, Mike is
encouraging the Edge speakers to participate in all the talks. If
Mike's talking, you might find yourself sitting next to Chad Fowler
or core-team member Marcel
Molina, Jr. If someone asks an Ajax question that Mike doesn't
feel comfortable handling, Stu
Halloway or Justin
Gehtland might field it from the floor.
As a speaker, I love this format--it means we're all part of the
same team. Having other people around to help out lets me go
both deeper and broader into stuff. I'm really looking forward to
these events.

It was standing-room only at Mike Clark's Capistrano talk: one of
the first talks at this
year's RailsConf. Latecomers stole
chairs from other rooms and fought their way to some free floor space
to hear Mike talk about the way we deploy Rails applications.

I'd just finished giving the first keynote. One of my topics was
making deployment in Rails easier and more amenable to corporate
use. I suspect from the interest in my talk, followed by the
overwhelming interest in Mike's talk, that deployment will be one of
the hot Rails topics of the coming year.

While I was being lazy Scott went ahead and posted a great write-up of the new Simply Helpful plugin that makes a few view-level operations more concise. Go ahead and check it out.
I gave a short and not-very-well-prepared demo of rela.tv at the Raleigh Ruby Brigade last night that generated a few inklings of interest amongst the crowd. And I use the word “interest” generously. However, I’ve been meaning to open-source the app for awhile now since I rarely find the time to play with it anymore – if for nothing else than to see if somebody else wants to use it as a learning tools as I did and try to further its functionality.
This comes with the disclaimer that I am not proud at all of the state of the code, and especially the state of the tests. Look at this as more of an opportunity for improvement than for a model by which all others should be based.
So, if you’ve got some interest in hacking away at a cool little Rails project – let me know. I’d love to see this get taken forward a few steps…
https://saucyworks.devguard.com/svn/projects/rela.tv/trunk
Don’t know what rela.tv is? Check out the overview for a summary.
tags: rela.tv, xfn, rails, rubyonrails
Oh, and somehow I forgot to mention this, but comments, people!
I cooked up a little anti-spam magic inspired by Pastie, so I'm not going to be afraid anymore! Of course, I'm subscribed to its feed now, so if anything stinky does start to happen, I'm totally going to be on top of things.

This plugin provides a simple solution for lookup fields - those cases where you just want to store a single text value, but also want to:
a) restrict the possible options and
b) be able to reflect on the possible options.
You could say it's an ActiveRecord implementation of 'enumerations' using a normalised db structure

Suck-o-meter. Brian Oberkirch lists 11 ways to tell if your product or service sucks. Let’s check back in June, and see how people fell about it.
Scary, but true. If planes were built like software.
A little ironic. Bruce Tate: “The Java community’s obsession with static type checking is curious because Java developers are now spending [...]

A comment that seems to be coming up a lot is: "Where are the docs?". Let's detour briefly from testing and talk about docs (okay, it won't be a complete detour ...):
What plans do you have to get solid user and developer level docs for rubinius?
Wilson: In the near future, one of us will kick out a big shiny diagram of all of the moving parts of Rubinius. I like diagrams. Particularly shiny
This time around, we're talking about cooperation between JRuby and rubinius developers. It's a timely topic, since Nick Sieger is starting a Serial JRuby Interview. Good times.
Evan wasn't available this time around ... I understand he's in seclusion working on rubinius' Garbage Collection. I'd rather have him get that right than respond to these — I think you'll agree.
I've been really
This week's episode hits three points; Evan's next steps with rubinius, garnet (the new name for cuby), and Software Transactional Memory (STM). MenTaLguY joins us for the third discussion, and provides a long list of resources to help get up to speed. Happy reading, and happier hacking!
Evan, after hiding out in your secret lair to hack on the newly released GC, what's next on your coding

Lots of refactoring, major cleanup. This is probably the last beta release before 1.0.
Also, I'm hopefully going to begin work on RubyCAS-Server.
*CAS is a central authentication (single signon) system for web applications. RubyCAS-Client is a Ruby client library for this protocol.

Easy Family Portal is the easiest way to keep in touch on the web. The system includes an address book, photo gallery and family news.
Version 0.6 standardizes most of the forms for site consistency. This version also includes Lightbox for the photo album viewer. Finally, there are three new skins to choose from to give your site a new look and feel.
Check out http://efp.rubyforge.org for full details!
Handoff provides a fluent interface for making assertions about simple delegation. The goal of the project is to make specifying delegation in unit tests as easy as implementing it with Forwardable--and even more readable.
See an example at http://handoff.rubyforge.org/.
But you can’t find much info on the subject? Stay tuned to this little teaser to learn ActiveResource in a live, real-world scenario.
This is part 3 in our ongoing conversation tracking the development of JRuby.
Official Rails support in February? That’s not far away! What do you mean by “official”?
Thomas Enebo: Largely, we just want to spend some extra TLC on fixing up various Rails issues between now and February. Basically, get rid of the remaining known issues with running Rails from JRuby. I think beyond marshalling we are very close to saying that today. We also want to provide a better deployment picture for Rails by then. So we will need to spend some time on that as well (the community has been doing a great job spearheading this).
Software is never perfect, so we know that there will continue to be Rails issues after we say it is supported. By setting this goal, we should give ourselves some pressure to polish what we have and also get a larger number of people some incentive to kick the tires.
Ola Bini: That’s a question of interpretation. In my view, “official” is some kind of high number. 95% of all test cases in 1.1.6, maybe? But the more important part of it is that all the common use cases should work. You should be able to work through AWDwR and everything should work.
It’s ambitious, but we can do it. What’s needed soon is to decide what needs to be done with ActiveRecord-JDBC, and do that, since AR-JDBC is one of the larger points in our Rails support, and sometimes I feel that the support there is our weak link.
Charles Nutter: We could probably say we support Rails today, with a whole list of caveats. Rails runs right now, people are using JRuby on Rails today (in some cases for production apps!), and things largely will “just work”. There’s also a lot of community effort behind alternative deployment scenarios like within a WAR file or behind a fast HTTP server like Grizzly. Rails does run on JRuby today.
Our challenge before making a big official announcement about “Rails support” is to shrink that list of caveats down as small as possible. We want marshalling to work so sessions function correctly. We want AR-JDBC to be cleaned up a bit more, with more testing and even wider database support. We want any remaining core library issues resolved. We want those peripheral deployment projects to work perfectly. There’s a lot of work to get there, but it’s now simply an incremental process; Rails runs today, and will run better tomorrow.
What’s this about YARV instruction interoperability?
Readers: here’s an IRC recap for you:
[1:31pm] olabini: HAHA
[1:31pm] olabini: YEAH BABY.
[1:31pm] olabini: hehe.
[1:31pm] olabini: echo 'puts "Hello world"' > test1.rb
[1:33pm] olabini: ruby-yarv ~/src/yarv/tool/compile.rb -o test1.rbc test1.rb
[1:33pm] olabini: jruby -y test1.rbc #=> "Hello world"
[1:33pm] headius: hah, awesome
[1:33pm] nicksieger: no way!
So this is awesome that you guys are able to track so closely with YARV’s progress, but why do it? Hedge your bets?
Ola Bini: First of all, it shows the maturity of the JRuby runtime that we can implement basic parts of the YARV VM this easily. Second, it can be very interesting for us to try out parts of how 1.9/2.0 will work out within the current JRuby system. Third, we don’t have a YARV compiler yet, but being able to run files compiled with YARV ensures that we stay on track for Ruby compatibility. Fourth: Yeah, hedging your bets is always a good idea. Diversity breeds evolution. I believe where on the right track with the current AOT and JIT compiler works, but there is always a good idea to implement these things in more than one way. And of course, it ‘s just fun!
The next step for this will be to get the loading to handle more things. At the moment, it only runs extremely simple scripts. But I’m planning on handling the more complex things soon too, adding support for labels and defining YARV methods and other such things. The very next step to handle is a compiled recursive fibonacci script. The YARVMachine already has most things needed for it, but the YARV emitted by the compiler contains some tricks that needs to be fixed.
Charles Nutter: I’ve been the primary person responsible for our various interpreter rewrites over the past year or two. Originally I modified it to be mostly “stackless”, using an Instruction object for each element in the AST and pushing down an external stack of previous instructions to maintain context. That seemed like a neat idea, and it certainly did move toward a stackless design (I actually demoed a recursive fib(100_000) at RubyConf 2005), but it was rather slow and complicated enough that only I could maintain it. So in October of 2006 I did another rewrite, basically simplifying the interpreter down to a “big switch statement” that could quickly traverse the AST without a lot of objects and stack manipulation. This new C-like interpreter engine was quite a bit faster, but unfortunately the tradeoff was that we were again burning Java stack frames when we had to dig deeper into the AST, and our maximum stack depth suffered.
I’ve still always wanted the stackless design back in JRuby, and started to think about alternate routes to get there. The most obvious was having our own bytecode engine. The most readily-available set of bytecodes for Ruby…was YARV’s.
Implementing a stack machine is pretty trivial. You need an operand stack, instructions for manipulating it, and instructions that consume values from it. Over the past year, YARV’s core set of bytecodes have started to solidify to the point that I figured implementing a YARV machine in JRuby would be a good idea. So I did a very simple initial implementation that just handled local variables, method calls, while loops, and so on, to see if it would be feasible. I got it as far as running an iterative fib, and the results were very promising: it was quite a bit faster than the current interpreter.
I ended up putting that down for a while to look at Java bytecode compilation, which has been coming along very nicely. Recently, Ola decided to pick up the YARV machine work, and made it double cool by loading real compiled YARV bytecodes into it. And if that wasn’t good enough, the original partial machine I’d implemented was able to run them without modification!
We’re looking toward the future with this work. We know that YARV is now “The” Ruby VM, and that eventually people will start to run compiled Ruby bytecodes. We also know that JRuby will never be able to fully escape interpreted-mode execution. I believe both goals are answered by having a fast Ruby bytecode machine that works in concert with our Ruby-to-Java compilers. And that’s the current roadmap for JRuby’s execution model.
Thomas Enebo: Personally, I would like to see us move from walking our current tree to walking a set of instructions. I think dynamic optimizations (as well as static) will be much easier using instructions and we can also create a simpler AST/parser (the traditional AST in Ruby does quite a bit of static optimization which I think makes the grammar a little tougher to wrap your head around).
Anything YARV-related sort of hits my sweet spot since it may nudge us in this direction. JRuby will probably always mix execution between compiled and interpreted code. I think interpretation will be easier to support at an instruction level. It will also give us a good opportunity to flatten the Java stack more. YARV is a good place to start. It may be right solution for us too. Who knows? I think experimentation is the name of the game for this stuff. So I love to see it happening :)
Norbert
is my latest project: a robot that I plan on building up and
programming.

I've got the motor hooked up and running, "mocking out" the control
logic to a pair of switches. The plan is to get my laptop on board
and control the motors through the serial port. Apparently the
circuitry for such a task involves using a UART chip to convert the
serial signals into something usable, which is going to be a bit of
a challenge for me; I haven't worked with ICs before.
Currently Norbert is capable of backward and forward motion as well
as turning, though the limitation of using switches on the chassis
makes control somewhat impractical.
The plan is all laid out in terms of what revisions will include
what features:
(Italics indicate completed revisions.)

I drummed up a bit of code for the controller before I had really
decided on parallel vs serial. (I had an old laptop I was
considering using that had an easier-to-interface-with parallel
port, but it was lacking a battery.) Hopefully it shouldn't be too difficult
to modify it to use the
ruby-serialport library.
class Robot
COMMAND_BITS = [:right_motor_forward, :right_motor_backward,
:left_motor_forward, :left_motor_backward]
def go_forward
write_byte aggregate_commands(:right_motor_forward, :left_motor_forward)
end
# [go_backward and other commands...]
def aggregate_commands(*commands)
commands.inject(0) do |aggregate, command|
aggregate | bit_place(COMMAND_BITS.index(command))
end
end
def bit_place(place)
(2 ** place)
end
def write_byte(byte)
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/24605
p = open('/dev/port', 'w') # open /dev/port in write mode
p.sync = true # turn buffering off, write to the
# port as soon as it is requested
p.seek(0x378, IO::SEEK_SET) # move writing cursor to the parallel
# port address
p.putc(byte) # write byte to it and activate
# whatever on your I/O board is
# attached to the D0 pin
end
end

If you are or have the intention to be a user of Ruby/Informix you're invited to join the mailing list, either to get your questions answered, send suggestions, bugs reports or participate in discussions on Ruby/Informix development directions.
Subscribe here: http://rubyforge.org/mailman/listinfo/ruby-informix-misc

Argh, dammit. It’s 2.15am and I should be sleeping but instead I find myself drawn into this ‘5 Things You Might Not Know About Me’ meme thingy by Pub Standards overlord, Mr Darlow. I’ll try to make this brief and as none-boring as possible.
And for the bonus: I’ve never voted in any kind of election. I’ve traditionallly been pretty disallusioned with politicians but I’ve been reading loads of Noam recently and I’m getting politicked up so this might change. God knows who I’ll vote for though, they are all arseholes.
Tagging some of the JavaScript Mafia and some London Rails peeps:
To those I’ve tagged, I apologise. Don’t feel obliged to carry this plague on.
And finally, if you are in London on thursday, Pub Standards beckons. Partake of the Fat Man In A Box and be merry.
I just wanted to mention the latest Ruby on Rails podcast, in which Obie Fernandez is the guest interviewer in a visit to the Copenhagen Ruby Brigade. Although the sound environment is a bit distracting at the start (Obie, please don't interview people in clubs anymore), the content is great.
Many of the members of the Brigade are .NET developers that are also using Rails. At RailsConf 2006, Brian and I had the pleasure of meeting Casper Fabricious in person. At that time he mentioned something about getting a local Ruby group together, and it's great to see how it's come together. Casper is a great guy and really smart. Working on .NET during the day and Rails at night (sound familiar?), he and the other guys at the CRB are helping spread the word of Rails to the companies they work with. Unfortunately Caspar was not included in the podcast, but the other guys who were interviewed did a great job and had insightful things to say about making the transition from .NET to Rails at your workplace.
In this podcast they talk about Rails vs. .NET, and the difference it makes in their work. Oh, and these guys aren't just using Rails, they're actively giving back to the community with plugins and trying to write code that can be incorporated into core. So definitely give it a listen to get a perspective on the impact Rails is having on existing .NET shops there.

This is a radically new version of the s33r S3 library. I've rewritten large chunks of it, so it's not guaranteed to work with your old code. However, most of the methods in previous versions still exist. Hopefully you'll find it more streamlined and easier to use. I've also not got round to the tests for the networking aspects of the application yet, but that's next on my todo. There is also a new usage document at http://s33r.rubyforge.org to titillate and delight.
when in the course of writing ⁄
it becomes necessary for writers ⁄
to dissolve the syntactical bands ⁄
which have connected them with another ⁄
and to assume ⁄
among the powers of the written word ⁄
the laws of nature ⁄
and of nature’s rule entitle them ⁄
a decent respect to the opinions of mankind ⁄
requires that they should declare ⁄
the causes which impel them to the separation
we hold these truths to be self-evident ⁄
that all words are created equal ⁄
that they are used by their writer on purpose
whenever any form of punctuation becomes destructive to these ends ⁄
and create injustice among the words ⁄
it is the right of the writers to alter ⁄
or abolish it ⁄
and to institute new punctuation ⁄
or no punctuation at all ⁄
laying its foundation on such principles ⁄
and organizing it in such form ⁄
as to them shall seem most likely to effect their purpose
prudence will dictate that punctuation long established ⁄
should not be changed for light and transient causes ⁄
and accordingly all experience has shown ⁄
that writers are more disposed to suffer ⁄
where evils are sufferable ⁄
than to right themselves by abolishing the forms of punctuation ⁄
to which they are accustomed
but when a long train of punctuation rules ⁄
evinces a design to reduce words under absolute despotism ⁄
it is their right ⁄
it is their duty ⁄
to throw off such punctuation ⁄
and provide new punctuation for their future writing
the history of punctuation is a history of repeated injuries ⁄
and usurpations ⁄
all having in direct object the establishment ⁄
of an absolute punctuation ⁄
over our words
it has refused ⁄
to give all words the same importance ⁄
it has dictated ⁄
illogical rules of capitalization ⁄
it has forbidden ⁄
to let the writer express himself however he wants it
in every stage of oppression ⁄
we have petitioned for the most humble terms ⁄
our repeated petitions ⁄
only have been answered by repeated injury
a rule of punctuation ⁄
whose character is thus marked by every act which may define a tyrant ⁄
is unfit to be used by writers
we ⁄
therefore ⁄
writers all over the world ⁄
do ⁄
in the name ⁄
and by the authority ⁄
of our writing ⁄
solemnly publish and declare ⁄
that this new way of writing is ⁄
absolved from all allegiance to punctuation ⁄
and ⁄
all connection between them ⁄
and related parts of language ⁄
is ⁄
and ought to be ⁄
totally dissolved ⁄
and that as free writers ⁄
they have full power to levy war ⁄
conclude peace ⁄
contract alliances ⁄
establish publishing ⁄
and to do all other acts and things ⁄
which free writers may of right do
and for the support of this declaration ⁄
with a firm reliance on the protection by the readership ⁄
we mutually pledge to each other ⁄
our lives ⁄
our writings ⁄
and our sacred honor
christian neukirchen
NP: The Who—Behind Blue Eyes
A comparison between the #5 language (ranked popularity by Tiobe on Jan/07) and the #1 framework (ranked lovability by me!).
When it comes to programming, more specifically the development of web applications, it is important to consider all the tools of the trade before using the one that is going to be used for the job.
For some background, I have been programming web applications since I was 13 years old, over 11 years ago today. I started with a simple language called HTML, which evolved into experience with JavaScript mouseovers, then PHP counters and include files, after that onto the MySQL to store the data from the forms for dynamic input, and then into CSS. In retrospect, learning CSS was likely the most difficult thus far to learn out of all of technologies as it required a significant unlearning of the firmly committed <table> tag from my memory. After CSS had been installed, I got equipped with XHTML 1.0, and started looking at more “enterprise” level languages and came across Java, .NET, and even a bit of Perl.
We need to pause here, because this was a major decision in my career. This was now 3 years along my path of web development, and I was working at a company called Tantalus. A major Java shop on Mainland Street in Yaletown that was run by the late Patrick Whelan. It was here that I got my first cup of Java knowledge, and I must say it was hard to swallow.
My brother Martin also worked at Tantalus as a Systems Administrator, managing all their amazing Sun servers and making elegance out of the hosting required for the Java and Oracle apps they were deploying for companies such as Future Shop and other major organizations. Martin continued to push Java as my saviour, saying that if I took a 2 year course at BCIT I could be starting at 45k-60k a year right out of school (which was actually true at the time). He even gave me free books, which I still have on my book shelf (collecting dust). Even more importantly, he gave me a class map of the Java tree and I was amazed. Looking over it in amazement at all the libraries, you could do everything with Java.
Here in lies the problem. Java is a swiss army knife in your web development toolkit, if you ever do decide to learn it. You can pretty much build everything from a cell phone app, to a full on desktop application. It is an amazing language, but it’s just that. Huge. I kept the poster on my wall for months, probably even close to a year if I time-stamped it.
While considering the advice provided by my brother, I decided to take a workshop taught by one of the Tantalus Java gurus and was interested. I learned some C and C++ back in high school in a Computer Science AP (advanced placement), which was a first year university course in high school, and found some very similar characteristics.
I continued along with my PHP development and self-taught education, seeing that Java was a better language at the time, but just didn’t feel my experience at the time (which now I see as really my interest itself in Java) wasn’t solidified enough to begin learning such a massive and complex language. Concepts such as Objects, inheritance, and other OOP terminology was quite foreign. So I held off learning it, and felt once I learned PHP well enough, would upgrade.
PHP was great. With the release at the time of PHP 4 and it’’s initial object functionality I started to get up to speed with many of the OOP principles. I was building some pretty amazing Content Management Systems, Digital Asset Management Systems, even Web Top Publishing Systems. My previous commitment to learn Java was fading as my experience grew with PHP was growing, seeing that I could build all the amazing things with what I had originally felt was a subordinate language.
I continued to expand my knowledge of PHP, get into the core of the internals and sparked a desire to write some core functionality. I eventually got to meet the creator of PHP (Rasmus Lerdorf) at a Vancouver conference I helped organize back in 2004.
When I started seeing the release candidates and beta code of PHP5 I was really excited. The principles of objects which I had grown to love, were being fully supported and embraced by the language I had gained enough knowledge with to realize there was few things, if any, I could actually do with it. This shelved Java way back on the list of technologies to learn at this point. One of the only things that I can see a use for Java is a drag and drop uploader residing within the browser to avoid the one file upload field plagued by today’s forms.
In any case, PHP was my tool of choice. At this point, it had an enormous amount of libraries, nearly as many as Java. Not to mention WAYYY more open source projects on sourceforge.net that Java could ever hope for. The world supported the language, and so did I.
But. There was a problem. After building these amazing systems, that did some really cool things. I found myself repeating the same lines of code over and over again. I was creating objects that had the get and set methods within objects and had the CRUD principle embraced. I began unifying my approach. Creating a save method that did both a update and create depending on the state of the object, centralizing the objects storing and access mechanisms for my all the data within the database. Evolving to standardize date, text, string, url, and all the other MySQL data field types and personal standardized column types in a base class extended by all Models. Basically, I was simplifying tasks I was doing every time I created a new Model so I didn’t have to repeat myself over and over again.
This was a great time in my development career. Realizing that I was paving a path that I would allow me to be able to create objects that could access fields I created in the database without having to implicitly specify by introspecting what was going on, and create the guts of the Model class automatically. Realizing the productivity gains alone on this were enormous I kept on it. I got quite a long way along this path, before something happened that changed the direction of career entirely.
I found this framework called Ruby on Rails. At first I was extremely frustrated. As many would who were working so hard to create something so important for several years in the background while trying to pay the bills would, and see the tool had already evolved to a very usable state by someone else, and even had a budding community behind it. This was an interesting time, and I began to look into the framework a bit more. And more. And then I decided what was the point of developing the remaining pieces of same thing in PHP when it was already pretty much 100% of what I wanted in another language? Simple choice, learn the new language and framework and save what could be hundreds of hours development.
This was the beginning of my journey learning Ruby on Rails, as well as Ruby the language which the framework was built on.
While learning the framework, I seen some major differences between PHP and the language of Ruby. Things like “for” iterators were somewhat non-existant in a 1:1 comparison.
Something like this in PHP…
<?php
$array = array('my list', 'of', 'items');
for ($index = 0; $index count($array); $index++) {
echo "$index. $array[$index]";
}
// alternatively
$array = array('my list', 'of', 'items');
foreach ($array as $index => $item) { echo "$index. $item"; }
?>
Looked like this in Ruby…
%
array = ['my list', 'of', 'items']
array.each_with_index { |item, index| p "#{index}. #{item}" }
%>
The clarity of the syntax, and the language in general was purely impressive.
I continued to ride along the Rails train, finding more and more benefits along the way, such as previously described as ActiveRecord’s ability to dynamically introspect all the fields of a table and have all the functionality needed to create, update, delete, and read any row of data automatically with one line of code.
In addition, ActiveRecord could be done with any database adapter. Whether it was PostgreSQL, MySQL, Oracle, etc. The factor of connectivity alone when in PHP required additional modules such as AdoDB or PEAR::DB. Both of which has some really crazy syntax that was quite complex to learn. You had to learn SQL, then you had to learn the implementation of SQL abstraction. With Rails, this was inherited.
Another great feature of Ruby on Rails I had discovered was the simple concept of organization. A concept known as MVC was perfect. For those that haven’t heard of the term it’s called Model-View-Controller. It was directly in line with what I had done in the past with PHP projects after adopting concepts from frameworks such as FuseBox and the multitude of others sharing the same principles.
The list of benefits for Rails got better and better, the more I learned of the framework, the happier I was realizing that I wouldn’t have to repeat myself nearly as much as when I was writing PHP apps.
So, while along this learning adventure in the world of Ruby on Rails, I started to find out more about the advanced concepts of Ruby, the underlying language of Rails. The most profound realization of mine was when I learned that there was no waterfall approach to a the Class hierarchy. With PHP and many other languages, you have a Class, and you extended a Class in a new Class to inherit and then subsequently add additional functionality. With Ruby, you have a Class defined in one file, and you can change that same Class entirely in another file by overriding methods, adding new ones. The language was showing it’s true colors as one of the most dynamic tools I had ever used.
Constantly finding myself comparing Ruby to PHP while learning the syntax of the language and underlying Objects, finding the equivalents of things like “count” ([1,2,3,4].length), or “str_replace” (”string”.gsub) in Ruby continued. I found myself in a world of Object Oriented bliss, rarely looking back at the dull, functional world of the PHP library.
It’s been close to 2 years now since I started playing with Rails back in February of 2005, and I have found little reason to go back, other than the odd open source project which is too impressive not to use and save the time it would take to rebuild it in Rails.
Actually, there is one other reason I frequently look back at PHP. The documentation. My learning curve in PHP was spring-boarded due to the elegance of the hard working PHP documentation team, and their choices made to organize the information in such a manner that was instrumental to many peoples adoption and education. So much so, that even right now I find myself remembering my appreciation setting up a local version of the PHP documentation at php.inimit.com helping support the threads of access and decreased latency of users dependent on the documentation with hosting a local mirror sponsored by my development business. It never got accepted as a Canadian mirror due to what seemed like messy political tape of the core PHP team, but that’s besides the point. I still appreciate the documentation, and will continue to host the mirror regardless.
What I find in ever increasing potency is that Ruby and Ruby on Rails needs documentation like PHP. Actually, every language ever created needs documentation like PHP. It is, at least it should be, the gold standard of documentation for anyone learning a language, and could likely be construed as the single most instrumental reason why PHP has had such a significant adoption rate within the world of development.
I became a supporter of the Ruby and Rails documentation project known as Rannotate, and on December 18th, 2005 registered the domain railsmanual.org to ensure that the community benefits from the only similar version of the gold standard of documentation that PHP has. RailsManual is a great resource, but needs some major work to raise it’s value to that of the same degree as PHP.net.
There has been quite of attention as of late on this subject. The people over at caboo.se managed to raise some ~$15,000 USD to help out on the documentation effort, but have had some trouble finding people to actually write the documentation itself.
I have given my $0.02 on the mailing list on how we can solve this, which would actually take the PHP.net documentation system to the next level. It’s really a simple process.
Here is a very basic layout of how I see it looking and functioning like.

It’s really quite simple, but to the point. No one person needs to create the documentation It’s a collaborative approach. The main area of concern for such a collaborative system is the prevention around the area of spam. Without registration, or confirmation of email validity, the site will eventually become ridden with Spam, as nearly every blog has been plagued by.
It may appear that I have digressed on my comparison of PHP vs. Ruby on Rails, but I haven’t really. The one area of Ruby and Ruby on Rails that is flawed, or at least needs major improvement, is the documentation. Everything else about Ruby language at it’s core and the framework of Rails, is amazing.
One thing I have simply glazed over at this point is the fact that Rails is a framework, and PHP is a language. And as the saying goes, you should really compare Apples with Apples, and not Apples (Programming Languages) with Oranges (Frameworks). Ruby on Rails is indeed a framework. One which extends upon the foundation programming language known as Ruby. This means that Rails provides additional functionality on top of Ruby. Including a many number of Objects enhancing capabilities within any application built on top of the Rails layer. These Rails enhancements are specifically catered to those building web applications.
Now to go back in my story, remembering when I mentioned how Java was the swiss army knife that could be used to help create everything a programmer wants, specializing in nothing. PHP in this case, is just that now except it caters to web applications. It is also a programming language that can create everything a programmer wants, but it was built first as a web development language. Where Java could do everything a programmer could want, PHP is falling victim to the same virus that creeps into anything that has been around long enough. Unintended growth in all directions. This isn’t entirely a flaw, but now enough leaves room for something better to come along that is focused on one area rather than all areas.
Ruby is the same as PHP, and even can be compared at a fundamental level to that of Java with one major difference I would like to point out. Ruby is as well focused on doing as much as a programmer wants and needs. But it does it with the elegance, simplicity, and dynamism that is lost with PHP, and next to non existent with Java.
So now that we are somewhat clear of comparisons, realizing that PHP and Ruby on Rails are fundamentally different. Seeing that we are actually comparing a language with a framework. Let’s compare a PHP framework such as PHP on Trax, a clone of Ruby on Rails written in PHP, compared to the original framework that sparked the clone wars - being Ruby on Rails.
For this, we look at an ActiveRecord example from each. Starting with a class definition in PHP on Trax written in PHP.
<?php
class Product extends ActiveRecord {
public function validate_title() {
if ($this->title == '')
return array(false, "Title can't be empty");
if ($this->find_first("title = '{$this->title}'") != false)
return array(false, "Title must be unique");
return array(true);
}
public function validate_description() {
if ($this->description == '')
return array(false, "Description can't be empty");
return array(true);
}
public function salable_items() {
return $this->find_all("date_available = now()", "date_available desc");
}
}
?>
And now in the same class in Ruby on Rails, inherently written in Ruby.
%
class Product ActiveRecord::Base
validates_presence_of :title, :message => "Title can't be empty"
validates_uniqueness_of :title, :message => "Title must be unique"
validates_presence_of :description, :message => "Description can't be blank"
def salable_items
Product.find(:all, :conditions => 'date_available = now()', :order => 'date_available desc')
end
end
%>
This is a real comparison between the two frameworks, and you can clearly see just by the lines of code alone. Ruby on Rails is less. Ruby on Rails even helps to clean up the validations to mere single lines of code having inherited functionality built within ActiveRecord::Base. And when it comes to Ruby, ignoring entirely all what is actually happening as far as functionality is concerned within the framework’s Class, you see the language really shine. The precision of each character is far from being wasted. There is next to nothing there that doesn’t need to be, allowing for even those understanding the logical order of words an intuitive grasp of what is happening within the lines of code written.
Now, when we decide to stop ignoring what is actually going on, we may ask “What are each of these blocks of code really doing?”.
Each sample creates a Object called Product that you can access throughout your application providing the programmer with:
1) Access to all rows of data in the “products” table through a single interface to create, update, read, and delete.
2) Optional validations for any data that is set to be stored in the database passes certain conditions
3) Integrated error handling
4) As well as inheriting tons, and I mean _tons_ of additional functionality provided by ActiveRecord (PHP on Trax) and ActiveRecord::Base (Ruby on Rails) respectively.
So, now that we have compared only a single slice of each each of the Apples (Languages) as well as the Oranges (Frameworks). We can see the decision really comes down to how much we enjoy the taste of simplicity at this point. Developing in either framework boils down to nearly the same thing. Saving the programmer time when it comes to creating and maintaining and displaying the data within applications.
Ruby provides to Ruby on Rails the simplicity to save more time for programmers compared to the other frameworks. Provides the ability for programmers to write less lines of code than the comparable frameworks. Requires less time for even the most novice programmer to understand what’s going on. And is quite simply more elegant to work with.
Rails has and will continue to be imitated as it has already been in nearly every language. Whether it’s PHP (PHP on Trax), Java (Sails), Perl (Catalyst), Python (Turbo Gears, Django), and even .NET (Castle) - developers from every language recognize the benefits which Ruby on Rails, as proven by their implementations in their native languages.
Yet with all these framework imitations in their respective languages, it comes down to Ruby at the foundation that makes Rails at the heat of it all, so simple, so elegant, so much the reason why it has caught fire so fast and so far across the globe that nearly every developer that is at all interested in keeping their job, has at least heard of it.
The way I see it, the only framework that is going to replace Ruby on Rails, is another one built in Ruby. It’s not the framework that makes it so simple, elegant, and tasty as a whole. It’s the language the framework is built on that makes Rails what it is today.
I would love to hear your thoughts on this, please do comment below or send me a private email from my website.
Have you converted from PHP for the greener pastures of Rails?

When you create your gems with 'newgem' and share it with the starving masses, they will no longer need to install hoe to use your gem.
Over the weekend I noticed that the Rails API docs didn't have any basic information on relation cardinality and how that maps to associations. It wasn't difficult to come up with some overview documentation, and a patch later, it's now part of the API docs. I'm reproducing it here because most people won't notice its appearance in the docs, and it's good to call out basic stuff like this.
ActiveRecord associations can be used to describe relations with one-to-one, one-to-many and many-to-many cardinality. Each model uses an association to describe its role in the relation. In each case, the belongs_to association is used in the model that has the foreign key.
Use has_one in the base, and belongs_to in the associated model.
class Employee < ActiveRecord::Base
has_one :office
end
class Office < ActiveRecord::Base
belongs_to :employee # foreign key - employee_id
end
Use has_many in the base, and belongs_to in the associated model.
class Manager < ActiveRecord::Base
has_many :employees
end
class Employee < ActiveRecord::Base
belongs_to :manager # foreign key - manager_id
end
There are two ways to build a many-to-many relationship.
The first way uses a has_many association with the :through option and a join model, so
there are two stages of associations.
class Assignment < ActiveRecord::Base
belongs_to :programmer # foreign key - programmer_id
belongs_to :project # foreign key - project_id
end
class Programmer < ActiveRecord::Base
has_many :assignments
has_many :projects, :through => :assignments
end
class Project < ActiveRecord::Base
has_many :assignments
has_many :programmers, :through => :assignments
end
For the second way, use has_and_belongs_to_many in both models. This requires a join table that has no corresponding model or primary key.
class Programmer < ActiveRecord::Base
has_and_belongs_to_many :projects # foreign keys in the join table
end
class Project < ActiveRecord::Base
has_and_belongs_to_many :programmers # foreign keys in the join table
end
It is not always a simple decision which way of building a many-to-many relationship is best. But if you need to work with the relationship model as its own entity, then you'll need to use has_many :through. Use has_and_belongs_to_many when working with legacy schemas or when you never work directly with the relationship itself.

uncertain version 0.1.0 has been released!
'Uncertain' adds a Numeric class that encapsulates and handles numbers with uncertainty (e.g., 1.0 +/- 0.2).
Changes:
== 0.1.0 / 2007-01-17
* Beta release
* Still needs lots of tests
* doesn't handle trig math yet
ruby-units version 1.0.1 has been released!
This library handles unit conversions and unit math
Changes:
Change Log for Ruby-units
=========================
2007-01-17 1.0.1 * Force units are now defined correctly.

Yesterday’s tip demonstrated how to refactor common RJS bits into their own method. Specifically, it gave an example that created a special render_error method which you can call whenever you need to render an error.
Today’s tip is about overriding the existing render method, to add support for your own custom conditions. Specifically, render_error is nice and all, but wouldn’t it be nice to make it look more like the standard Rails render method?
| 1 2 3 4 5 |
def create
... rescue Exception => error render :error => error end |
It’s remarkably simple, actually. To implement the above, you’d just throw something like the following in your ApplicationController:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def render(*args)
if args.length == 1 && args.first.is_a?(Hash) case args.first[:error] when nil then super when ActiveRecord::InvalidRecord render(:update) do |page| page[:js_error_bold].replace_html(args.first[:message]) page[:js_error_text].replace_html( args.first[:error].record.errors.full_messages.join("\n")) page[:js_error].visual_effect :blind_down, :duration => 0.2 end else raise args.first[:error] end else super end end |
In other words, first we check to see if the first and only argument is a hash (since that’s all our new feature uses). Then, we test the value of the :error key, calling super whenever we want to delegate to Rails’ render method. We then compare the error raised to some list of errors that we want to handle specially, and do the appropriate work for each.
You could also make it so that it accepted the error directly, as the first argument (render(error)).
You can use this technique anywhere you find yourself rendering the same kind of thing in multiple places. Errors are a good example, and are (frankly) where I use this technique the most.
I just ran across an almost exact functional clone of my RailsDay entrant, Gr.egario.us over at Quotiki. I’d say the design is much better than what I was able to do, although they don’t yet have the ability to put quotes on your own site like gr.egario.us offers.
Is that the sound of bitterness you hear? Not at all – in fact I’d love to pull gr.egario.us down at some point so please take a look at Quotiki for your future needs. My only question is – was Quotiki written in a day?
If any of the Quotiki folks want to look at how easy it is to write in Rails, let me know and I can shoot the source over to you. The only thing more satisfying than a Java-to-Rails conversion is a .NET-to-Rails conversion.
tags: rubyonrails, rails, railsday2006, quotiki

Wow, the nice artists over at Apress have put together a button for this month's How Rails Made Me a Better Programmer blogging contest. If you've already submitted an entry, feel free to grab the image and use it with your essay. If you haven't entered yet, what's keeping you? Time's running out. Just go read the challenge and leave a link to your entry in the comments.
I'm hoping the Apress
WEBrick isn't as fashionable as it once was, but it's still invaluable for
development and testing. I recently needed it to handle rewrite rules, and
google didn't return anything better than
Simon Strandgaard's code.
On that same thread, GOTOU Yuuzou indicated that he wanted to add proper URL rewriting support to HEAD (1.9). It's been two years, but grep -r rewrite webrick says it hasn't happened yet.
Simon's code choked on query arguments, so I extended it as follows:
class WEBrick::HTTPServer
alias :__rewrite_old_initialize :initialize
alias :__rewrite_old_service :service
def initialize(config={}, default=WEBrick::Config::HTTP)
__rewrite_old_initialize(config, default)
@rewrite_rules = []
end
def rewrite(pattern, subst)
@logger.info("rewrite rule %s -> %s." %
[pattern.inspect, subst])
@rewrite_rules << [pattern, subst]
end
def service(req, res)
olduri = URI.parse(req.path)
olduri.query = req.query_string
old = olduri.to_s
@rewrite_rules.each do |pattern, subst|
if pattern =~ old
uri = URI.parse(old.gsub(pattern, subst))
req.instance_variable_set("@path", uri.path)
req.instance_variable_set("@query_string", uri.query)
req.instance_variable_set("@query", nil) # so it gets reparsed
@logger.info("Rewrote URL %s -> %s" % [olduri.to_s, uri.to_s])
break
end
end
__rewrite_old_service(req, res)
end
end
Yes, it doesn't use define_method to redefine the instance methods while keeping the old definitions*1, but it doesn't matter since the above code is sitting in a 50LoC file and there's no danger of it being loaded twice.
Recently, I wrote about using RSpec and autotest (...which I think should be called autospec) together to help boost productivity while working on Rails projects. It seems that a few members of the PLANET ARGON team have picked up on using it, which I’m happy to hear about. :-)
It’s not the only thing that I’m happy about though.
I recently came across another gem. Several of my comrades in #caboose are using piston to manage external plugins for Ruby on Rails. Wait! Isn’t this what Subversion externals is meant for? Well, yes… but externals also eat away at productivity. For example, each day, we may have anywhere from 4-6 designers and developers working on one client project. When we’re in crunch mode, this could account for quite a few subversion commits throughout the day. We all know that we should run svn up on a regular basis to make sure that we’re keeping things in sync… especially when designers and developers are working really closely and fine tuning something specific in the application. Well, the one downside to this process is that each svn up not only checks our repository, but it also checks external repositories.
“But wait! Can’t you just ignore externals on an update?”
Of course, but who wants to type out --ignore-externals each time they run an update? ...or perhaps you could make an alias for this in your shell. In any event, everyone on the team is then left to be responsible for doing this… and an extra 30-60 seconds (if not longer) per svn update times x number of people on project… well… time wasted if you’re closely watching the svn updates. Also, TextMate doesn’t have an option currently (that I could find) to ignore externals, so for those who manage subversion through it… they’re waiting on externals within their primary workspace.
Another issue with svn externals is that when a repository goes down, it really starts to slow stuff down your updates. This is always fun when you go to deploy your application with Capistrano and realize that you can’t finish the update because it can’t connect it to http://svn.lazyatom.com/public/plugins/acts_as_hasselhoff/ to make sure that your application has the latest version of the best plugins available for Rails.
Then there is the whole issue of wanting to make changes to the plugin that you’re including as an external. How does that fit into the whole mix?
Piston encourages you to keep your external plugins in your local repository. Don’t worry, it remembers where it retrieved the code from so that you can update from the external repository at any time.
Again, this is really simple like most gems.
$ sudo gem install -y piston
Password:
...
Successfully installed piston-1.2.1
Great, that’s all that you have to do to get started with Piston. Now, let’s get on with the show.
If you don’t have any existing Subversion externals, feel free to skip this section.
Okay, so let’s say that you’re working on a Ruby on Rails project and are relying on several external repsitories. For example, a project that I’m working on… currently looks like this.
$ svn proplist --verbose vendor/plugins/
Properties on 'vendor/plugins':
svn:externals :
authorization http://svn.writertopia.com/svn/plugins/authorization
svn_tools http://svn.planetargon.org/rails/plugins/svn_tools
simply_helpful http://dev.rubyonrails.com/svn/rails/plugins/simply_helpful
exception_notification http://dev.rubyonrails.com/svn/rails/plugins/exception_notification
asset_field http://svn.planetargon.org/rails/plugins/asset_field
rspec_on_rails svn://rubyforge.org/var/svn/rspec/tags/REL_0_7_5/rspec_on_rails/vendor/plugins/rspec_on_rails
rspec_autotest http://svn.caldersphere.net/svn/main/plugins/rspec_autotest
Piston is smart enough to know how to convert these Subversion externals into Piston-friendly plugins. This can be done by passing the piston command the convert option from within your Rails application directory.
Go ahead and run the following.
$ piston convert
Importing 'http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-0_RC1' to vendor/rails (-r 5619)
Exported r5619 from 'http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-0_RC1' to 'vendor/rails'
Importing 'http://svn.writertopia.com/svn/plugins/authorization' to vendor/plugins/authorization (-r 83)
Exported r83 from 'http://svn.writertopia.com/svn/plugins/authorization' to 'vendor/plugins/authorization'
Importing 'http://svn.planetargon.org/rails/plugins/svn_tools' to vendor/plugins/svn_tools (-r 119)
Exported r119 from 'http://svn.planetargon.org/rails/plugins/svn_tools' to 'vendor/plugins/svn_tools'
Importing 'http://dev.rubyonrails.com/svn/rails/plugins/simply_helpful' to vendor/plugins/simply_helpful (-r 5700)
Exported r5700 from 'http://dev.rubyonrails.com/svn/rails/plugins/simply_helpful' to 'vendor/plugins/simply_helpful'
Importing 'http://dev.rubyonrails.com/svn/rails/plugins/exception_notification' to vendor/plugins/exception_notification (-r 3900)
Exported r3900 from 'http://dev.rubyonrails.com/svn/rails/plugins/exception_notification' to 'vendor/plugins/exception_notification'
Importing 'http://svn.planetargon.org/rails/plugins/asset_field' to vendor/plugins/asset_field (-r 50)
Exported r50 from 'http://svn.planetargon.org/rails/plugins/asset_field' to 'vendor/plugins/asset_field'
Importing 'svn://rubyforge.org/var/svn/rspec/tags/REL_0_7_5/rspec_on_rails/vendor/plugins/rspec_on_rails' to vendor/plugins/rspec_on_rails (-r 1330)
Exported r1330 from 'svn://rubyforge.org/var/svn/rspec/tags/REL_0_7_5/rspec_on_rails/vendor/plugins/rspec_on_rails' to 'vendor/plugins/rspec_on_rails'
Importing 'http://svn.caldersphere.net/svn/main/plugins/rspec_autotest' to vendor/plugins/rspec_autotest (-r 48)
Exported r48 from 'http://svn.caldersphere.net/svn/main/plugins/rspec_autotest' to 'vendor/plugins/rspec_autotest'
Done converting existing svn:externals to Piston
All we have to do now is checkin our changes to subversion and we’re golden.
svn ci -m "updating repository to use piston instead of those lame-o externals..."
If you find this interesting and want to learn more, be sure to check out this post on Ruby Inside for a detailed introduction to Piston.
update
the following morning I saw this come across our development team channel…
< argonbot> svn.commit( project_name, { :author => 'brian.ford', :rev => 83, :log => 'converted svn:externals to piston for product, cus I can.' }
:-)
What a great weekend! We got together with 20 great people to learn Rails together this past Saturday, and Brian and I had a good time. And I'm really glad to say that it seems everyone else also had a good time, too.
We're going to follow up with a more substantial post this week, but I wanted to give an immediate thank-you to Michael Leung for being willing to help us out. Everyone's PC is a little different, and troubleshooting a few problems with Ruby and/or Rails and/or MySQL on Windows would have been hard work for us without his help. Michael has given a lot to the Rails on Windows community. Although Michael isn't actively coding on RideMe anymore, he's still donating time and resources to keep it going. The inevitable question of IDEs came up during our class, and I hope everyone will take a look at RideMe (and even better, contributing to it, if you know C#). Michael is an excellent Rails developer, and it was reassuring to have him there and to keep us honest. :-)
Just a few quick observations about the class:
Although advertised as a class for former Microsoft developers who want to learn about Rails on Windows, several very cool-looking Macs showed up. Which we thought was great. We demonstrated Ruby and Rails on Windows Vista, Windows XP running inside Parallels on a Mac, and then on the Mac itself, to show that you can develop your Rails apps on either operating system (and we do). (Brian develops mostly on his awesome MacBookPro these days; I use an iMac at my new day-time Rails job, and I use Windows XP for Rails development when I'm at home.)
I was especially happy to see how many attendees had never developed a Web site by themselves before in any programming language. I hadn't either before I learned Rails. I had been a client software developer my whole career (C/C++/C#). My attempts at ASP (and later ASP.NET) just depressed me...writing my own ORM later each time was just the worst. Last year Rails opened up a new world of programming joy to me, and I'm so glad we had a chance to spread the good news of Rails to these folks.
Everyone who came was nice! I don't know what it is, but the Ruby community just seems to attract nice people. No heckling the entire day, and no fruit was thrown (ok, I admit, I thought about throwing selected items lunch buffet at Brian at one point, but I resisted the urge.)
A surprising number of people were from out of town. I remember people saying they were from Seattle, Florida, Memphis, and New York (and I bet I'm forgetting about a couple others).
Thanks again to all who came. And for those who couldn't attend this time around, we hope to see you next time.

For today’s tip, I’m going to be cheap and just point you at someone else’s post. :) It’s a good post, though, and it fits right in with my recent posts on RJS, so I think it’s fair. Also, since I posted to The Rails Way this morning, I don’t think too much should be expected of me today, blog-wise!
So, the pointer: RJS Refactoring. Find yourself doing a lot of the same thing in your RJS code? This tip’s for you. (Thanks for writing that up, Gustav!)

I’ve been offline (read: access to dialup only, which is close enough to offline) and discovered today I had 950+ RSS articles to read. Amongst them, was Coty Rosenblath’s link-blog (often includes Ruby related links) and his “Five things” article. At the end, in little font, was my name.
Thusly tagged, here are five things [...]
I have just released version 0.0..9 of Merb to rubyforge. Within a few hours you should be able to gem install merb and get the new version.
There have been a ton of updates since the last release. It’s now easier to get started with merb. There is an app generator as well as mrblog, a lightweight blogging engine build on merb(not finished but good for examples)
Merb is running in production on more then 12 apps that I know of. Some of these apps are handling insane amounts of file uploads every day. And a few javascript tracker style apps are running on merb now for speed.
Here is an excerpt from the changelog. I know I missed a ton of stuff because merb has grown twice as much code since the last release and is working sweet now.
* Added merb app generator $ merb -g appname
* added super snazzy error pages and stack trace. install the coderay gem to get syntax highlighting of error code pages.
* many fixes for efficeincy of overall framework.
* extensiuve refactoring since last version
* form helpers
* template caching
* production test and development environments.
* upload progress built in now. no need for mup gem.
* added helper system.
* Updated merb rails session parasite mode.
* vendored Paginator gem
* added memory sessions
* added transactional yaml store.
* before and after filters, with very powerfult filter chain halting and redirection
* refactor merb_server to be in the framework and not in bin/
* catch_content and throw_content
* updated routing tobe more precise
* added status codes module
* added Request object
* added Merb::Mailer frameowkr
* fixed up exception handling
* added basic auth mixin
* added drb service provider
* refactored merb halnder for speed
* added Enumerable#injecting
* too many more tweaks to list
You can get your own merb app started in a few steps with the new app generator:
$ sudo gem install merb
$ merb -g myapp
And you can look at mrblog to see a merb app with a decent amount of functionality to see how merb works a little bit easier then the old sample app:
And the rdoc has been updated quite a bit as well:
Stay tuned for some detailed tutorials on making a secure file upload/download server with merb and integrating it with your rails app.
Today I’ve released a new gem version (0.9.1) of railsbench. It’s mainly a bug fix release for the installation problems discovered for 0.9.0.
However, there’s also a new script called generate_benchmarks, which can be used to generate and maintain the benchmark configuration file used by railsbench.
railsbench generate_benchmarks updates the benchmark configuration file with
This should get you started benchmarking in no time ;-)
After generating the file, you will need to edit the benchmarks and replace routing placeholders (:id, :article_id, etc.) by actual values.
If you add new controllers/actions later in the development process, you can invoke railsbench generate_benchmarks again to add new items to the configuration file. The older entries will not be removed by this process.
Currently, generate_benchmarks only works for the 1.2 release candidate and edge Rails (but I’ll gladly accept patches to make it work with 1.1.6).
Happy benchmarking!

Certain color combinations can make your eyes water, others can make your eyes practically leap out of their sockets in delight. Colors can help instill confidence in a product, company, or design—or undermine it. Color can set the mood, or destroy it. Color can make you fit in, or stand out—and it depends on your situation whether or not that's a good thing.
Despite the seemingly magical power...
Check out Slash7 for more -- and let me know what you think!

Chris was the latest person to ask me about RSS updates for Mephisto. I did a little looking, and I found this nifty svnlog xslt from a coding monkey. Only problem was, it creates a feed for a whole repository. However, my public one is made up of several projects and a lot of plugins. (I don’t normally advocate setting up One Repository to Rule Them All, but it requires a textdrive support ticket so they can set the permissions for anonymous read-only.) In the end, I made 3 copies of the xslt to tweak the title, and wrote a shell script for a cron job:
/usr/local/bin/svn log file:///usr/home/technoweenie/svn/projects/$1 --limit 15 -v --xml > /usr/home/technoweenie/tmp-$1.xml
/usr/local/bin/xsltproc /usr/home/technoweenie/bin/svnlog/$1.xslt /usr/home/technoweenie/tmp-$1.xml > /usr/home/technoweenie/public_html/changesets/$1.xml
rm /usr/home/technoweenie/tmp-$1.xml
Point your browsers to http://techno-weenie.net/changesets/ and see what’s available.

After nearly 2 years, I’m happy to announce the release of a new version of sqlite3-ruby. This version is primarily a bug-fix release, so don’t expect lots of new goodies, but it does vastly improve the stability of the sqlite3 bindings for Ruby.
To install:
| 1 |
gem install sqlite3-ruby |
There’s even a precompiled binary gem for you Windows users. (Boy, the world would be a lot less complicated if that OS just went away…I spent about as much time just building that Windows gem as I did applying the patches and fixing all the bugs below, but that’s a rant for another day.)
Two of the most significant things you should note:
The list of fixed bugs, more or less in order of severity:
And, lastly, one (minor) new feature: Before this release, if you used named placeholders for bind variables, you had to refer to them with the colon character:
| 1 2 |
db.execute "select * from users where user_name = :user",
":user" => "mrmacho" |
Now, you can leave the colon off, or even use a symbol:
| 1 2 3 4 5 6 7 |
db.execute "select * from users where user_name = :user",
"user" => "mrmacho" # or db.execute "select * from users where user_name = :user", :user => "mrmacho" |
So, there you have it. Enjoy!

Although ActiveResource was announced last June during David’s World of Resources talk at RailsConf, it has yet to see an official release. It currently lives in the rails svn trunk with the rest of Rails, but was left out in the 1.2 Pre Release. A few rails developers (myself included) have been plugging away at it little by little as we’ve been implementing little REST services. (The only public example I know of is Blinksale, which uses what looks like a compatible interface. However, they provide their own REST::Client library as a sample ruby client lib, instead of ARes). From what I gather, ARes is only being used in limited, private services, but I think it’s time to get it out in the open. My goal with this (and possibly more, making this a series of articles) is to get the word out on where we’re at with ActiveResource, and hopefully get some folks interested in helping out.
For those that don’t know, ActiveResource is a client-side XML consumer for APIs created by the latest Rails restful additions. Consider it your reward for figuring out how to wield map.resources appropriately and restructuring parts of your app around it. That’s right, follow these rules, and you’ll get most of a server API and a client library for free.
Since ActiveResource isn’t released, how do we start playing with it? Probably the easiest way (until a gem is released) is by checking out the whole rails trunk and requiring both ActiveSupport and ActiveResource:
$ svn co http://dev.rubyonrails.org/svn/rails/trunk
$ irb
> require 'activesupport/lib/active_support'
> require 'activeresource/lib/active_resource'
Note: if you don’t already have a checkout of the rails trunk somewhere, all you actually need are ActiveSupport and ActiveResource.
If you’re still following along with us in irb, you can go ahead and create the ActiveResource classes and start using it. First, we’ll create a base class that will set up the Beast site URL, as well as the optional user/password if you want to make changes.
| 1 2 3 4 5 6 |
class BeastResource < ActiveResource::Base # any recent trunk version of Beast will work here self.site = 'http://beast.caboo.se' # site.user = 'rick' # site.password = 'secret sauce' end |
Now that we have that, we can create classes for the four main resources we’ll be dealing with: users, forums, topics, and posts. Users and forums will be straight forward. Topics and Posts, however, are nested resources. They will need a site value that matches the path prefix set by map.resources in Beast.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 |
class User < BeastResource
end class Forum < BeastResource end class Topic < BeastResource self.site += '/forums/:forum_id' end class Post < BeastResource self.site += '/forums/:forum_id/topics/:topic_id' end |
That’s all there is to it. Now, let’s play around.
| 1 2 3 4 5 6 |
f = Forum.find 1
# notice that since Topic has a prefix, we must pass the forum_id. # This is so it can make the request to /forums/1/topics/1.xml t = Topic.find 1, :forum_id => f.id p = Post.find 1, :forum_id => f.id, :topic_id => t.id u = User.find p.user_id |
If that all worked, you should be able to experiment with Beast. If you create any posts, please do so in the Testing forum.
| 1 2 3 4 5 6 7 8 |
forums = Forum.find :all
testing = forums.detect { |f| f.name == 'Testing' } # initialize takes two parameters in ActiveResource. One for the model parameters, and one for the prefix parameters. topic = Topic.new({ :title => 'Testing out ARes', :body => 'Testing 1, 2, 3!'}, { :forum_id => testing.id }) |
You may notice a few odd things here. First, #initialize takes a second hash param for the prefix options. This is so it can POST to /forums/5/topics.xml. Also, if you look at the schema for a topic, there is no body attribute. Beast cheats a little bit here and creates both a topic and the first post from one request.
ActiveResource doesn’t know the schema and will basically send whatever you give it. If you’re a little mischievous, you may try making requests to change the posts-count, updated-at, and other “unchangeable” fields. Luckily, Beast protects its attributes with attr_accessible, so this won’t be an issue.
That’s about it for part one of this series. Hopefully you have a little more understanding of where we’re at with ActiveResource, and have had a chance to knock it around a bit. In future articles, I’ll talk about how to customize your Resources for custom applications, how to correctly build API support that ActiveResource can understand, and go into what work remains for ActiveResource. If you want to see how it works from the server side, check out Beast.
Latest release: 0.4.1
rcodetools is a collection of Ruby code manipulation tools.
It includes xmpfilter and editor-independent Ruby development helper tools,
as well as emacs and vim interfaces.
Currently, rcodetools comprises:
rcodetools can be installed with RubyGems:
gem install rcodetools
If you try this shortly after a release and you get an old version/a 404 error, please allow some time until the packages propagate to RubyForge's mirrors.
rcodetools is available in tarball format. rcodetools' executables will run faster when installed this way, since RubyGems add a noticeable overhead. The last tarball is rcodetools-0.4.1.tar.gz
You can also get it from http://eigenclass.org/static/rcodetools
See this page for more information on xmpfilter and how to use it to generate Test::Unit assertions and RSpec expectations automagically.
The rct-* programs can be used with any editor, but rcodetools includes emacs and vim interfaces (contributions for other editors are welcome); see README.emacs and README.vim in the sources for more information.
This week I managed to escape for Puna to some pleasant surprises on my return home including the iPhone announcement and a Wii. If you even get a chance, visiting India is a must. There are two tips I would give. One: night buses suck, the train is much nicer. Two: if you visit Puna, going to the Osho Meditation Resort is unmissable even if it’s only for the architecture.
Whilst there I also found the time to read The Long Tail. I’d put off buying this because of the high price tag and its deceptively small amount of content. But even if you’re well versed in the concept it’s worth reading if just to put some numbers to the theory.
Also of note: I’ll be speaking at the Skillsmatter RoR eXchange 2007 on Feb 9th. Look forward to seeing you there.

Life is random. Introducing, the iPhone Shuffle. (Brasten Sager)
Object/anything mapping. A lot of people argue that ActiveRecord is not a serious/ideal/complete ORM layer. Maybe. But ActiveRecord did manage, in a very short time, to accomplish something many before it promised, but never quite delivered: to abstract data access. ActiveRecord can talk to SalesForce, LDAP, Amazon, [...]
CES came, CES went, and like every year, I ignored it. It might be the size of my apartment, or my checking account, but I don’t have a burning desire to own a TV that’s taller than me. Or to hook it up to a media center that can fit in my pocket. Nor am [...]

In Inline RJS I talked about invoking simple RJS actions right there in your controller. Did you know you can do the same in your views, with (among other helpers) link_to_function?
| 1 2 3 4 5 6 7 8 |
# before <%= link_to_function "Close", "$('some_div').down('form').reset(); $('some_div').hide()" %> # after <%= link_to_function "Close" do |page| page[:some_div].down('form').reset page[:some_div].hide end %> |
Furthermore, Sam Stephenson showed me a trick where you can use RJS in arbitrary helper methods to generate Javascript code. Don’t like inlining RJS as above? Then refactor it like this:
| 1 2 3 4 5 6 7 8 |
module SomeHelper def hide_and_reset(div) update_page do |page| page[div].down('form').reset page[div].hide end end end |
Then, in your view:
| 1 |
<%= link_to_function "Close", hide_and_reset(:some_div) %> |
That update_page method is defined in PrototypeHelper, and will return the generated Javascript as a string. Beware, though: whether you use update_page or a block passed to link_to_function, making use of inline RJS has a price. It’s fine if you only need to do it a few times on a page, but stick to explicit Javascript if you’re emitting lots of bits like that.

I predict that we're about to witness the birth of the Rails' community's very own "fireside chat."
Entre: CoderPath screencasts. The pitch? Instead of just the screencaster himself speaking, Miles Forrest is interviewing and chatting with others at the same time. Screencast meet interview-style podcast. It's a sweet idea. (And it doesn't hurt that they're free—an excellent addition to the...
Check out Slash7 for more -- and let me know what you think!

This is the first in a series of articles, discussing why
many software rewrite projects end badly and what
to do to avoid some of the ways I've seen them go astray.
You’ve got an existing, successful software product. You’ve hit
the ceiling on extensibility and maintainability. Your project platform is
inflexible, and your application is a software house of cards that
can’t support another new feature.
You’ve seen the videos, the weblog posts and the hype, and
you’ve decided you’re going to re-implement your product in
Rails (or Java, or .NET, or Erlang, etc.).
Beware. This is a longer, harder, more failure-prone path than you expect.
Throughout my career in software development, I’ve been involved in
Big Rewrite after Big Rewrite. I suspect it’s because I have an
interest in learning eclectic computer languages, operating systems, and
development environments. Not being just-a-Java-guy or just-a-Windows-guy
has led to me becoming a serial rewriter. I’ve been on projects to
replace C, COBOL, PHP, Visual Basic, Perl, PLSQL, VBX (don’t ask!)
and all manner of architectural atrocities with the latest and greatest
technology of the day.
In many cases, these Big Rewrite projects have resulted in unhappy
customers, political battles, missed deadlines, and sometimes complete
failure to deliver. In all cases, the projects were considerably
harder than the projects’ initiators ever thought they would be.
This is not a technology problem. It’s not at all Rails-specific, but
being in the limelight these days, Rails implementations are both very
likely to happen and very risky right now.
So, why, in software rewrites, when you’re traversing exclusively
familiar territory are the results so often unpredictable and
negative?
For the next week, I’ll post specific reasons I’ve seen things
go wrong. The following is a list which will eventually be made into links:
Stay tuned.
My hometown, St. Louis, is hardly one of the great meccas of the computing world. Places like San Francisco, Seattle, and New York were the first to have local training available. Yet, even here in St. Louis, if you want Ruby on Rails training you now have more than one choice (competition is good). Last year OCI unveiled local RoR training, and now Inspired Horizons is doing the same. I’d be willing to bet that this is quietly happening all over.
Help prove me right. Do you live in a place that is not considered one of the computing hot spots, yet you still have local Ruby or Ruby on Rails training available? If so, post a comment and tell us about it!

Yesterday (Wednesday, January 10th, 2007), there was a short discussion on the #rubinius irc channel which prompted a few questions which I thought would be best asked and answered here. Before I get to them though, I thought I'd share some context:
olabini: pate said something about Lisp on rubinius? wanna elaborate Evan? I'm drooling at the thought...
evan: Sure, since i started the project,

Although after some persuasion I’ve become somewhat of a convert to the church of JavaScript libraries, some (in fact, for me, most) smaller scripting tasks just don’t require a library. I’m a firm believer, especially with JavaScript, that simple is best. File size / download time arguments aside, the less code you can get away with having the browser parse and execute the better off you are. Less for the browser to do. Less to go wrong. Less to try to understand. In JavaScript development, I think this need for minimalism is as important as the need to write code for re-use which is one of the major aspect in which it differs from traditional software development wisdom. There are however some bits of code I can’t do without for any scripting task.
For years I’ve found myself copying and pasting the same old stuff into my script files before I write a single line. This is a tedious task so, while writing some code for the upcoming @media 2007 site, I decided to put together a JS file of absolute essentials. A set of functions I always use for any scripting task that isn’t a one-liner. It turned out to be an interesting exercise as trying to be absolutely minimal in anything often is. What code is always useful? Here’s what I came up with (in no particular order):
So, here are my JavaScript essentials posted for your reference. I’m not releasing this and I’m definitely not supporting it but some of you might find it interesting all the same. It’s worth making your own.
What are your JavaScript essentials?
Here's a fairly obscure but useful trick to optimize session usage in Rails. I can pretty safely bet that you haven't used it yet because it was broken until two weeks ago when, with bloody forehead, I discovered the bug that had been causing me to bang my head repeatedly on the table. Big kudos to Jeremy Kemper for assisting in the speedy fix. Anyway, where was I?
Oh yeah. Sessions.
Sessions are mostly useless. There, I said it. I'd guess that at least 95% of the time all people are using sessions for in Rails are flash messages and setting the :user_id of authenticated users. If your app doesn't authenticate users or have some other unusual need for sessions, it's a pretty painful waste of that overhead to use them only for flash messages.
Here's a fairly obscure but useful trick to optimize session usage in Rails. I can pretty safely bet that you haven't used it yet because it was broken until two weeks ago when, with bloody forehead, I discovered the bug that had been causing me to bang my head repeatedly on the table. Big kudos to Jeremy Kemper for assisting in the speedy fix. Anyway, where was I?
Oh yeah. Sessions.
Sessions are mostly useless. There, I said it. I'd guess that at least 95% of the time all people are using sessions for in Rails are flash messages and setting the :user_id of authenticated users. If your app doesn't authenticate users or have some other unusual need for sessions, it's a pretty painful waste of that overhead to use them only for flash messages.
One of the nice things about how Mephisto is designed is that only authenticated users get a session when they login to the admin console. (Yes, there are no flash messages.) That means that the kajillions of guest users who are just reading a blog don't get a session. And that removes a lot of overhead from serving up pages, especially when most of the pages are cached as static HTML (yay for Rails' page caching!). I think that was a great decision, but it became a pain when I decided I wanted to highlight comments I made in my own blog as special so readers could easily see which comments were mine.
The problem was that the main controller is configured with session :off, so no session was available to check to see if there was an authenticated user making the comment. Now, the admin controller has sessions on, so if I had already logged in on the admin console I'd have a session_id cookie in the browser, and the main controller could just notice it there and use it to get the commenter's user id to mark the comment as special. At least in theory. But you can't see an existing session with sessions turned off in your controller!
It turns out there is a lovely option on the session directive for controllers.
LazyController < ActiveController::Base
session :new_session => false
# ...
end
Using the :new_session => false option tells Rails not to create a new session if there isn't one already, but if there is, go ahead and use it. That's exactly what I needed, and it ended up working perfectly to let me hack Mephisto to mark my comments as special. (At least it did after Jeremy and I fixed the crashing bug.) If you use this option and there is no previously existing session, the session will appear as an empty hash. You can set values in that hash, but they won't stick around to the next action.
You can see the special comments in action right here in my blog - just look around. You can also use that feature in your own Mephisto blog, since Rick accepted my patch and now trunk will do that for you too. Check out the wiki page on how to do it.
And if you're not using Mephisto, you can still use the :new_session => false option to lighten the load on your web app. I think this is potentially very useful for RESTful apps. I like the idea of blending admin functions into the normal content UI. This way you can have sessionless guest users and still provide authorized admin features on public pages.
As part of some work I’m doing to make JRuby more portable and easier to run standalone without all the $JRUBY_HOME launcher scripts, it’s now easier than ever to get up and running with JRuby, or to launch in your build scripts or IDE in a platform-neutral way. (Note: as of this writing, this feature is in 0.9.3 jruby-complete snapshots older than 2007/01/11 only.)
Here, give it a try:
$ curl -o jruby-complete.jar http://snapshots.repository.codehaus.org/org/jruby/jruby-complete/0.9.3-...
$ java -jar jruby-complete.jar --command irb
irb(main):001:0>
RubyGems needs a place to unpack and run gems, so JRuby currently will hide all that away from you in ~/.jruby. (Also, unfortunately we exceed Java’s default memory size when downloading the RubyGems index file, so you’ll have to add the -Xmx256m argument for now to avoid an out of memory condition.)
$ java -Xmx256m -jar jruby-complete.jar --command gem install tattle -y --no-rdoc --no-ri
creating /Users/nicksieger/.jruby/bin/gem
... more files extracted ...
copying /Users/nicksieger/jruby-complete.jar to /Users/nicksieger/.jruby/lib
Bulk updating Gem source index for: http://gems.rubyforge.org
Successfully installed tattle-1.0.1
Successfully installed hoe-1.1.7
Successfully installed rubyforge-0.4.0
Successfully installed rake-0.7.1
You can still have JRuby unpack to a shared directory if you like, and use the regular shell scripts for launching JRuby. In this case, JRuby is actually replicating itself into the directory you choose. Simply add the bin subdirectory to your $PATH, and continue to use JRuby just as you would a regular Ruby installation.
$ sudo java -jar jruby-complete.jar --command extract /opt/local/jruby
Password:
creating /opt/local/jruby/bin/gem
... more files extracted ...
copying /Users/nicksieger/jruby-complete.jar to /opt/local/jruby/lib
$ PATH=/opt/local/jruby/bin:$PATH
$ which gem
/opt/local/jruby/bin/gem
$ jirb
irb(main):001:0>
The --command argument is not limited to just gem and irb. Once you’ve installed any gem that has an accompanying executable script, you can simply pass that argument as the --command:
$ java -jar jruby-complete.jar --command tattle report
ruby_install_name, jruby
LIBRUBY, jruby
target, java
arch, java
host_vendor, Apple Computer, Inc.
key, b1bd5eaf4254d9874ca297995b906be6f4975d395dd0136432f859c62a33cc8c
host_os, Mac OS X
ruby_version, 1.8.5
build, java
target_cpu, i386
prefix, /Users/nicksieger/.jruby
report_time, Thu Jan 11 22:21:57 CST 2007
rubygems_version, 0.9.0
host_cpu, i386
LIBRUBY_SO, jruby
SHELL, /bin/sh
$ java -jar jruby-complete.jar --command tattle
Posting information to Tattle server. Thanks!
And lo and behold, there’s a ruby_install_name of java at the new Gem Tattle homepage!
Time for a little honesty here. I actually had a fairly lousy month
in December--for the first time in almost two years I went through a
month where I didn't feel at the end like I was at all better at
what I do than I was at the month's beginning. Sure, I had
learned a lot
about Javascript,
but that's mostly been about extending Firefox/Conkeror and only
marginally related to What I Do.
I'm sure most of this was due to the fact that I spent most of the
month looking for work or waiting for projects to get started. I
tried to keep busy with personal projects and whatnot, but when I
finally did start on a Rails job at the beginning of this month, it
was a bit distressing how rusty I felt. Part of this was also due to
picking up both RSpec (more on this in a future post) and the new Restful style, which was a bit
disorienting. (Though Geoffrey's
excellent PeepCode
screencast helped a lot with that; give it a spin if you're having
trouble.)
I'm thinking I should take this as a bit of a warning to practice
Pragmatic-Programmer-style continual learning. It was a pretty
jarring experience, but it helped remind me that staying sharp and
active is a really important part of maintaining competence. Falling
into complacency is easy to do, especially when you really feel on
top of your game, but it gets you nowhere.

On an entirely unrelated note, when I was first getting into Ruby (around RubyConf '05),
I joked about how "Ruby
is becoming Lisp" because of some superficial changes
regarding how parameters were specified. Well it turns out some of
the
stuff they're doing with Rubinius could make that a reality;
you should be able to feed the Rubinius straight S-expressions,
and from there it's a short leap to providing a defmacro
facility.
Which is cool.
by Ben Bleything
This is a riff on the Jumble puzzle found in many (US) newspapers. More specifically, it's based on the game TextTwist[1], made by GameHouse[2] and published in various places around the web.
The mechanic of TextTwist is simple. The player is given six letters and is tasked with unscrambling those letters into as many words as possible. If the player can use all six letters in a word, they proceed to the next round.
Your task is to build the back-end engine to run a TextTwist clone. Effectively, this means that you must generate a list of three- to six-letter words that can all be constructed from the same six letters. This list must contain at least one six-letter word.
Bonus points for building a completely functional game!
[1]: http://games.yahoo.com/games/texttwist.html (just one example, java)[2]: http://www.gamehouse.com/
I've been interested for some time in the possibilities offered by bringing external data into virtual environments like Second Life. This data might come from the web, but it could also come from the real world - from physical sensors and interfaces.
Over the last couple of weeks I've enjoyed playing with the Arduino hardware prototyping board. This week's open-sourcing of the Second Life client came at exactly the right time for a new experiment.
Here's a video demonstration (people reading the feed, start your web browsers). On the left you'll see an Arduino reading analogue values from a potentiometer and feeding the results in via the USB-serial interface to my Mac. On the right, you'll see a modified version of Second Life that is feeding those values in via my avatar's chat channel. An object in the Second Life world is reacting, with perhaps a half-second lag.
How does this work? All it takes is a few small code fragments in the right places. The Arduino code is trivial:
void setup() {
Serial.begin(9600);
pinMode(0,INPUT);
}
void loop() {
delay(100);
Serial.println(analogRead(0));
}
The in-world LSL code is trivial:
vector pos;
default
{
state_entry()
{
llListen(42,"Matt Basiat",NULL_KEY,"");
pos = llGetPos();
}
listen(integer channel, string name, key id, string message) {
float val = (float)message;
llSetPos(pos + 0,0,(val/100.0)>);
}
}
The clever bit, such as it is, involves adding a bit of good old-fashioned Unix file-descriptor code to the SL client's idle loop (located in viewer.cpp in the source) that polls the Arduino. Once I've got the reading, all it takes to make my avatar speak to the server is the line:
gChatBar->sendChatFromViewer(reading, CHAT_TYPE_NORMAL, FALSE);
In total, I added about 150 lines of code to a single file to achieve this. Obviously this is just a concept demo, and there are plenty of places to take it from here, but I'm encouraged by the progress.
If you're curious about the details, here's the patch against viewer.cpp in the newview directory of the source. It's definitely not The Right Way To Do It - just the fastest route I could find into the heart of the code. It has hardcoded device names and other bad practice. I release it under the GPL, and must thank Tod Kurt for the use of his arduino-serial.c code and Massimo Banzi for everything he taught me about Arduino over the holiday season.

Have you ever done something like this in a controller?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# The corresponding view looks something like this: # # Name: <input type="text" name="person[name]" /><br /> # Email: <input type="text" name="email_address[address]" /><br /> # Phone: <input type="text" name="phone_number[number]" /><br /> # def create Person.transaction do @person = current_account.people.create(params[:person]) @person.create_email_address params[:email_address] @person.create_phone_number params[:phone_number] end redirect_to person_url(@person) end |
Harkening back to the Skinny Controller, Fat Model idea, I’ve lately been converting the above, into the following:
| 1 2 3 4 5 6 7 8 9 10 11 |
# The corresponding view looks something like this: # # Name: <input type="text" name="person[name]" /><br /> # Email: <input type="text" name="person[data][email_address][address]" /><br /> # Phone: <input type="text" name="person[data][phone_number][number]" /><br /> # def create @person = current_account.people.create(params[:person]) redirect_to person_url(@person) end |
This works by moving all of the creation logic to the models. Consider the Person model for the above:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Person < ActiveRecord::Base has_one :email_address has_one :phone_number attr_writer :data after_create :update_data private def update_data return if @data.nil? create_email_address(@data[:email_address]) if @data[:email_address] create_phone_number(@data[:phone_number]) if @data[:phone_number] @data = nil end end |
So, when the params[:person] hash gets used to create the new Person, the data subhash, if it exists, gets assigned to the data writer on the Person model. Then, after the create happens, the update_data callback is invoked, which examines that @data variable to see what needs to be done.
It keeps your controllers slim, and puts all the creation logic in one place, so if you ever want to create the email address and phone number from a different action, it’s all ready for you!
With a little more effort, this can work for updates and deletes, too, but I’ll leave that as an exercise for the reader. ;)

Tactile. What do you think? Is this just a glossy concept, or will people really be able to use it?
The Grinch who stole my brackets. James Bennett injects some humor (and wise words) into the debate: “The XML guys are sitting up on the mountaintop like the Grinch, with his pile of stolen presents, wondering [...]

Pat Eyler is running a Rails-related blogging challenge, in cahoots with Apress. The topic How has Ruby on Rails made you a better programmer? was proposed by Jarkko Laine.
How could I resist such a fertile topic? (Psst! The answer is: I can’t!)
Among other factoids, Pat and Jarkko are both Slash7 readers and sometimes commenters—hi, guys!
So Much Better, Baby
Really, Rails has made...
Check out Slash7 for more -- and let me know what you think!

Over in my 2007 Ruby prediction post on Linux Journal, I wrote:
Refactoring tools — This is something I think there's just too much clamor for (and too much momentum toward) not to hit in 2007. The JRuby team is making steady progress in NetBeans and Eclipse while wierd, wonderful things are being done with code rewriting on top of ParseTree and other tools. This year, we'll be able to stop
Well, it looks like I'm not the only one thinking about this problem. Dries Buytaert blogged about it (from a drupal perspective) a while ago. I'll be interested to see if this idea is useful to the Drupal community.
My original post also seems to be making the rounds, having shown up over on the squeak smalltalk list and on LWN (in a subscription only page, for now). I'm glad that people are
This is part 2 in our ongoing conversation tracking the development of JRuby.
It’s been exciting to see all the discussion between the JRuby developers and Rubinius developers, especially in #rubinius. What benefits do you see coming from this kind of cooperation?
Charles Nutter: Evan and I have been talking since this summer, actually, when he was working on early versions of Rubinius. We both have gone through many of the same growing pains dealing with Ruby’s quirkier features and evaluating interpreter/VM design options. I don’t know how Evan feels about it, but I was very glad to find someone else who was interested in such things.
Now that Rubinius is in the public eye and has some real momentum, there’s more sharing going on. We’ve been talking about those same design options, weighing them together and coming up with new choices we can both implement. Others on the Rubinius team have forwarded the idea of reusing portions of the Rubinius source in JRuby.
It’s also become apparent that we’re trying to solve very similar problems from different directions. In JRuby’s case, we already have a fully-functional Ruby interpreter, functional enough to run apps as complicated as Rails. Our challenge is to keep JRuby running well and evolve a working interpreter toward a more future proof, performant, and maintainable design. Rubinius is really just starting out, only to the point of running a small portion of the Ruby corpus, but the design is easier to follow and simpler to evolve. Their challenge is to keep the design simple while expanding compatibility and improving speed. JRuby is mostly Java with some Ruby code, though we’d like to make it more Ruby code in the future. Rubinius is obviously mostly Ruby code with some C, but they’re interested in being able to migrate it to other underlying languages. We’re both interested in a Java-based Rubinius.
I think it’s been very positive for everyone involved to have this level of cooperation, and it’s helped us all understand Ruby better.
Ola Bini: Well, the exchange with Rubinius is obviously very valuable. The more people working on implementations and sharing information, the better for all the implementations, of course. I also see Rubinius as something very intriguing, and it would be very interesting to see how much we could port to JRuby.
Thomas Enebo: I have not personally been in contact with Rubinius developers (Charles has though), but I can say more generally that many implementations will necessitate some level of cooperation. As we discover differences between implementations, we need dialogue to help understand why those differences exist. It is possible this dialogue will end up identifying poorly-identified cross-platform issues or general mis-features.
At an implementation level it will yield suggestions across the fence for how to do things differently. A thread in ruby-core a month or so ago had some exchanges on how MRI could be optimized. Charles and I chimed in about some of those ideas because we had considered and implemented some of them in JRuby. I think as time goes on, this exchange of ideas will increase.
The biggest news in Ruby land recently is probably the announcement of a fully merged YARV. What affect does this have on JRuby?
Thomas Enebo: This seems like great news for Ruby, but I am not sure it has much affect currently on JRuby. We are still focused on 1.8.x support. It is getting easier for us to change language semantics now and when 1.9/2 starts getting closer to release I feel comfortable that we can spin a Ruby 2 branch pretty quickly.
From a personal standpoint, it is great to see Ruby hit this next milestone. I think the perception of progress is pretty important and merging YARV will give Ruby 2 development a nice perceptual boost. Also this will mean many more people pounding on YARV, which will help run it through its paces better.
Ola Bini: YARV is important news. Very much so. But at the moment the effects will not be that noticeable. Right now we’re still working hard to get 1.8-compatibility complete. But, Charles have begun work on a YARVMachine that runs some basic scripts (including the famous iterative fib bench). I’ve started looking on this the last few days, and have some ideas. My first priority will probably be to implement a reader for YARV bytecode. This will make it easier to test our machine, since we can compile with YARV and then run the compiled files with JRuby. Alongside with that I am going to start tinkering on a new backend to Charles current compiler, so it will emit YARV bytecode instead. I’m not sure exactly when this is going to happen, though, but we try to stay on top of YARV.
Charles Nutter: The merging of YARV (no longer “yet another” Ruby VM but instead “the” Ruby VM) is a very big event for the Ruby world. Koichi has worked long and hard on it, and I’m very glad to see it’s now officially part of Ruby core. I had some time to talk with Koichi and Matz about implementation challenges at RubyConf 2006, and we came to agreement on a number of items, most prominently that critical= needs to go away. Again, more cross-project sharing.
We’re watching the newly-reset 2.0 design process closely, since we know it will eventually affect JRuby’s future. In the interim, however, we’re trying to solve at the 1.8 level many issues YARV is designed to solve in 1.9 and 2.0. So many of the design choices made by Koichi and Matz for 1.9 play directly into how we tackle those same decisions in JRuby.
I think in general the merging of YARV shows that Ruby is moving forward and evolving on all fronts.
As part of a larger consolidation effort I have taken down Rela.tv and gr.egario.us. They were mostly play apps for me and I’m moving on to other things. As my boss tells me, “you don’t want to dilute your brand…”
For the curious or nostalgic amongst you, you can get the source for both from my subversion repository:
svn co https://saucyworks.devguard.com/svn/projects/rela.tv/trunk rela.tv
svn co https://saucyworks.devguard.com/svn/projects/gr.egario.us/trunk gr.egario.us
And if either of these domain names appeals to you, let me know. I’m willing to transfer them over to you if you have a project or cause that speaks to me (and even if you don’t have such a cause…)
tags: rails, rubyonrails, rela.tv, gr.egario.us
I was talking with a friend of mine last week about the new Rails deprecation warnings that you’ll see when you do naughty things like access @cookies from your controller or use deprecated methods like ActiveRecord’s find_all. Sometimes it’s useful to turn off those warnings – especially when they’re coming from a part of your application you don’t control (i.e. a third-party library).
To turn off all deprecation warnings, just do the following:
ActiveSupport::Deprecation.silenced = true
Or, if you want to perform something other than spit out deprecation warnings you can re-route them however you want within a block:
ActiveSupport::Deprecation.behavior = Proc.new { |msg, stack| MyLogger.warn(msg) }
Or, if you want to be more granular, you can silence specific parts of your code that you know reference deprecated code:
def bad_action
ActiveSupport::Deprecation.silence { p "Referencing #{@cookies} is bad" }
end
Hopefully this will get you past any annoying deprecations you can’t do much about (without giving you an easy out for those that you can do something about).

Your mission, should you choose to accept it, is to find the secret message
hidden in that Ruby script, follow the instructions to generate the code that
will prove you've found the message, and claim your chance to win a (very)
modest prize at http://eigenclass.org/rubychallenge2007/YOURCODE .
The completion times will be recorded and Kernel#rand will also pick a few lucky winners.
Here's what people had to say about a similar puzzle I made last year:
Wow, I'm really impressed. That was a tough (and fun) puzzle. -- Kevin Ballard
Thanks Mauricio, you made my day! -- olivier
My head hurts. Took me nearly two hours -- aniero
Anything from a few minutes (say 10-20 minutes if you're having a good day and
aren't easily scared off by tricky Ruby code) to several hours. Many will give
up before, though :-) I cannot really know, but I can say I've spent quite some time making this fairly tricky...
There's a different script for each supported Ruby version; get the one
corresponding to your ruby executable or you won't be able to run it at all,
let alone crack it.

We all know and love RJS templates in Rails. (If you don’t, please do google them and read up—you’re missing out on some of the hottest stuff around.). I honestly believe they are the most significant advance in web development technology since the introduction of XmlHttpRequest.
Sometimes, though, it seems like a bit of overkill to have to create a new file if all you’re doing is highlighting some element, or removing one. If your action only responds to “text/javascript” requests, it’s often much simpler just to inline the RJS calls, right there in your controller:
| 1 2 3 4 5 6 7 |
class ItemsController < ApplicationController def destroy @item = current_account.items.find(params[:id]) @item.destroy render(:update) { |page| page[dom_id(@item)].remove } end end |
(Note that the dom_id helper is courtesy of the simply_helpful plugin.)
That call to render(:update) just yields the RJS page instance to the block. Then, you can do all your RJS calls in the block, instead of having to create a file for a single line of code.
When would you not want to do this? Well, if your RJS stuff is particularly complex, or does more than a handful of things, you might be better off throwing it in its own template. Also, if your action responds to more than just RJS (e.g., via the respond_to method), you should use a separate RJS template file as well.

One of my favourite features in Event Wax is the help sidebar in the admin area. The interface itself is kept pretty clean but if you need help on a particular page you can just open the help which shows the relevant help page. This way we avoid filling the screen with prompts and help content that will get in the way of experienced users but still give new users plenty of help if they need it.
The help content is in fact taken from the help site which resides at eventwax.com/help but is re-purposed and pulled into the help sidebar via Ajax. This way we have a searchable, printable plain HTML version of the documentation for users to refer to if needed but are able to provide context sensitive help to users as they use the application. Of course, this is all implemented unobtrusively and still provides users with a decent experience if for some reason JavaScript isn’t behaving. Here’s how:
Firstly, we define the inline help link and a div to hold the help content:
<a href="/help/your_account/your_event/the_attendees_tab" id="hlink"><span>Help</span></a>
<!-- code omitted for clarity -->
<div id="help"></div>
Notice that the href of the link is pointing to the location of that particular help page in the regular site so as it stands now our help link will just send us through to the correct documentation. In order to pop up the content in a side bar I’ve implemented a help script that’s responsible for opening and closing the sidebar by applying a class to the help div and triggering an Ajax.Updater request to fill it with content. I’m not going to show that here but you can check it out if you like. Essentially this gives us Help.show(url), Help.hide() and Help.toggle(url) to play with.
Now we can use UJS to apply some behaviour and make our sidebar come alive:
<% apply_behaviour '#hlink:click', 'Help.toggle(this.href); return false;' %>
This catches the help links click event and instead triggers the sidebar to open and close. We call Help.toggle() to open the sidebar passing in the href of the link as the content to get to place in the help div. At this point, it’s all pretty much working but there’s one snag: there are links inside the help content and we want them to change the sidebar rather than link normally. Time for some more UJS:
<% apply_behaviour '#help a:click', 'Help.open(this.href); return false;' %>
We hijack the click events of all the links inside the help div and make them call Help.open() with their href instead of their default behaviour which causes them to open within the sidebar. Sorted.
There’s a final problem to solve. The normal help content is going to need to be inside a full HTML document with a header and footer while the help content in the sidebar doesn’t need any of that. We solve this with a bit of Rails magic. The Help controller that displays the help pages looks like this:
class HelpController < ApplicationController
# displays a page of help given the path
def page
# page finding code ommitted for clarity
respond_to do |type|
type.html { render :file => page, :layout => :help }
type.js { render :file => page, :layout => false }
end
end
end
This means that requests for help pages via Ajax get no layout and just get the html content and normal requests get the whole page, doctype, html tag and all. As you can see it would be easy to dispense these pages in lots of other formats if we need to.
So that’s that…As you can see, it’s really quite simple to get some impressive features working unobtrusively, especially with Rails and UJS. In coming posts I’ll highlight how I went about implementing some of the other features of Event Wax but in the meantime register and check out the application and plan an event while you’re at it. Get it while it’s free!
Hey! You’re a cheater!
Well, if you’re not… I’m hoping to make one out of you.
“A thing worth having is a thing worth cheating for.”—W. C. Fields
I’m a fan of the PDF cheat sheets as I like the consolidated content contained in them. However, I don’t like having to read PDFs any more than I have to. Printing them isn’t always ideal either as I really don’t like to carry around extra paper in my laptop bag. So, what are we to do?
Well, you can cheat the system! ...and I’m going to show you how!
Cheat is this really nice command-line tool that outputs a plain text cheat sheet whenever and wherever you want.
Like all the happy and good Rubygems, this is quite simple…
$ sudo gem install cheat
Done! Okay… let’s try to do some cheating. Don’t worry, your friends and family will forgive you.
To view a cheat sheet, just run the cheat command from your favorite terminal window.
$ cheat _cheat name_
So, for example… to see the cheat sheet for RSpec, run cheat rspec.
$ cheat rspec
rspec:
INSTALL
=======
$ sudo gem install rspec
$ ./script/plugin install
svn://rubyforge.org/var/svn/rspec/tags/REL_X_Y_Z/vendor/rspec_on_rails/vendor/p
ugins/rspec
Where X_Y_Z is the version number.
$ ./script/generate rspec
create spec
create spec/spec_helper.rb
create spec/test2spec.erb
create test/test2spec_help.rb
create script/rails_spec
create script/rails_spec_runner
HOW TO USE
==========
./script/generate rspec_model User
####################################################
# truncated to save precious bandwidth
####################################################
Because this is all printing out in your shell, you can take advantage of your favorite command line tools.
$ cheat rspec | grep 'equal'
@user.errors.on(:username).should_equal "is required"
target.should_equal <value>
target.should_not_equal <value>
$ cheat rspec | mate
Head over to this list of cheats to see what is currently available.
Thanks to the Err team for putting this together!
Several months ago, I heard that people were using a program called autotest to have their tests continue to run as you made changes to your code base, which comes with ZenTest. It’s a really nice tool written by Ryan Davis and I hadn’t gotten a chance to play with it as of yet. Well, our team isn’t spending too much time in the test/ directory these days as we jumped ship near the end of last summer and found ourselves hanging out on the Isle of BDD. The locals are quite thoughtful about these sorts of things.
I just started working on a project that has been under development for several months and as I’m getting to learn the ins/outs of the system, I find myself having to rerun the specs, which can take quite a bit of time watching. Watching your specs or tests run sometimes is as productive as watching your code compile. Oddly enough, this is as close to compilation as we really get when working with Ruby on Rails… and it’s a productivity killer for me.
So, I did a quick google search and found an announcement for Rails that ran specs through ZenTest. This was exactly what I was searching for!
Please makes sure that you have the following gems installed in your development environment as they are dependencies to make this all work.
$ sudo gem install zentest diff-lcs
note I’m going to assume that you have rspec and rspec for rails installed… if not… tsk. ;-)
$ script/plugin install http://svn.caldersphere.net/svn/main/plugins/rspec_autotest
If you’re using subversion, you might consider installing it as an external.
$ script/plugin install -x http://svn.caldersphere.net/svn/main/plugins/rspec_autotest
This is where it gets tricky. ;-)
$ rake spec:autotest
Now, you can keep a terminal window open and autotest will watch your application and detect when files change. When they change, it’ll attempt to rerun your specs (specifically those that changed). This helps save you the time of having to rerun all your specs throughout the development process and keep your spec:all sanity checks for when you’re about to commit code to your repository.
I’ll post another entry in the next few days to show you how you can use Growl with RSpec Autotest to keep you from having to look at your terminal all the time.
Until then… have fun!
After two days and 562 tattle reports a picture of rubyists' operating system choice is emerging:
$ ruby filter_host_os.rb tattle-host_os-20070110-1053.yml
darwin8: 242
linux-gnu: 161
mswin32: 116
freebsd6: 16
solaris2: 7
darwin7: 5
cygwin: 4
openbsd4: 4
linux: 2
freebsd5: 2
darwin9: 2
openbsd3: 1
Generated from:
$ cat filter_host_os.rb
require 'yaml'
data = YAML.load ARGF.read
collapsed = Hash.new 0
data['host_os'].each do |os, count|
os =~ /^(.*?)(\.|$)/
collapsed[$1] += count
end
length = collapsed.keys.sort_by { |k| -k.length }.first.length
collapsed.sort_by { |o,c| -c }.each do |os,count|
puts "%#{length}s: %d" % [os, count]
end
(Consider this an entry for the contest.)
The question how Rails made me a better programmer can be answered in
a short, but incomplete and actually wrong way: It didn’t.
That is only half the truth. When Rails was released in 2004, I
already had almost three years of programming experience in Ruby.
Therefore, I don’t think I learned much from Rails in a technical way.
I knew MVC, the code didn’t particularly impress me, and, in the end, I
didn’t care a lot about web development either. At that time, at least.
The things I’ve learned (or everyone could learn) from Rails are
social lessons. Some of them were to be expected, some were very
unexpected and a few still make me question the universe everytime I
think of them.
So, what did I learn from Rails?
Community matters. The best idea is useless even in the literal
sense if nobody uses it. I did not learn that directly from Rails,
since Ruby had (and still has) a very nice, but at that time rather
small community. (Which is not necessarily a bad thing.)
Don’t underestimate the community. I primarily noticed this
attending RailsConf Europe. Almost everybody I talked to really
knew his/her stuff well, and lots were really experienced in Ruby,
too. Of course, it was a rather small and exclusive selection of
Rails users, and they had enough time to learn Ruby until September
2006.
Don’t overestimate the community. Scaling a community is hard, and
Rails soon got into a storm of newbies from Java and PHP camps.
The eager and clever people of these can learn and pick up
everything. The rest proably still lurks in #rubyonrails waiting
for their answers. Just because something was made easy, it
doesn’t mean it’s less complex in itself, there is less to learn or
less to think. Rails may be easy to use, and quick to get started,
but it’s not a silver bullet, and designing, programming and
deploying a real life website is still demanding.
Learn to sell. Before Rails, one rarely saw a screencast, but they
are a great way to convince people of some piece of software
quickly—there is no denying. The whole “PR” of Rails worked very
well in the end. Everyone now knows about it. But also see 3.
Opinions help you and the users. Writing a totally generic
framework without any defaults and conventions turns out to be lots
of effort for the users. The less opinionated the software is, the
bigger the possible userbase becomes, at the cost of passion.
Avoid this. Rather, enable useful (to you) defaults, and make
going beyond them not cost flexibility, but convenience. The users
with vastly different needs will find a different solution (cf. 7).
Gauge evolution and revolution. In the end, Rails is just
meta-programming the boring tasks of web development—there is
nothing really revolutionary, at least compared to more
“advanced” frameworks based on continuations and so on. However,
this technically slight evolution had a huge effect, while a more
revolutionary framework would have had an even harder time to get
acknowledged and appreciated.
Everything has its niche. Many thought that with Rails’ uprising
the other Ruby web frameworks had no chance. It turned out to be
wrong: today there are more Ruby web frameworks that ever (we still
have a long way to go to catch up with Python, though ;-)). If you
absolutely can’t stand Rails, of if it simply doesn’t satisfy your
needs, just check them out. Or write your own.
Mastering anything takes time. It’s rare nowadays, but it
occasionally still happens that I discover a Ruby method/trick/dark
corner that I haven’t heard of before, despite year long learning and
using the language. The same is true for Rails, both for its users
as well as its programmers. Lots of Rails programmers came to Ruby
via Rails, and lots of them probably today bitch as much as me
when I have to read some piece of their early code. That’s not
a problem by itself, but one needs to recognize that even though
doing Ruby for, say, half a year, mastery has not been reached.
Furthermore, if you realize an often used piece of code is written
in a newbie style, don’t hesitate to refactor.
Success comes after the hype. There have been times I’ve pondered
myself for not really liking Rails, but just like in real life,
people quickly recognized that Rails is not paradise either. Just
about everybody stumbled over some rough parts, got bitten by a
nasty bug, or completely became befuzzled trying to add more magic
to ActiveRecord. And a fair lot admit that Rails could be better
than it is. However, people still use it. Even a big part of
these critics uses it, and some make their money with it. Rails
clearly survived the hype, and still looks good. This can be known
only afterwards, though.
Make programming fun. With Rails as with Ruby, one often sees the
word “fun” in the same sentence as the word “programming”. As a
hobbyist programmer, I pity people that need to program non-fun
stuff, and I knew all the time that I vastly prefer fun
programming. Guess how happy I was when I found Ruby.
NP: Bob Dylan—Visions Of Johanna

awk’s not deadAt Values of n, we branch our codebase to create a safe environment for experiments or non-trivial changes to Stikkit. After spending a week on the east coast for holidays, I had the cough pleasure of merging over a weeks’ changes into my branch to keep current.
In my first approach, I tried merging everything at once. I ended up catching a multitude of conflicts – some of which made no sense since I was missing a weeks’ worth of context in a fast-paced environment. Clearly that was not the way to go.
My second attempt: divide and conquer. Using our revision history to look up changesets, I merged a day’s worth of changes at a time. Because a small number of issues tend to prevail on any given day, this allowed me to deal wih actual conflicts as they came. Actual, meaningful conflicts as opposed to conflicts in binary files or code I haven’t touched.
For reverting and resolving files I had no interest in, I learned the smallest bit of awk.
svn st | awk '/^C/ { print "svn revert " $2 | "sh"; print "svn resolved " $2 | "sh" }'
This handy one-liner finds all conflicted files from the output of svn status, reverts them, and resolves them, allowing me to proceed. Other awk invocations resolved conflicts for a particular set of files by copying them from another directory and resolving. Familiarity with tools like lex and racc made awk a cinch to learn and more useful than I would have guessed.
Open question: what small-time automation do you rely on to support regular development?

In My Job Went to India, I talked about using supply and demand as a gauge with which to make decisions about which technologies you should invest in as a software developer:
The offshore market has injected its low-cost programmers into a relatively narrow set of technologies. Java and .NET programmers are a dime a dozen in India. India has a lot of Oracle DBAs as well. Less mainstream technologies are very much underrepresented by the offshore development shops. When choosing a technology set to focus your career on, you should understand the effects of increased supply and lower prices on your career prospects.
As a .NET programmer, you may find yourself competing with tens of thousands of more people in the job market than you would if you were, for example, a Python programmer. This would result in the average cost of a .NET programmer decreasing significantly, possibly driving demand higher (i.e., creating more .NET jobs). So, you’d be likely to find jobs available, but the jobs wouldn’t pay all that well. The supply of Python programmers might be much smaller than that of .NET programmers with a demand to match.
If the Python job market were to support noticeably higher prices per-programmer, additional people might be attracted to supply their services at this higher price range, resulting in competition that would drive the price back down.
The whole thing is a balancing act. But, one thing seems certain (for now). India caters to the already balanced IT services markets. You don’t find mainstream Indian offshoring companies jumping on unconventional technologies. They aren’t first-movers. They generally don’t take chances. They wait for technology services markets to balance, and they disrupt those markets with significantly lower per-programmer costs.
Yesterday, one of the Rails Core guys passed along an interesting link to and article called Who’s Searching for XML? by XML noteworthy, David Megginson.
David used Google Trends to compare and contrast where searches for certain technologies were coming from geographically. Have a look at a few:
Now look at these:
As David says, it’s totally unscientific. But if I were a young programmer trying to figure out where to invest my time, I might spend just a little of it on Google Trends researching who I’m likely to be competing with.
Chad Fowler: I was thinking we could deploy this on rubygems.org and maybe open up the source for a few collaborators.
RE: Gemtacular.com. Added to hoodwink.d, if you want to comment on gems. Also related and interesting: Dr. Nic and Erik Kastner offer Gem metastuff in JSON.

Redundancy. So we know some languages (*cough*java*cough*) thrive on verbosity and have a lot of redundancy. And we know redundancy interfers with your frontal debugging cortex. But how do you measure the amount of redundancy? Compress the source code! Eric did just that. Scientific? Maybe. But definitely a cool party trick.
Type casted. If marriage was [...]

I really, really love the feature of ActiveRecord that lets you extend arbitrary associations with additional methods. For instance, suppose you have some Project that can have multiple Tasks:
| 1 2 3 |
class Project < ActiveRecord::Base has_many :tasks, :dependent => :delete_all end |
Now, what you want to be able to do is partition the tasks association into subcollections based on the status of the tasks. One way to do that is by using extra associations with conditions:
| 1
2 3 4 5 |
class Project < ActiveRecord::Base
has_many :tasks, :dependent => :delete_all has_many :active_tasks, :conditions => "status = 'active'" has_many :inactive_tasks, :conditions => "status = 'inactive'" end |
That works…but it feels messy to me, like it is cluttering the Project namespace unnecessarily. What I want to be able to say is something like “project.tasks.active” and have it return me a list of the active tasks. Like this:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Project < ActiveRecord::Base
has_many :tasks, :dependent => :delete_all do def active(reload=false) @active = nil if reload @active ||= find(:all, :conditions => "status = 'active'") end def inactive(reload=false) @inactive = nil if reload @inactive ||= find(:all, :conditions => "status = 'inactive'") end end end |
There! But…it’s a bit verbose, isn’t it? I find myself using this particular scenario quite frequently. To save myself some keystrokes, I can just define an extra method on the core Module class:
| 1 2 3 4 5 6 7 8 9 10 |
class Module
def memoized_finder(name, conditions=nil) class_eval <<-STR def #{name}(reload=false) @#{name} = nil if reload @#{name} ||= find(:all, :conditions => #{conditions.inspect}) end STR end end |
Armed with that extension, I can minimize the active and inactive helper methods to just:
| 1 2 3 4 5 6 |
class Project < ActiveRecord::Base has_many :tasks, :dependent => :delete_all do memoized_finder :active, "status = 'active'" memoized_finder :inactive, "status = 'inactive'" end end |
It is worth noting here (since if I don’t, someone else will) that you could also define those “active” and “inactive” methods on the Task class itself, as class methods, and then call them from tasks association (since associations delegate missing methods to the association’s class):
| 1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Task < ActiveRecord::Base def self.active find(:all, :conditions => "status = 'active'") end def self.inactive find(:all, :conditions => "status = 'inactive'") end end project = Project.find(:first) project.tasks.active project.tasks.inactive |
The reason I generally prefer to avoid that in cases like this, is because I want to be able to memoize the result. In other words, I want to be able to call “project.tasks.active” multiple times and have it only query the database on the first call.
Also, I like having the finders on the association, rather than the class, because I almost never want to search the entire database for (in this case) all active tasks. Rather, I want to find all active tasks for a specific project. If you define the methods on Task, you are kind of giving the impression that you expect to call them unscoped.

Pat Eyler is running a Ruby blogging contest, sponsored by Apress, and the first month’s topic is Rails Revelations: How Rails made me a better programmmer. Read the requirements at that post, and then write up your article and post a link to it in the comments here. Pat Eyler, Apress editor Jason Gilmore, and Jarkko Laine will judge the entries, picking a winner in February. Go to it!

Early in my career, I worked as a computer support person in the IT department of a state university. There was a batch of us that came in at the same time. We all started at the help desk, worked our way into doing service calls around campus, and eventually graduated to back-room system administration or programming.
After you graduated into the back room, the next step was to get a real job. I mean, the university job was fun, but the pay wasn’t so great. Especially if you started as a help desk person. Minimum wage is a bad starting point to get increments from as a computer professional. So, for that reason, back in the back room it was pretty common to hear colleagues on phone interviews.
A close friend of mine had a particularly funny interview that a few of us heard his end of. It went something like this:
“I haven’t used Windows NT Advanced Server, because there’s no such thing. I’ve done advanced things with NT Server.” He said it snottily. Still sore from sitting at the help desk helping users with their “FTP” problems, he found it difficult to hide his distaste for ignorance. The problem is, there actually was such a thing as Windows NT Advanced Server. He just hadn’t heard of it. Before he finished the interview, another friend went into his cubicle, retrieved a copy of Windows NT Advanced Server, and place it on his desk.
This brings us to the point of this post. Yesterday, registration for Pragmatic Studio’s March Advanced Rails Studio in Chicago has opened. So far this year, we’ve only got one of these on the schedule, and they tend to sell out fast. Mike, Dave, and I are proud of what we’ve put together for this class. We did the first one back in the fall and got great reviews from the attendees. It was a joy to teach and (we think) a joy to attend.
Just to be clear, being pretty close to what’s happening in the Rails world, I can confidently tell you that there’s no such product or piece of software as “Advanced Rails”. But we’ve done advanced things with Rails, and we’re going to show you how. :)
Back in November, I did a presentation for the XP West Michigan at the Atomic Object office in Grand Rapids. They’ve recently posted the talk to Google Video.
The talk was titled “Don’t Follow the Lemmings” and is a continuation of the thoughts laid out in my book, My Job Went to India.
It being on Google Video, you can watch it online (embedded here, in fact) or download it to your computer or iPod for off-line viewing (a discovery I’ve recently made which makes plane trips much more enjoyable).
Watching on an iPod should be fine, because there are no slides to squint at.
<embed salign="TL" bgcolor="#ffffff" scale="noScale" src="http://video.google.com/googleplayer.swf?docId=-8984753198261505541&hl=en" type="application/x-shockwave-flash" id="VideoPlayback" flashvars="playerMode=embedded" quality="best" align="middle" style="width:400px; height:326px;"> </embed>
Well, they must be listening to me.
A few months ago, I posted that I was looking to switch mobile services. Well, I switched over to Cingular after a lot of back and forth and have been fairly happy with their service. I opted to get their lowend/entry phone as I wanted to get a nicer phone when I found something that met my requirements.
I wanted…
Well, I hadn’t found anything that really caught my attention. So, I heard rumors about Apple releasing a phone in January. So… I waited.

“Yay Apple! I think I’m in the right office, we’re all sitting here reading the keynote updates.”—Audrey
So, how much is this going to cost us? ..a few of us here came up with our predictions.

Thank you, Apple!
...well… I would have given Apple a hug if I didn’t have to wait til June.
![]()
...back to work.
Although I hate to admit it, yes, I've been developing web applications with Rails for almost two years and I've just started using Capistrano for application deployment. Why has it taken so long?
I suspect that if you're like me (i.e. a Windows guy) you've found this whole new world of Linux, Apache, lighttpd, mongrel, etc, etc. daunting. So at first glance, Capistrano can certainly be a bit intimidating. When I read the list of assumptions Capistrano makes about your Rails app for the first time last year, I was really only able to see one bullet point:
Fast forward to the present day. I'm feeling more comfortable with the Linux command line. I have a solid understanding of Subversion and mongrel and even Apache. So why not give Capistrano another go?
In short, it's very powerful. And surprisingly, for most things you might want to do, it's actually quite simple. Sure beats the pants off of SSH'ing to your production server and managing it by hand all the time. If you've been meaning to give it a try, go for it - I promise, it's worth it.
Highly recommended is the Peepcode Screencast on Capistrano Concepts. Although released about two month too late for me (arggh!), it is simply the best way to get yourself up-to-speed.
(Disclosure: Peepcode is a paid sponsor of this blog.)
If you develop on OSX and want to try out image_science, things just got even easier:
% sudo port selfupdate
% sudo port install freeimage
% sudo gem install image_science
I welcome any and all help on the linux side to get freeimage packaged up in their various packaging systems. It'll make it easier to get freeimage accepted on various ISPs/ASPs.
FreeBSD already has a port. It is a bit old but I think it should actually be compatible.
Rails is all about some open-ness and interopability and it has become incrementally easier to achieve this with the new Resource Feeder plugin. This plugin gives you an easy way to create RSS and Atom feeds in your controllers from a collection of model objects with the use of the rss_feed_for and atom_feed_for methods:
class PostsController < ActionController
# Build an rss feed
def rss
render_rss_feed_for Post.find(:all, :order => 'created_at DESC',
:limit => 10)
end
# Build an atom feed
def atom
render_atom_feed_for Post.find(:all, :order => 'created_at DESC',
:limit => 10)
end
end
So how do these feed methods know how to pull information from each individual resource of the collection? It uses a combination of options passed into the feed methods and specific properties of the resource. If you don’t pass any options into these feed methods your model objects should have title, description and created_at reader methods (and updated_at for atom).
There are several options you can pass into these nice little feed methods to customize the title of the feed and most of the other feed elements. Here’s my attempt at enumerating all of them for RSS:
Feed options (w/ defaults):
Individual item options (w/ defaults). These are the method symbols used to retrieve the proper values from each individual object:
General options:
Just pass in these options to your feed methods as needed:
class PostsController < ActionController
# Build an rss feed
def rss
render_rss_feed_for(Post.find(:all, :order => 'created_at DESC',
:limit => 10),
{ :feed => {:title => "All posts"},
:item => {:title => :name,
:pub_date => :updated_at} })
end
end
Feelin’ sassy? Try taking advantage of this guy :
class PostsController < ActionController
# View a collection of posts. If "format" is specified
# will return view of that type (of either rss or atom format)
# /posts/list?format=rss => RSS
# /posts/list?format=atom => Atom
def list
@posts = Post.find(:all, :order => 'created_at DESC',
:limit => 10)
options = { :feed => {:title => "All posts"},
:item => {:title => :name,
:pub_date => :updated_at} }
respond_to do |wants|
wants.html
wants.rss { render_rss_feed_for @posts, options }
wants.atom { render_atom_feed_for @posts, options }
end
end
end
It just feels so right sometimes!
oh yeah, and to install this pup just do:
script/plugin install resource_feeder
tags: rubyonrails, rails, rss, atom
For the second time I’ve had my virtual hand slapped for trumpeting a poor usage of with_scope . For the record, I want to make it clear that one should be using the rich domain model that active record provides to operate on associated objects: user.assets.find() and user.asset.create() instead of scoping to a user as my and Roman’s examples implied. Just a case of not thinking hard enough to come up with an appropriate example. Sorry David, won’t happen again!
I’ve mentioned the Meantime filter plugin by Roman Le Negrate in the past as a very useful little utility – apparently the core team agrees as around filtering is now part of edge Rails.
Usage is pretty much the same as with meantime:
class AssetController < ActionController
before_filter :verify_login
around_filter :benchmark
def assets
@assets = Asset.find(:all)
end
def benchmark
benchmark("Asset benchmark") { yield }
end
end
You can also define a class to handle your filtering needs (whose filter method yields to the action block)
class AssetController < ActionController
around_filter BenchmarkFilter # or BenchmarkFilter.new
...
class BenchmarkFilter
def filter
benchmark("Benchmarking...") { yield }
end
end
end
Or you can directly pass a Proc in as the filter:
class AssetController < ActionController
around_filter (:only => :assets) do |controller,action_block|
controller.benchmark("Benchmarking...") { action_block.call }
end
...
end
Since the around filter explicitly governs the execution of the action being requested, you can use them to skip the action completely. This would act the same as a before_filter that returned false.
tags: rubyonrails, rails
This may not seem like a biggie, but we all know you haven’t gotten around to prettying up your error pages yet..
The new, pretty, 404 error page
and
The new, pretty, 500 error page
It’s the little things sometimes…
tags: rubyonrails, rails
It’s gotta be right around the corner, right?
The REST client framework, ActiveResource, has been pulled from the up and coming Rails v1.2 release.
I’ve been using it to develop some REST client libraries and there are some refinements I can see being needed, but I don’t know if that’s the reasoning for its exclusion in the up-coming release. As a quick refresher – ActiveResource is the client framework that lets you invoke REST services from model objects. Think of it as ActiveRecord for REST.
However, get your REST panties out of their collective knot – you can still develop completely RESTful apps using the Simply RESTful server side functionality and the link helpers for enhancing the web tier with REST compliant requests.
Thanks to Tom of GiftHat for beating my feedreader to the punch on this one.
tags: rails, rubyonrails, REST
If you’re just not happy with some of the existing options out there for doing Http Authentication in Rails, we’ve got another entry into the market. There’s now an official Rails http authentication plugin in the Rails repo that makes this a simple proposition.
A few convenient methods are now available to you in your controllers to hold your hand: authenticate_or_request_with_http_basic that hands the basic username and password to a block for evaluation and request_http_basic_authentication that asks the client to authenticate itself using http basic authentication. Using them is pretty simple – their inclusion in an authentication filter seems to be the most intuitive use:
class DocumentsController < ActionController
before_filter :verify_access
def show
@document = @user.documents.find(params[:id])
end
# Use basic authentication in my realm to get a user object.
# Since this is a security filter - return false if the user is not
# authenticated.
def verify_access
authenticate_or_request_with_http_basic("Documents Realm") do |username, password|
@user = User.authenticate(username, password)
end
end
end
When the block of authenticate_or_request_with_http_basic evaluates to false, request_http_basic_authentication is invoked which requests that the user enter their credentials. You can also manually invoke request_http_basic_authentication if you are doing a mix of authentication methods and want to use http authentication only if session authentication fails etc…
So what’s with the “plea”? Well, digest authentication hasn’t been added to the plugin yet – though the structure and framework as all but been laid at your feet to contribute the digest logic yourself. Take a look at HttpAuthentication::Digest and see how easy it would be to contribute back to your favorite framework. Just fill in those tiny places that say stuff like # Fancy nouncing goes here and # You compute me and the world will revere you.
tags: rails, rubyonrails, http authentication
The most-requested feature for RubyGems is the addition of a platform preference for automating installs and ignoring gems for the platforms you aren’t on. In order to help get there, Jim, Chad and Bruce have put together tattle:
At the first Rails Edge conference, Jim
Weirich, Bruce Williams, and I were chatting about how to improve theRubyGems platform-specific behavior, when we realized that it would be really helpful to have more info about the install footprint of the Ruby community at large.
So instead of going right into hacking RubyGems as was our plan, we
created a little census tool and an accompanying web site to help us
collect information. Most of the info we collect is from
Config::CONFIG, with the addition of the RubyGems version.We know this information will help the implementers of RubyGems, and
we hope it will also help Ruby implementers and library developers as
well.To install:
$ sudo gem install tattle
To submit your info:
$ tattle
If you want to see what would be posted before posting, you can do:
$ tattle report
The information gets posted to http://tattle.rubygarden.org. You can
view the posted data with your web browser at that URL.
—Tattle: The Ruby Census via ChadFowler.com

At the first Rails Edge conference, Jim
Weirich, Bruce Williams, and I were chatting about how to improve the
RubyGems platform-specific behavior, when we realized that it would be
really helpful to have more info about the install footprint of the
Ruby community at large.
So instead of going right into hacking RubyGems as was our plan, we
created a little census tool and an accompanying web site to help us
collect information. Most of the info we collect is from
Config::CONFIG, with the addition of the RubyGems version.
We know this information will help the implementers of RubyGems, and
we hope it will also help Ruby implementers and library developers as
well.
To install:
$ sudo gem install tattle
To submit your info:
$ tattle
If you want to see what would be posted before posting, you can do:
$ tattle report
The information gets posted to http://tattle.rubygarden.org. You can
view the posted data with your web browser at that URL.
As a side note, Eric posted the latest RubyGems beta this weekend. Please do give it a go if you’re so inclined.

ActiveRecord is cool and all, and it goes without saying that we all trust its judgment, but sometimes you just want to watch while it does its thing. For instance, just today, I wanted to verify that, in edge Rails, ActiveRecord no longer loads the entire collection when doing a scoped “create”.
In other words, consider the following snippet:
| 1 2 3 4 5 6 |
class Account < ActiveRecord::Base has_many :people end account = Account.find(:first) person = account.people.create :name => "Jamis Buck" |
Before Rails 1.2, that last line would actually load all of the people in that collection, before creating the new person. This was problematic if the collection had thousands of rows, because a simple insert suddenly became a monstrous resource sink.
So, how to verify that the collection is no longer being loaded?
Did you know you can install your own logger instances in Rails? Yah, you can. And yah, it’s pretty cool:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ script/console >> ActiveRecord::Base.logger = Logger.new(STDOUT) => #<Logger:0x2814134 ...> >> account = Account.find(:first) Account Load (0.000346) SELECT * FROM accounts LIMIT 1 => #<Account:0x2665478 ...> >> account.people.create :name => "Jamis Buck" Account Columns (0.000271) SHOW FIELDS FROM accounts Person Columns (0.000246) SHOW FIELDS FROM people SQL (0.000093) BEGIN SQL (0.000351) INSERT INTO people (`account_id`, `name`) VALUES (1, 'Jamis Buck') SQL (0.253635) COMMIT => #<Person:0x27cb628 ...> |
There you have it. Each call to ActiveRecord now logs all of its activity to STDOUT (e.g., the console), via your custom logger instance. The tale it tells is revealing, and reassuring: scoped creates do not, in fact, load the entire collection anymore.
Yay!
(One caveat: be sure to set up your logger first, before doing anything else, otherwise the default logger will get cached with no simple way to uncache it.)

I recently had the privilege of writing a tutorial for Dabble DB’s new plugin API. If you haven’t heard of Dabble DB yet, it’s one of the few really innovative applications you’ll find with the “web 2.0” label. For a quick look at what it’s all about, check out the popular 7 minute demo movie that Avi made.
Even if you’re not planning to use Dabble DB, I think it’s worth reading the tutorial to see how they’ve implemented plugins. It may have been done before, but I haven’t seen it done like this. When you host an application on the open internet, how do you allow users to safely “plug” their own code into your application? You could go to a lot of trouble and create a sandboxed interpreted environment inside your application, exposing an API. But that’s really really hard to do.
What Smallthought did might be more aptly called “plugouts”. Instead of just exposing services that you can consume into your own mashup, they allow Dabble DB to call out to custom, internet-accessible services. And, rather than clutter things up with an ugly XML API, they deal in simple CSV in and out, kind of like UNIX pipes.
It’ll be interesting to see what happens with this both in Dabble DB and other applications that start to adopt this approach. Immediately after the plugin API’s release, there are already a couple of publicly available plugins (from an apparent Rubyist. Hi Tim!)
What other interesting approaches have you seen to accomplish this same goal?
The day before yesterday i wrote a short post about RubyOSA. RubyOSA is a Ruby/AppleEvent Bridge which in the end means that you can use Ruby to script Mac OS X applications like iTunes, iChat, Address Book and many more.
As a small introductory example i wrote (read: quick, dirty hack) a small script to print all contacts in a Mac OS X Address Book.
Running this script with Ruby 1.8.4 worked just fine. Running it with Ruby 1.8.5 resulted in a (eval):2: [BUG] Segmentation fault. Without further investigation i just wrote RubyOsa seems to work better with Ruby 1.8.4 than with Ruby 1.8.5.. What i should have done is what i like to explain in this post.
ruby 1.8.5 (2006-12-25) [i686-darwin8.8.1]
Laurent Sansonetti the maintainer and main developer of RubyOSA left a comment and asked about the problems with Ruby 1.8.5.
The sensible thing to do in the first place would have been to investigate if Ruby 1.8.5 really caused the aforementionend segmentation fault and if that was the case - to file a bug report with as much information as needed.
Laurent asked me if Ruby had been build as a shared library. A quick and easy way to determine this is to check rbconfig.rb.
When building Ruby rbconfig.rb is being created with all relevant informations about the specific build. The following script prints all configuration options and shows if Ruby was built as a shared lib (mine actually was).
require 'rbconfig'
# Print all available configuration options
Config::CONFIG.each do |k,v|
puts "#{k}: #{v}"
end
# Ruby built as shared library?
puts Config::CONFIG['ENABLE_SHARED']
To debug the Ruby interpreter or any low level library (like in this case) gdb the GNU Project debugger yields valuable informations.
GDB just recently gained a new momentum in the Rails community after Jamis Buck and Mauricio Fernandez described how to easily attach the gnu debugger to a running ruby process.
To debug a short running ruby script (without attaching the debugger to a process id) the following steps are neccessary:
Start gdb with the ruby interpreter as the first argument. You will get an interacive gdb session with a gdb prompt. There are more than 130 GDB commands but few will be sufficent to get the information that is needed.
macbook-sts:~/Desktop stefan$ gdb `which ruby`
GNU gdb 6.3.50-20050815 (Apple version gdb-573) (Fri Oct 20 15:50:43 GMT 2006)
[... output stripped...]
This GDB was configured as "i386-apple-darwin"...Reading symbols for shared libraries .... done
Run the script that causes the bug. In this case it is rubyosa_ad.rb.
(gdb) run rubyosa_ad.rb
Starting program: /usr/local/bin/ruby rubyosa_ad.rb
Reading symbols for shared libraries .+... done
Reading symbols for shared libraries . done
Reading symbols for shared libraries . done
Reading symbols for shared libraries ... done
Reading symbols for shared libraries . done
Reading symbols for shared libraries ............................................................... done
Reading symbols for shared libraries . done
Reading symbols for shared libraries . done
[... output stripped...]
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x6552534e
0x9000c5f8 in __vfprintf ()
The output now shows what is really happening: Program received signal EXC_BAD_ACCESS, Could not access memory.. To get even more information type backtrace (or bt) to get a backtrace.
(gdb) bt
#0 0x9000c5f8 in __vfprintf ()
#1 0x90022818 in snprintf ()
#2 0x000b4562 in rbosa_app_send_event (self=6878720, event_class=6826060, event_id=6826040, params=6826020, need_retval=2) at src/rbosa.c:231
#3 0x00217f54 in call_cfunc (func=0, recv=980578162, len=-1, argc=0, argv=0x0) at eval.c:5672
GDB allows you to set breakpoints, step interactively through program execution and as shown in this really short example: Examine what has happened, when your program has stopped. This is what makes a bug report valuable and what really helps the developer who has to or wants to fix the bug you are reporting.
Laurent already fixed the bug in the RubyOSA trunk and even improved the address book example. The improved version is now in the RubyOSA sample directory which contains some interesting usage examples. Go and check them out!
For more information about GDB check out the GDB manual.
Have a look at RubyOSA or RubyCocoa - a Ruby/Objective-C Bridge for Mac OS X Cocoa. Great and interesting librarys for Ruby development on Mac OS X.

Ah, Portland. The open-source motherland. Pacific springtime beauty. RailsConf ‘07 nirvana.rb # => true and home of CD Baby, a little record store that digs Ruby and Rails.
We’re gearing up for a RailsConf hackfest at the Jupiter hotel just down the street and figured, heck, let’s start now! The top twenty Rails contributors between the new year and conference registration opening day will have a free conf pass and a room at the Jupiter specially reserved, CD Baby’s treat.
No kidding. Registration opens in a matter of weeks. Sprint!
Rails contribution is measured by real Trac activity weighted in favor of well-tested, committed patches but also accounts for new tickets and even comments. We’re joining forces with Working With Rails to track Rails contributions from the new year onward. To be included, mark yourself as a core contributor and give your Trac username in your account profile.
Have a Rails itch you’ve longed to scratch? Now’s the time! Happy hacking, and see you at RailsConf.
Update: Derek @ CD Baby’s announcement with more details.
You’ve probably heard that RailsConf 2007 will be May 17-20 in Portland, Oregon.
Since my company CD Baby depends on Rails, and since we’re based in Portland, I decided to spend some company money to reward the people that MAKE Rails. Not just the ones who invented it, but the people who are actively improving it by contributing patches to Rails code.
* - We bought 20 full RailsConf registrations from O’Reilly. ($800 value)
* - We pre-paid for 20 rooms at the Jupiter Hotel, an incrediby cool funky modern hotel, a few blocks from the conference, with free wi-fi everywhere - for three nights : May 17, 18, 19 (a $300 value)
* - We reserved the DreamBox conference room at the Jupiter Hotel for the nights of May 17, 18, 19, for elite Rails hackers to gather, plug in, hack, eat, drink, etc. (priceless)
These 20 registrations, 20 hotel rooms, and access to the DreamBox will go to the top 20 contributors of Rails patches (as measured here) between January 1 and January 22!
(RailsConf is opening registration soon after January 22 - that’s why we have to make the Jan 22 cutoff date.)
In other words : if you want CD Baby to save you $1100 on RailsConf, sprint!
If you’re not already signed up at workingwithrails.com, sign up now. In your workingwithrails profile, mark yourself as a core contributor and enter your Trac username. Then all of your patches will be linked to your account.
Bookmark http://workingwithrails.com/contests/hackfest2007 to watch progress
Also see Jeremy’s announcement at http://weblog.rubyonrails.org/2007/1/8/hackfest-2007-and-cdbaby-sprint
Wow, this is pretty cool.
CDBaby is sponsoring conference passes AND twenty rooms at the Jupiter Hotel in Portland, OR during RailsConf 2007 to the top 20 contributors to the Ruby on Rails project from during January.
Start submitting patches!

Now that Charles Nutter has tagged me with the Five Things meme, I guess I ought to give it a shot. Here are five things you probably don't know about me:
I never intended to get into computing as anything more than a hobby. I planned on being a chmical engineer instead.
I joined the army straight out of High School to earn money to go to college, and got involved in computers and networks.

The API comes for free
And are you going to turn away a free gift?
With Rails 1.2, you can easily respond to the same request with different content types. Say you have an action that displays an HTML page with all the books in the category ‘Ruby’. From the same action, you can also return the [...]

I'm just starting to work through a copy of Working Effectively with Legacy Code by Michael Feathers. I've had my eye on the book for a while, and am really glad I was able to borrow a copy (now I just need to buy my own). Like any good book it's making me think, making me question things I've taken at face value. So far, the best example of this is in his discussion of Unit Testing.
I've
Matz is warming up to the term eigenclass, the People’s slang for (class << self; self; end). From [ruby-talk:231992]:
In my mindset, two candidates have survived. singleton_class (or singletonclass), which can easily be confused with a class in the singleton design pattern. And eigenclass, which is unfamiliar for most people.
Does anyone know if Perl 6 folks still use it?
I finally bit the bullet and moved my blog over to Mephisto. So far I am loving it. Thanks to Justin Palmer and Rick Olson for all of their hard work that went into making this an awesome application.
I migrated from Typo and used the great howto Converting Typo to Mephisto on the Octoblog. What an awesome name for a blog! The only thing I did differently, since I'm using the latest code from the Mephisto trunk, was the support for Typo style article URLs. I just opened up config/routes.rb and tweaked it to look as follows:
| 1 2 3 4 5 6 |
ActionController::Routing::Routes.draw do |map| Mephisto::Routing.connect_with map do map.connect 'articles/*path', :controller => 'mephisto', :action => 'dispatch' end end |
I recently released my Ruby client for the eBay XML API. The source code can be found on Google Code. Benefits of this implementation include:
Enough talking about why you should use this library, let's get started with the eBay equivalent to 'Hello World', which is the GeteBayOfficialTime call.
Firstly you'll need to sign up for an eBay developer account. You can sign up at the eBay Developer Center. Once you have signed up you need to follow the directions in the confirmation email to get your Developer ID, Application ID, and Certificate ID. Record this information, as you'll need it when setting up the eBay client.
Now you need to setup a sandbox user to make API calls on behalf of.
Next you'll need to generate your Authentication Token. Simply enter the information you previously recorded into the form, select the sandbox environment from the dropdown menu and click the "Continue to generate token" link. Then sign in as the sandbox user you just created above and agree to allow your developer account to make API calls on behalf of the sandbox user. Record the Authentication Token that is now displayed.
The Authentication Token is your means of sending requests for different users. All you have to do to send a request for a different eBay user is change the Authentication Token that pass into the API call you are making. Of course, you'll need permission to make API calls on their behalf.
Now that we have all of the information needed for authenticating the API calls we can setup the configuration file that we'll use for the following example.
Start by creating a file config.rb and place the following code into it:
| 1 2 3 4 5 6 7 8 9 10 11 |
Ebay::Api.configure do |ebay| ebay.auth_token = 'YOUR AUTH TOKEN HERE' ebay.dev_id = 'YOUR DEVELOPER ID HERE' ebay.app_id = 'YOUR APPLICATION ID HERE' ebay.cert = 'YOUR CERTIFICATE HERE' # The default environment is the production environment # Override by setting use_sandbox to true ebay.use_sandbox = true end |
Obviously you'll want to place your own IDs and tokens into the configuration.
After you've signed up for the Developer Program and you have the API configuration ready to go you can get started installing the Ruby ebayapi gem. Install this gem as by running:
| 1
2 |
> sudo gem install ebayapi -y |
The -y flag tells gems to install all the dependencies that the the gem requires.
Now that you've got the API client installed we can finally go ahead and get the official eBay time from eBay's servers.
Create a file named official_time.rb, in the same directory as the config.rb file we created earlier, and place the following code in it:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#!/usr/bin/env ruby require 'rubygems' require 'ebay' # Include the API configuration require 'config' # Create the eBay client ebay = Ebay::Api.new # Get the official eBay time response = ebay.get_ebay_official_time # Display the time to the user puts response.timestamp |
Now you can run this simple application:
> ruby official_time.rb
# => Wed Nov 22 06:03:35 UTC 2006
That was easy. Once we got all of the IDs and tokens that eBay requires, that is. Next time I'll go into some more depth and background the client.
In the meantime you can checkout the examples I've provided in the source. Happy coding.
Way back on June 16th, Tobi, Daniel, and I decided to enter the Rails Day 2006 programming contest. The contest was on June 17th. Somehow the theme became ninjas and Ninjistix was born.
A really good overview of Ninjistix and the rest of the Rails Day winners can be found on Evan Weaver's blog.
The day was really good. We started around 9am or so and worked until 12am that night. I can't really say that I did anything productive after around 9pm, but hey, we stuck it out to the end.
What I loved most about doing the project was the kind of discussions we had regarding the project. I remember asking "Ok, so add an attack method to the Ninja model?". Then later on I can recall Tobi announcing "I just added an RSS feed for the Ninja's kills". The bugs were also amusing: "Why does meditating cause the ninja to lose consciousness?" I don't remember hearing too much from Daniel, but that's because he was creating the killer UI that even included little Ninja attack and action icons.
So, the end result.... We won first prize for the most creative entry! Kudos to my teamates. I still can't believe how much work a team of 3 can do in one day. Also, congratulations to the other teams and thanks to the judges for judging the copious number of entries (> 100).
Geoffrey Grosenbach a.k.a. Topfunky of nuby on rails fame has launched an excellent new Rails screencast series called PeepCode.
The first episode in the series is on RJS templates. I was able to watch the screencast before its release and I was mightily impressed.
Geoffrey gives RJS a very thorough treatment from the basics of getting started all the way up to advanced concepts like collection proxies and testing RJS with ARTS.
I would highly recommend this screencast even if you're already familiar with RJS because you'll definitely learn a new trick or two. Congratulations to Geoffrey on a job well done.
First I'd like to thank the 600 or so people who bought RJS Templates for Rails in the past week.
I'd also like to thank all of the people who contacted me with their feedback and errata.
On that note, I'd like to let you know that if you have already purchased the book that you can go and download an updated, hopefully errata free, version from O'Reilly.
I'm happy to announce the availability of RJS Templates for Rails published by O'Reilly. Here's the intro from the book:
RJS templates are an exciting and powerful new type of template added to Rails 1.1. Unlike conventional Rails templates that generate HTML or XML, RJS templates generate JavaScript code that is executed when it is returned to the browser. This JavaScript generation allows you to perform multiple page updates in-place without a page reload using Ajax. All the JavaScript you need is generated from simple templates written in Ruby. This document helps you get acquainted with how RJS templates fit into the Rails framework and gets you started with a few easy-to-follow examples.
The book covers all aspects and features of RJS that are included in Rails 1.1. It also walks through a few examples, debugging with FireBug, and finishes off with some reference material.
I'm really happy with how the book has turned out and I think you'll really enjoy it.
Are you tired of debugging your RJS calls ? If you answered "yes" then it is your lucky day. Kevin Clark has created a new plugin for Rails called ARTS: Another RJS Testing System.
ARTS allows you to write assertions for your RJS calls in your functional test cases. Kevin has also created an excellent tutorial Test Driven RJS with ARTS.
What are you waiting for? Get over to Kevin's site and get started.
I am unable to attend the Canada on Rails conference, but I've already purchased a ticket.
The conference just sold out, so if you want a ticket for the price of $150 CAD, you should contact me before April 10th and I can transfer the ticket to you. The last day they will allow the transfer of the ticket is April 10th.
Email me at codyfauser [at] gmail [dot] com
Some powerful new features have been added to Rails RJS Templates. What are these new features? They are called element and collection proxies.
First, from Wikipedia, the definition of the Proxy pattern:
A proxy, in its most general form, is a class functioning as an interface to another thing.
So, in the case of RJS templates, the proxy is functioning as an interface to a JavaScript DOM object. The syntax is quite similar to the syntax of the original RJS templates, except that we use the [] operator on the page object within the template. So, if we wanted to hide the DOM element with id header, we'd use the following code:
| 1 2 |
page['header'].hide |
You can also use symbols, so passing in :header will also work.
Currently there is support for all of the RJS methods that you are already familiar with like replace_html, replace, visual_effect, show and hide. In addition, there is an interesting new method named reload, which will call replace on the element and replace the element's content with the rendered output of a partial of the same name. Example:
| 1 2 |
page['header'].reload |
Is equivalent to
| 1 2 |
page['header'].replace :partial => 'header' |
The proxy will also correctly pass through other Prototype methods that previously had to be called using page.call, such as remove_class_name.
So far the proxies may just look like a matter of semantics, however, when combined with the new select method, the results are very powerful.
The new select method returns an array of DOM objects. select takes as an argument a CSS based selector and returns an array of DOM objects matching that selector. So, to get all paragraphs within the <div> with id content, we would use:
| 1 2 |
page.select('#content p') |
Now combine this with the enumerable methods available through the collection proxy and you can do things like:
| 1 2 3 4 |
page.select('#content p').each do |element| element.hide end |
All <p> elements within the <div> with id content will be hidden.
Not only is it easy to iterate through the elements of the collection, but Rick Olson, the newest Rails core team member, went out and got all sorts of other enumerable methods that Prototype supports working. I'm going to leave those as an exercise for you to explore. You can start with the changeset.
The new element and collection proxies are a very nice and powerful addition to RJS. They allow us more flexibilty and we now have to write even less JavaScript. They also provide a nicer syntax for calling existing Prototype methods on DOM elements from RJS templates.
I've started working at Jaded Pixel on a top secret project known as the Pixel Box.
I can't say much, but what I can say is that I've laid my eyes on Shopify and it is absolutely incredible.
So if you haven't yet, go check it out. You won't be sorry.
I have come across a great way of refactoring finder methods, yet still maintaining the flexibilty of the built in ActiveRecord finder methods.
First I'll show an inflexible way of refactoring a simple finder. I was calling the following method from several places in my controller:
| 1 2 3 4 |
@emps = Employee.find(:all, :conditions => "work_status <> 'Gone'" ) |
Creating a static finder in my Employee class makes calling this method a bit more simple.
| 1 2 3 4 5 6 7 8 |
class Employee < ActiveRecord::Base def self.find_all_current find(:all, :conditions => "work_status <> 'Gone'" ) end end |
Now I can call:
| 1
2 |
Employee.find_all_current |
Finding employees that aren't "Gone" will be a common task throughout the application and it would be nice to have some flexibility in finding them. I'd hate to have to create another static finder method like just to order the employees differently or add another simple condition.
The best way to remove this duplication is to use with_scope. with_scope allows finder methods to be called normally, but have conditions applied to find or create methods called from within the block. An example will clarify this concept:
| 1 2 3 4 5 6 |
Employee.with_scope(:find => { :conditions => "work_status <> 'Gone'" } ) do Employee.find(1) # => SELECT * from employees # WHERE work_status <> 'Gone' # AND id = 1 end |
Now we can apply this concept to help make the refactored finder method a lot more flexible:
| 1 2 3 4 5 6 7 8 |
class Employee < ActiveRecord::Base def self.find_current(*args) with_scope(:find => { :conditions => "work_status <> 'Gone'" }) do find(*args) end end end |
This allows us to find all current employees, but with the flexibility to specify more parameters. A few examples are:
| 1 2 3 4 5 6 7 8 9 |
@emp = Employee.find_current(:first) @emps = Employee.find_current(:all) @emps_named_bill = Employee.find_current(:all, :conditions => "name like '%bill%'", :order => 'last_name, first_name' ) |
As you can see from the above code we maintain all the power of ActiveRecord's finder methods while imposing a constraint of our own in a straight forward, legible manner. In addition, it would be in the spirit of DRY to create other static finders in terms of find_current, such as Employee.find_current_ordered. One current limitation is that nested scopes are not yet supported.
Nested with_scope will be supported in Rails 1.1. To see the true potential of Rails ActiveRecord scoping check out this article on Nested with_scope by AnnaChan. It will rock your world.
I recently had a few minutes to create a subversion repository for the RJS Templates Plugin that I recently packaged.
Installation is now much simpler. First, run:
script/plugin discover
This will question you whether or not you want to add the plugin repositories that have been listed on the Rails Plugins wiki page to your local list of plugin repositories. Ensure that you add my repository, http://www.codyfauser.com/svn/projects/plugins/, when prompted. You can ensure that you have by ensuring my repository is listed when you execute:
script/plugin sources
Now all you have to do is:
script/plugin install javascript_generator_templates
If you don't want to add my repository to your list of plugin sources you can install the plugin in one shot as follows:
script/plugin install \
http://www.codyfauser.com/svn/projects/plugins/javascript_generator_temp...
Update: The plugin now has its own page
Go and get Rails 1.1 and you won't need this plugin.
Marcel Molina Jr. recently announced that RJS templates would not be included in the 1.0 release of Rails, but that they might include them as a plugin.
I thought that it was about time for me to learn the plugin system in Rails anyway, so I packaged up all of Sam Stephenson's hard work on the RJS templates from changesets 3078 and 3084 and turned it into a plugin.
This means that you can add the new RJS templates functionality to your application without having to run on the bleeding edge. Please note that the plugin updates quite a few methods from ActiveRecord::Base and ActionView::Base, but mostly in minor ways. Take a look at the changesets, linked to above, for more details.
The plugin should work if you are running the latest Rails gem (0.14.3) or if you are running the stable branch from the subversion repository. If you are running on Edge Rails already then please stop reading now because this plugin won't do anything for you.
Follow these directions to install the plugin from my subversion repository
Now that you have installed the plugin you can proceed with my tutorial or Rick Olson's more advanced tutorial.
Please notify me of any problems or feedback you may have.
Update: The plugin now has its own page
During my daily reading of the Ruby on Rails mailing list I ran across a post asking about RJS templates. I hadn't heard of them before and I was intrigued to find out more.
It turns out that RJS templates are a new form of template, called JavascriptGeneratorTemplates, and end with a .rjs file extension.
Ok, so there is a new type of template, but what does it do? Here is the description from the rdoc documentation in the changeset:
Unlike conventional templates which are used to render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax and make updates to the page where the request originated from.
Trying out the rjs templates requires checking out the latest Rails code from the subversion repository. You can use these instructions to help get your project running on edge Rails. After you are running edge Rails be sure to run the following:
rake update_javascripts
First, create the view that will be updated by the rjs template:
| 1 2 3 4 5 6 7 8 9 |
<h1 id='header'>RJS Template Test</h1> <ul id='list'> <li>Dog</li> <li>Cat</li> <li>Mouse</li> </ul> <%= link_to_remote("Add a fox", :url =>{ :action => :add }) %> |
Ensure that your layout is including the javascript libraries:
| 1 2 |
<%= javascript_include_tag :defaults %> |
Then add the action that will be called by link_to_remote to your controller:
| 1 2 3 |
def add end |
Rails now looks for templates with an extension of .rjs, in addition to .rhtml and .rxml, so create a view named add.rjs for your controller and add the following code to it:
| 1 2 3 4 5 6 |
page.insert_html :bottom, 'list', content_tag("li", "Fox") page.visual_effect :highlight, 'list', :duration => 3 page.replace_html 'header', 'RJS Template Test Complete!' |
If you're curious where the page object comes from, the rdocs provide the explanation:
An instance of the JavaScriptGenerator object named +page+ is automatically made available to your template, which is implicitly wrapped in an ActionView::Helpers::PrototypeHelper#update_page block.
Now when you load the page in your browser and click the 'Add a fox' link, a Fox list item will be added to the list and the entire list will be highlighted. The header will also be updated. You can also render partials:
| 1 2 |
page.replace_html 'header', :partial => 'my_partial' |
As you can see from the example, the new RJS templates make it dead simple to update multiple page elements using AJAX. This example barely scratched the surface of what is possible. Kudos to the Rails developers for yet another wonderful addition to the framework.
Checkout the new RJS Element and Collection Proxies.
No longer do you need Edge Rails or any plugin to get RJS working. Just upgrade to Rails 1.1 to get RJS baked right into the framework. Have fun!
Shopify has been released. You'll be blown away at how easy it is to setup your shop and start selling online. I could go on and on, but the homepage has more than enough information to whet your appetite. Have fun.
Beta version 0.9.0.9 is now available with:
gem update --system --source http://onestepback.org/betagems
This will be the last beta with major changes before the release of 0.9.1.
While require_gem was deprecated in 0.9.0, the bin stubs are still using it (oops!). To get rid of the warnings printed by rake or other bin stubs simply run gem pristine --all.
Lots! Many changes both big and small! Here’s an incomplete summary:
require_gem is deprecated and will print a warning. Use gem instead.
now -w clean
many proxy installation improvements
gem cert improvements
RubyGems is now easier to use as a library
extension building enhancements
error reporting enhancements (less odd exceptions)
many bugs fixed or closed (0 bugs in tracker!)
require now loads .jar files
select bug fixes:
For full details, read the ChangeLog.
Simple question: Am I running Mac OS X or Windows XP in the screenshot above? (Click to enlarge).
Simple answer: I’m running both.
Complicated answer
I’m really running Parallels with the coherence feature enabled. Parallels is an application that utilizes the Intel processors in newer Macs, allowing Windows XP to run in a virtual machine, but without the [...]
I normally stay away from political material on my blog, but this bit by Keith Olbermann on Sacrifice was just too compelling not to post. In the words of Dion, "If only he would listen."
Tired of your job? Need to hire developers? Visit DZone Jobs: great people, great opportunities.
Dieses Bild hat ja schon eine lange Tradition auf “chris blogs”.
Dieses Jahr gabs allerdings keinen Schnee, da mussten wir auf eine
andere Kühltruhe ausweichen.
NP: Minutemen—One Reporter’s Opinion

Stop the press. Microformats make it to InformationWeek, with a mention of hListing. Exciting times! (Thanks John)
Unintended consequences. LinkedIn, the social network I love to ignore, just added a new feature. You can send questions to your network of contacts. I received a couple of questions, both rethorical questions on non-interesting topics, with … you [...]
rbayes version 1.0.0 has been released!
An bayesian filter fed by a tokenizer that throws crap out you’d find in emails. Originally by Dan Peterson
Changes:
Crap, I saw this coming as soon as Tor tagged Charlie. I never was a chain letter person, and I’m kinda getting sick of this one, so I’ll let it end here, but just to not be seen as a complete curmudgeon, I’ll bullet-pointilize with these five items:
"We're recording this in at a club by the way; to all you aspiring podcasters, it doesn't matter where you record, just get something good!"
My recorded interview of a few opinionated guys (Thomas, Tobias, Jesper and Olle) from copenhagenrb.dk is finally published at the Rails Podcast. The background noise is indeed from the rest of the bustling club, where we had holed up in the little VIP room to drink beer and record our podcast.
Among their practical tidbits of advice: Instead of trying to specify and prototype web applications using Word documents or static html documents, just do it in Rails. I also get them to predict the future of Rails in Denmark in the upcoming year. Good times!
Bonus: As promised to the guys, here is the Takahashi version of the podcast (1min 20s) My web server didn't like the m4a extension, so gunzip to listen.
Tired of your job? Need to hire developers? Visit DZone Jobs: great people, great opportunities.
I've always kept almost every technical book I've ever bought. I guess I wanted to keep a historical record of my career by being able to look at my bookshelves. I imagined being 60 years old, reminiscing to some kid fresh out of college, pointing over to my original copy of Don Box's classic Essential COM and saying, "See, son, back when I was your age, we had to program uphill... both ways."
But I decided it was time for some real-life refactoring. Time to throw out all that dead code -- er, books, that is. Here are many of the books I just took out to the curb (snif). This picture kind of represents my work life for the past 10 years in one glance (click to zoom in if you really want to read the titles):
Now for me, this was actually a hard thing to do. Those old books you see in the picture at the top (plus others that I didn't get into the picture) represent uncountable hours of work, fun, stress, and growth for me over the past 10 years or so. Sure, I don't really need them anymore - I do Ruby full-time now - but it's still hard to make such a big change without a little fear.
Getting these books out of my daily sight was one way for me to make my committment to Ruby more tangible than ever.
It's similar to how I feel when I refactor a big ugly function, or remove a lot of deadcode, and then I run the tests and they still pass - I feel so much better. So much better.
And now, here's the glorious picture of all that remains: books that represent my current career and interests:
(There's one cool book missing from this picture because I have the .pdf of it instead, and another life-changing book that's missing because the co-writer of this blog borrowed it about a year ago and still has yet to return it... but I digress...)
What books on your shelf today were once important but don't really represent your interests anymore? Or perhaps, what books have you acquired recently that you would recommend?
Eyelid surgery stigma fades among Asian-Americans
Even if the patient is ambivalent, [Dr. Edmund] Kwan said the mother is often convinced of the surgery’s benefits. “It’s ingrained in their mind that an eyelid fold will look better, will help their daughter get a better husband,” Kwan said.
Skinny girls to blame for late trains?
“You have women trying to get their bodies tight for the summer and they won’t eat,” said Asim Nelson, a Transit emergency medical technician based in Grand Central Station. “Not eating for three or four days, you are going to go down. If you don’t eat for 12 hours you are going to get weak.”
Japan, Home of the Cute and Inbred Dog
The breeder told Mr. Sasaki that he had bred a dog with three generations of offspring—in human terms, first with its daughter, then a granddaughter and then a great-granddaughter—until Keika was born. The other four puppies in the litter were so hideously deformed that they were killed right after birth.
During the summer of 2005, I wrote a post that listed several coffee shops in Portland, Oregon that I found to be really good places to work on your laptop at. I’ve gotten bored with my regulars and have recently begun to look for new places to venture to.
Pier Coffee is in a weird part of Portland that is somewhat isolated due to the train tracks that will block you in when a long train is moving through town. It’s a very short walk from Allison’s place and they have Oregon Chai, which has become my replacement for drinking coffee. The chairs in Pier Coffee are very comfortable and they have an electrical outlet at most of their tables. When you get bored, you can walk over and play darts, or get a glass of wine. The wireless works really well and when it’s not raining, you can sit out front and overlook the train tracks and downtown, while hacking on your laptop. Pier Coffee is what I would consider an easy place for me to feel productive. There usually isn’t too many people here and I believe most of the customers are from the two condo complexes next to it. The staff is very friendly and their music tastes aren’t annoying.
Backspace is about a half block from the PLANET ARGON office. They don’t serve Oregon Chai, so I usually only get a tea, a viso, or a hot cocoa while there. They have a few tables and couches and I haven’t found this a good place to be productive. It’s a good place to have a short meeting with a coworker though. Music tastes are better here than most places, and they have a food menu now that caters to my vegetarian diet. There are a few electrical outlets, but the seats near them are often occupied.
Three Lions Bakery is about a block from the PLANET ARGON office. They do have Oregon Chai, so I stop by here often in the morning to get my fix. Not many electrical outlets, so your visits are usually not very long. They have a few sandwiches that are quite good. This is a good place to stop by if you’re in the mood to work for about a hour and have some chai and an excellent (and freshly baked) cookie.
If you’re in Portland and have some recommendations, please do share. I’m looking for a few places that are open later in the evening.
In cooperation with Pat Eyler, we present this conversation as a parallel thread to his recent string of Rubinius “serial” (ongoing) interviews. We aim to bring short, frequent, looks at the two alternate Ruby implementations’ developments, and have the conversations intersect from time to time.
A lot has happened since the last JRuby interview with Pat – Java was open-sourced, you’ve been to Javapolis, pushed out another release, and a slew of new contributions have poured in. How have your plans and goals for JRuby changed (if at all) since then?
Charles Nutter: For me the biggest items are the following, in order:
All these of these have been the hot topics on the JRuby mailing lists lately. I’ve launched into a newly-refactored compiler that’s showing great performance gains. Many of us have discussed how to speed method dispatch and finally push interpreted-mode performance up to or beyond Ruby’s speed. And we’ve started to test and track Rails 1.2, while continuing to resolve remaining issues running Rails 1.1.6.
Now there’s a lot of work to do, but we’ve seen steady, continuous growth among JRuby contributors. Just in the past week we’ve had a number of new names on the mailing lists, we’ve added a new committer (Nick Sieger), and we’ve seen patches pouring in for more and more bugs. Things are going great.
Ola Bini: I was very happy about the last release. It fulfilled the goals I had set for it, which was to get OpenSSL and complete Java-backed YAML into it. Besides that, we also got seriously many bugs fixed in just a few months. Since I have a tendency to plan mostly for the next release, what I want to see in 0.9.3 is support for Sandbox, all those strange block scope bugs that surface in Rails gone, our load times improved (by refactoring the LoadService code), and finalizers finally working.
The Sandbox stuff is mostly done, and I also hacked a Generator that is so much faster than MRI that we come out faster, all in all, in a
test case with generators.
Thomas Enebo: Largely, I think three goals are important: 1. Support Rails well enough where people do not need to ask us if it is ready for prime time; 2. Round out java integration support to do what most people expect it to do; 3. Make the runtime ‘fast’ enough. These three goals existed before JavaPolis, so I do not feel much has changed goal-wise.
How much closer have you come to achieving them? What is your perception of delta in growth in the JRuby community and acceptance of JRuby as a viable alternative to MRI?
Ola Bini: What I like about the last few months - since RubyConf - is that it really feels like JRuby and the other implementations will actually be viable alternatives and that there is something really useful going on. With Java open source, one of the major roadblocks for adoption in certain circumstances has all but disappeared. The contributions we have gotten is mostly visible in how many bug reports we get. That is really great, because that makes it that much easier to fix things. So I would say that the future looks brighter than ever.
Thomas Enebo: If you look at the amount of time between releases then you get a better idea of how much development has sped up. The time between 0.9.1 and 0.9.2 was a little under two months. This is the shortest development cycle to date and it seemed like we got so much done. Sun hiring us obviously had something to do with this, but also our community involvement is at an all time high. We get so many emails, bug reports, patches, tests, ideas, and enthusiasm coming in from the JRuby community. The community impact on JRuby is huge.
I think acceptance of JRuby as a Ruby interpreter is certain. Compatibility keeps improving, we keep getting faster, and we also offer integration with Java. If you look at the trend of how often JRuby is mentioned in blogs or the volume of email on our mailing lists, then I think you can get a picture as to whether people are willing to accept JRuby as a Ruby runtime.
Charles Nutter: Rails is probably the most visible measure of success for JRuby right now, and I’d say we’re able to run something like 75% of Rails 1.1.6 code and test cases. We’ve been using Rails’ own test suite as a yardstick for compatibility, with the idea that if we can run all the Rails test cases, we can say we support it. And that 75% is better than it might sound, since it’s the most heavily-used functions.
Now this might change, but we’re really hoping to claim full Rails support some time in February. We’re not sure if that will mean 90% of 1.1.6 test cases or 100% of 1.2 test cases, but we’re weighing options now. Finally having Rails support behind us will let us change focus toward outward to other applications and inward to improving JRuby internals and performance.
We’re also seeing daily gains in the performance area, with more to come. Since this past summer, we’ve managed to eliminate all the major performance bottlenecks seen when profiling. The only remaining area is the interpreter itself. My work on the compiler will eventually resolve that, and our work to improve the performance of method lookup and dispatch will help both interpreted and compiled execution. Everything’s moving very fast now. It’s going to be a great Spring for JRuby.
Probably the most intriguing change of the past month is the support from Aslak Hellesøy, creator of RSpec. Aslak has helped us get JRuby running RSpec extremely well, and we’re looking forward to the RSpec team using JRuby as part of their regression testing. I hope more Ruby app developers will take this same path, since their users are going be running JRuby more and more. Compatibility and regression testing for those apps should include JRuby just like it includes different Ruby versions and host operating systems.
As much as we’d like to think we live in a Ruby-glasses-colored world, the fact is there are plenty of neat toys out there that don’t know a bit about us. One that I’m currently enamoured with is Bamboo, Atlassian’s new continuous integration server. But, most commercial CI products are aiming for a wider market, and that means Java and Ant. Ant and JUnit predate Rake and Test::Unit by a few years, so I’m afraid they beat us to the punch, so that now the JUnit Ant task’s XML format is pretty much the first consideration for a continuous integration server to understand in order to display a test report for a build.
Where does that leave us Rubyists who want to play along with the bigs? Right here!. With support for not just RSpec, but Test::Unit too.
Right now, it’s packaged as a Rails plugin, because I’m lazy and I don’t need anything else right now. If you’re interested in a gem, please leave a comment. To install into your Rails app, the usual:
./script/plugin install http://svn.caldersphere.net/svn/main/ci_reporter
That’s it! Now all you have to do is have your CI server invoke an extra target before the main target that runs your tests.
For RSpec,
rake ci:setup_rspec spec
will leave one XML file per context in the spec/reports directory (creating it if it doesn’t exist).
For Test::Unit,
rake ci:setup_testunit test
will leave one XML file per test case class in the test/reports directory.
Most CI servers have configuration telling them where to look for test reports. Simply plug in one of these directories, and you’re set. Now sit back and watch your test or spec failures get tracked in your automated builds.

Authority files are rather important for unambiguously talking about a person, place or thing. In database lingo they essentially amount to a primary key for a table. Given the time and effort libraries spend in maintaining authority records and assigning control numbers to individuals it makes sense that a URI could be assigned to an [...]
Alas, manveru tagged me and I need
to tell you five things you probably didn’t know yet about me. It’s
like the perfect start into a year with the resolution of writing
more.
Here’s my list:
I have a photographic memory for URLs. Want to show me “something new”?
I’ll tell you immediately if I already have been on that site.
I’m a programming language fetishist. Well, if you read my blog,
you probably guessed that already, but I can recognize almost every language
given a short snippet and likely heard of the rest too.
I love to sleep long. Don’t even dare to wake me on weekends!
I have every official Bob Dylan disk on my hard drive. Must be the
collector’s disease.
My mind goes all weird when I’m drunk. And I mean really weird.
For example, I once couldn’t sleep in a bus because I did too many
sudokus that day, and desperately tried to sleep in a different
position than the people in my row and my column. Or, one time, I
tried to analyze relationships in a discotheque using advanced
algebra. It sucks if love isn’t commutative.
Actually, that’s pretty funny, but rather scary too when you
remember it, no?
The next people to tell five things we didn’t yet know about them are, umm,
Aria, David,
NP: The Kooks—See the World

I’ve been remiss in announcing recent Capistrano releases, so I’m making up for lost time now. Capistrano 1.3.1 is now available!
Capistrano, for those of you that are late to the game, is a utility for executing commands in parallel on multiple remote machines. It comes with support for vastly simplifying the deployment process of Rails applications, but can be customized to work with virtually any environment.
Since 1.2.0, the following enhancements and changes have been made:
role :app, "app1.host.com"
role :web, "webuser [at] web1 [dot] host [dot] com"
role :db, "db1.host.com:1234"
role :file, "fileuser [at] file1 [dot] host [dot] com:1234"
:as option to sudo, to specify which user a command should be run as:sudo "spinner", :as => "app"
Feel free to read the changelog several other fixes and tweaks. It might be a few hours before the 1.3.1 gem reaches all the mirrors, but when it gets there, a simple “gem install capistrano” ought to do the trick!
DemoCampDC is an adaptation of BarCamp to provide an informal mechanism for sharing technology shtuff in the DC area. If you are interested and in the DC area please add your name to the list of attendees and stay tuned.

Capistrano Concepts is the newest PeepCode (released earlier this week). People are already saying that “it put a lot of things into perspective and really helped [me] grasp the concepts. I think I’ve learned Rails faster from your screencasts than all the books I have combined.” (Jon Baer, Developer)
Also available as a free bonus is a 10 minute screencast showing you how to install a full Rails stack on Ubuntu using the deprec gem. It’s a great way to build a staging server or a sandbox for experimentation. Download it at the new site.
The new site also has some new features that people have been asking for:

Mike Clark has got a great writeup on how to create custom maintenance pages for use with Capistrano and Apache. I haven’t seen much written where people are using the render helper in Capistrano—it’s good to see it getting some use, anyway!
If you happen to be hit by Ticket #5704: Bug in ActiveRecord::Base when mixing STI and abstract models, and you're seeing failures to find STI instances intermittently in development mode, try the following:
class MyAbstractModel < ActiveRecard::Base
self.abstract_class = false
# ...
end
-----
class MySTIModel < MyAbstractModel
TYPES = %w(Sub1 Sub2 Sub3)
def self.inherited(cls)
super
raise "not in #{self.class}::TYPES: #{cls}" unless TYPES.include? cls.name
end
end
MySTIModel::TYPES.each do |f|
require_dependency f.underscore
end
-----
class Sub1 < MySTIModel; end
class Sub2 < MySTIModel; end
class Sub3 < MySTIModel; end
It is a stupid bug and I can't do much about it, but the above workaround seems to be a nice tradeoff between horrible hack and maintainability. By pushing the list of subclasses up to the TYPES array, you keep it visible and near the top of the file. By having the inherited hook, you keep slipups in maintainability as visible as possible.
UPDATED: All of the classes in my actual use were single word classes. Kevin Clark pointed out that my code doesn't work with camel-cased/multiple-word class names. The code above has been updated to fix that.

Today’s TADFALAICKIU: balancing brevity and clarity.
I’m a big fan of the ternary operator. (That’s the bizarre little foo ? bar : baz construct which Ruby, and others, borrowed from C.) It lets you express simple conditionals very concisely. However, the poor ternary operator gets a lot of flak. It is easily abused, and some people have even gone so far as to swear that any use of it is an evil use.
If that’s you, then I guess we’ll have to agree to disagree. :)
I’ll admit that I’m still learning the balancing act. I’ve been going through some older code of mine and discovering things like the following:
| 1 2 3 4 5 |
def smart_overview_url(options)
@project ? project_overview_url(options.merge(:project_id => @project.id)) : overview_url(options) end |
Although certainly not one of the evilest invocations of the ternary operator, it is undeniably destined for some circle of Hell. Ternary Operator Rule #1: if you can’t fit the entire condition on a single line, use an explicit if-then-else construct.
| 1
2 3 4 5 6 7 |
def smart_overview_url(options)
if @project project_overview_url(options.merge(:project_id => @project.id)) else overview_url(options) end end |
There, isn’t that cleaner? Other rules of thumb:
So, when is it ok to use the ternary op? Try these examples:
| 1 2 3 4 5 6 |
# trivial conditions increment = x < y ? 1 : -1 # simple type conversions value = record.respond_to?(:something) ? record.something : nil # unfolding hashes element = hash[:here] ? hash[:here][:there] : nil |
Note that in the case where something is either a result of some operation or nil, you can also use the && operator in Ruby:
| 1 2 3 4 |
# simple type conversions value = record.respond_to?(:something) && record.something # unfolding hashes element = hash[:here] && hash[:here][:there] |
That works because && does not (necessarily) return a boolean value—it returns the first false/nil value, or the last value if none are false/nil.
Overheard on #rubinius, MenTaLguY, the modern-day concurrent programming guru, on memory barriers:
MenTaLguY: as far as memory barriers go, the issue is that modern processors do all kinds of crazy stuff behind the scenes
MenTaLguY: reordering reads/writes, deferring writethroughs, etc
MenTaLguY: it’s like one of those shady delis where they don’t seem to do much actual deli business, but people are always going in and out and there’s a room in back full of cigar smoke
MenTaLguY: you walk in at the wrong time, and … wellMenTaLguY: memory barriers are like loudly announcing “WHY, HELLO THERE OFFICER, NICE DAY TODAY, I’M JUST GOING TO THE DELI NOW” before you come in

This was actually inspired by some thoughts at a new_haven.rb meeting I wasn’t able to attend, reintroduced in a RubyTalk thread, and solidified in another blog entry that’s worth a look.
The topic here is simple, and it’s that for most common needs, there is absolute no reason to use class variables. I will show how you can use class instance variables to avoid the problems associated with class variables in most cases at the end of this article, but first, take a look at two compelling and mind melting reasons for *not* using class variables.
From Gary Wright:
>> class A
>> @@avar = 'hello'
>> end
=> "hello"
>> A.class_variables
=> ["@@avar"]
>> A.class_eval { puts @@avar }
NameError: uninitialized class variable @@avar in Object
from (irb):5
from (irb):5
>> class A
>> puts @@avar
>> end
hello
=> nil
>> class A
>> def get_avar
>> @@avar
>> end
>> end
=> nil
>> a = A.new
=> #
>> a.get_avar
=> "hello"
>> a.instance_eval { puts @@avar }
NameError: uninitialized class variable @@avar in Object
from (irb):16
from (irb):16
And the real scary one, from David A. Black:
@@avar = 1
class A
@@avar = "hello"
end
puts @@avar # => hello
A.class_eval { puts @@avar } # => hello
Yes, there are reasons why both of these problems occur. Yes, they are likely to give you a headache.
If you’re just looking to store some data in a variable which is unique to your class, but accessible from instances or externally, why not just use instance variables?
>> class A
>> @foo = "bar"
>> class self; attr_reader :foo; end
>> end
=> nil
>> A.foo
=> "bar"
Yup, classes are just regular old ruby objects, and class instance variables are just regular old instance variables. This avoids the above problems, as well as simplifies the concepts of where your variables actually live.
Yeah, maybe @@foo is easier to type than self.class.foo
But good luck debugging it! :)

With release candidate 2 out now, Ruby on Rails 1.2 is scheduled to be released in the very near future.
Again, if you want to make use of the tons of tweaks, additions and improvements, grab it, and test with your apps!
On the JavaScript side of things, Prototype has seen lots of updates lately, and this new improved version is part of the Rails release candidate, so don’t miss it.
Firebug, the DOM messin’ around and JavaScript debugging tool everyone loves, is nearing it’s 1.0 release.
New and improved features include:
It’s currently in closed beta, but will hopefully arrive soon.
Check out the all-new firebug site, www.getfirebug.com.
Two thumbs up for Mr. Hewitt and easing the pain the web development can be. Maybe it can be fun after all…? :)
I'm releasing the code on Sat. 2007-01-06 20H UTC (barring technical problems).
Stay tuned to the RSS feed for more details...
image_science version 1.1.0 has been released!
sudo gem install image_science
http://rubyforge.org/projects/seattlerb
ImageScience is a clean and happy Ruby library that generates
thumbnails -- and kicks the living crap out of RMagick. Oh, and it
doesn't leak memory like a sieve. :) For more information including build steps, see http://seattlerb.rubyforge.org/
http://rubyforge.org/projects/seattlerb
I've been quiet lately, both bloggy and email (sorry if I haven't gotten back to you!). I think I'm hitting information overload and my brain is pushing back. That said, I'm going to try to actively fix this. I have a bunch of stuff to release and even more stuff sitting around that could be blog-fodder. Hopefully from here on I'll be publishing daily at least until I'm through my current blog-fodder queue and the releases...

Earlier this week, Hunter, uber technocrat at DailyKos.com started talking about how they will build the next version of DailyKos. The discussion has been going for a day or two now with over 700 comments as I write this.
While DailyKos is the highest-traffic political blog in the US, I don't think it's particularly newsworthy that they are considering Rails. In fact, I think it's quite the opposite. What I do find interesting is the evolving discussion about the choices. Hunter essentially set out Perl/mod_perl, Python/Django and Ruby/Rails as the main choices. What people have to say about the differences and why they would choose one over the others makes for some really I-should-have-been-in-bed-an-hour-ago reading. Some of what people think they know about Ruby and Rails seems to be out of date or otherwise misinformed, but there are some good arguments on all sides.
If you are gearing up to have a conversation with management about picking Rails for a big project, take a read to see in one place all the arguments you will have to deal with!

This is it. We’re a mere two shakes of a lamb’s tail from releasing the final version of Rails 1.2. But before we light the fireworks and pop the champagne, we’ll just do one itsy, bitsy, tiny test run. Like wearing protection glasses in downtown Copenhagen on New Year’s. You know, just for precautions.
So please do give it a good run. We’re looking for STOP THE BOAT and HOLD THE PRESSES kind of issues for this one. Nothing else will stop it (but please do report every thing you find any way).
For a reminder on how to install and what’s new, see the release notes for Release Candidate 1. We also did a series of highlights for Active Record, Action Pack, and Active Support. Read those and hold your breath in anticipation. Unless a surge of heinous issues appear, we’re expecting the final version to land some times next week.
Yay, hurray!
Want to move from Instiki to Junebug? I exported my Instiki as a zip of .textile pages and wrote instiki2junebug.rb to import my pages. Give it the Junebug username to assign the pages to and a path to the unzipped directory of files.
junebug wiki
cd wiki
ruby instiki2junebug.rb _why ~/instiki-dump

Color theory corrected. Color theory for developers was good at explaining HSB to this RGB geek, but according to Amy Hoy (recommended blog) … well you better read what she has to say.
Boxing day. Something to read in your spare time. (Thanks Sterling).
Open door. Sometimes a blog is a place to vent, sometimes a place [...]
I’ve been keeping my eye on a series of blog posts by Chad Fowler, which he calls The Big Rewrite.
Today, Chad posted an entry titled, Who’s Tending the Store? He writes…
“the experts keep the old system running while the new system is being built. So, who builds the new system? Not the experts, that’s who. Usually, it’s people like me: technology experts. And while we’re banging away at the existing system’s UI, trying to figure out what needs to be coded, the domain experts are doing their jobs. Unfortunately, this means the domain experts aren’t watching the Big Rewrite very closely. Regardless of how good the team, if communication is impaired between the domain experts and the technology experts, things are going to move slowly, and wrong software is going to be created.”
I wanted to follow up on this issue as it’s an area of great interest to me.
I feel like this issue runs deeper and while it’s important to be mindful of the communication between domain and technology experts, it’s a good idea for each of us to take a break every few days (or everyday) to assess our perceptions in all areas of the project. More specifically, I’m suggesting that in order for us to be effective in our communication, we must make time to refactor our perceptions about the state of a project. From the design, to the development, to team communication, to the schedule, and all the way to customer satisfaction… or what Martin Fowler calls, Customer Affinity. These things are not static and we must see them as extremely dynamic variables… much more dynamic than our wonderful language of choice.
When Brian Ford and I started discussing Dialogue-Driven Development (d3), we were initially focused on an area that always seems to come up in projects. Client communication. From managing expectations to delivering the right product, d3 has become an essential tool in our team’s tool belt. We refactored our entire Design and Development process (and it’s always evolving) to focus on the things that we felt were the most important to a successful project. Clients come to us in search of expertise and guidance so that we can build them innovative solutions. When it comes to this process, clients deserve simplicity.
If there is one thing that I have learned, it is that our initial perceptions are often misguided. We have to work really hard to think critically, not only of the problem we’re trying to build a solution for, but also of how we, ourselves, are actually looking at the problem. It’s easy to fall victim to tunnel vision. I often find myself having to take a step back from problems on a very regular basis. While I have no scientific proof to back this, it seems to feels natural for us to keep firing once we pull the trigger. It’s important to re-aim.
Chad raises a very important topic and leaves readers to think about the problem. After thinking about this, it’s my opinion that in order for the domain and technology experts to be effective, they need healthy collaboration. But, I feel like this applies to many other areas of our process as well.
So, what is the solution? Better yet, what is the problem? Is there even a problem?
How can we avoid situations where communication becomes impaired? We’ve all been there. We know how to spot impaired communication, but how can we spot it… before we perceive it as too late? How can we recover from it? What causes the communication to break down? What if… it were possible to repair the situation?
These questions don’t have easy answers. These are complicated problems that reach far beyond the development community. These are the same problems that all members of organizations, communities, countries, and planets all face, each and every day.
While it’s important to make sure we’re engaging in healthy dialogue through a project, bad things will happen. They are inevitable. As Agilists, we’re accepting this as a fact of (project) life and should be prepared to take action. If you see communication being impaired, it’s time to step up and help the team out. Otherwise, you’re only hurting yourself… and your colleagues.
“Be the change you wish to see in the world.”—Mahatma Gandhi
If these sorts of topics are of interest to you, I encourage you to join the Dialogue-Driven community and help us figure this stuff out!
So, in what ways have you guys extended Hpricot? I really enjoy this collection of accessories to Hpricot by Christoffer Sawicki, who also wrote the Hpricot-based HTML-to-feed library called Feedalizer.
He has one script that does gsub! on all text nodes in the document. Another script is for generating tables of contents from the headers on an HTML page. I imagine that would go great with Markdown and Textile. (See also: del.icio.us/tag/hpricot.)
Ruby is now in the top ten languages in the TIOBE index, and has been declared Programming Language of the Year for 2006 because it had the largest popularity increase in 2006 of all the languages tracked:
We are glad to announce that Ruby has become “Programming Language of the Year 2006″. Ruby has the highest popularity increase in a year of all programming languages (+2.15%). Runner up this year is JavaScript with +1.31%. Both languages are boosted by their corresponding frameworks, Ruby On Rails and Ajax. This might be a new trend. In the recent past it was necessary to have a large company behind the language to get it in the spotlight (Sun with Java, Microsoft with C#), but nowadays a killer app appears to be sufficient. Viral marketing via the Internet works! The winners of the last 2 years, PHP and Java, are the losers of this year. Other trends that are observed are the growth of dynamically typed languages and the fact that the difference in popularity between languages is getting less.
This is awesome… ‘nuf said.
22:01 edsu> i would try to separate them now before it's
too late :)
22:02 erikhatcher> it's never too late, but i certainly want
to keep this clean from the start
New Years Resolution #9 - never underestimate the power of a positive attitude…
In my experience, there are a few different attitudes when it comes to beautiful design. Many consider Rails to be a beautiful framework to work with. In it’s own right, I certainly would agree with these folks. If you’re willing to accept the 80/20 divide and the tool fits the job, it could be dreamy to work with Rails. But in my limited experience, I sort of feel like a decision to work with Rails is more or less an all-or-nothing decision.
Like a train that wants to go east but only has tracks running North to South, a change in course is going to create some major problems. I don’t think this is a bad design, that’s what a train is meant to do. But maybe for some jobs, you need a dune buggy. That’s where the little wheels come in.
The camping framework is designed in light of another definition of beauty, and that definition is closer to the austere. When I started a job in it, I asked the usual questions one might run into when dealing with a small web app. “Does camping support sessions|file uploads|static files”
The answers were, ’sort of’,'nope’,'nope’. But all three were also appended with a “but it’s easy to roll your own”. The rest of this article will show you one way to do all three, and hopefully show some appreciation for the simplicity of the task.
There is optional support for sessions. To me, it totally rocks how easy these are to set up. Camping lets you use SQLite3 with zero config, so all you need to do is use the session library to create a schema, and you’re right off the ground in no time.
Straight from an actual job of mine, the relevant parts look like this.
require "camping/session
module Importer
include Camping::Session
end
def Importer.create
Camping::Models::Session.create_schema
end
Now in the rest of my app, the @state variable will hold a unique session that I can just stuff things in for the user, no further thoughts needed.
for example:
@state.my_attribute = "Chunky Bacon"
could be accessed throughout my app, maintaining state. Very cool.
The thing is, to a Rubyist with minimal rails experience, this kind of thing might make more sense. I *see* where the schema is being created, I see the library that’s in charge of my sessions, etc. And if I really wanted to, I can hack on those things without digging much deeper. This to me is a valuable tradeoff from ‘just works’ to ‘works easily and you can see how’. Now yeah, I’d be annoyed if I was looking for more high level support, but for what I was looking for, I saw this as ’super cool’
Note that the way I do this is a hack, but the joy of Camping is that’s okay! This particular app is meant to run locally, and all users to be considered equal, so I had no need for ACLs or any other constraints, which others may.
Here is the controller:
class Upload R '/upload'
def get
render :upload
end
def post
file = @input.File.tempfile.read
@state.mi.load(file) #does something with the file, using sessions
redirect Import
end
end
And the relevant bits of the view:
def upload
form :action => "?upload_id=#{Time.now.to_f}", :method => 'post',
:enctype => 'multipart/form-data' do
p do
input({:name => "File", :id => "File", :type => 'file'})
input.newfile! :type => "submit", :value => "Upload"
end
end
end
Nothing particularly magical here, and that’s the way I like it. This just creates the appropriate form, lets me select a file from my machine, whack the ‘Upload’ button, and then handle that in my controller. There are a ton of other ways to deal with this, and the more complicated they get, the more likely you’ll be to say something like “Maybe I should be using Rails”. But for simple needs, I like having this kind of “roll your own” power.
I copied and pasted this code from the camping wiki, but again, I was awestruck by the coolness of the ‘if I need to tweak that, it should be easy’ effect.
require 'pathname'
module Camping::Controllers
class Static R '/static/(.+)'
MIME_TYPES = {'.css' => 'text/css', '.js' => 'text/javascript',
'.jpg' => 'image/jpeg'}
PATH = File.expand_path(File.dirname(__FILE__))
def get(path)
@headers['Content-Type'] = MIME_TYPES[path[/.w+$/, 0]] || "text/plain"
unless path.include? ".." # prevent directory traversal attacks
@headers['X-Sendfile'] = "#{PATH}/static/#{path}"
else
@status = "403"
"403 - Invalid path"
end
end
end
I realized that this was the kind of tool I was looking for. Something simple, basic, and super extendable. I’m not afraid of rolling my sleeves up, and sparse documentation isn’t enough to keep me away from code that seems cool. If you’re in the same boat, be sure to check Camping out. Most of my code here is either taken directly from the wiki page or via suggestions from the kind folks in #camping on Freenode.
A slight warning is that if you plan on working with the framework, give yourself some extra exploration time. The little wheels are *awesome*, but I can promise you you’ll spend more time on IRC and sifting blogs and wikis at first then you might for the equivalent Rails job. I personally think it’s well worth it for the minimal web needs I have, and even if you don’t have a pressing need for a minimal tool like this, it’s great eye opener to the benefits of a simple design.

As I’m wrapping up the 8th chapter of my obscure Ruby book, you might be interested in a sneak peek at some of the art going into this 20-page fully-illustrated chapter. The Poignant Guide Earlies set on flickr has just a few scans.
This weekend I’ll also be posting some scans from Expansion Pak No. 2, which covers packaging libraries. This expansion pak will have appearances by Spiderman, Indiana Jones, various illegal Windows product keys, illegal scans of sheet music—in short, a pile of things which will render the book unprintable. With any luck, the first illegal programming manual.

Yeah, I’m on a real testing kick these days. Today’s TADFALAICKIU is a little trick you can play with assert_select.
Out of the box, assert_select works only with HTML documents. If you try it on an XML document (like, say, an RSS or Atom feed), you’ll more than likely see warnings about the document being malformed. It’s easy enough to work around, though.
The trick is to define your own HTML::Document instance before calling assert_select. When you define your own instance, you can pass some optional parameters that make HTML::Document play nicely with XML:
| 1 2 3 |
def xml_document @xml_document ||= HTML::Document.new(@response.body, false, true) end |
The second parameter says whether you want to parse the document in strict mode or not. “False” is the default; if you set it to “true”, you’ll get an exception (instead of a warning) whenever the parser hits what looks like a malformed document.
The third parameter says whether or not the document is an XML document or not. It defaults to “false”, meaning that, by default, only HTML documents are parsed. Here, we set it to “true”.
Once you’ve defined your custom document, you just need to define your assert_select wrapper:
| 1 2 3 4 |
def assert_xml_select(*args) @html_document = xml_document assert_select(*args) end |
The assert_select method then will reuse the existing html_document value. Nothing to it! Just put these two methods in your test/test_helper.rb file, and you’re all set.
(Caveat: the above won’t work if you’re trying to use assert_select on XML returned via RJS, since when assert_select parses the RJS response to extract the document, it builds it’s own html document.)

(This article is part of the Big Rewrite series.)
While we’re all in the back creating the next revision of a product, who’s tending to the day to day issues of the existing product? Typically, it’s the domain experts and the original implementers of the product.
Regardless of our intentions, day to day life and in-your-face time-sensitive issues can very easily steal all of the attention from a Big Rewrite. Screaming customers need their problems solved. Outages and serious bugs need to be fixed. Enhancements have to keep rolling in if your project takes as long as projects tend to take. Somebody has to do these things. Training new people is hard and doesn’t seem to make sense. If we’re getting rid of a system, why would we train someone how to maintain it?
So, the experts keep the old system running while the new system is being built. So, who builds the new system? Not the experts, that’s who. Usually, it’s people like me: technology experts. And while we’re banging away at the existing system’s UI, trying to figure out what needs to be coded, the domain experts are doing their jobs. Unfortunately, this means the domain experts aren’t watching the Big Rewrite very closely. Regardless of how good the team, if communication is impaired between the domain experts and the technology experts, things are going to move slowly, and wrong software is going to be created.

Here’s a really simple example:
function adder(num) {
return function(a) {
return a + num;
}
}
This function returns functions that add the given number to the argument:
var plus5 = adder(5);
plus5(7); //=> 12
plus5(1); //=> 6
This works because the returned function remembers the value of num originally passed into adder(). This is behaviour is called a closure but you can read more about them elsewhere. Let’s get on to how you can apply this technique.
function map(arr, iterator) {
var narr = [];
for (var i = 0; i < arr.length; i++) narr.push(iterator(arr[i], i));
return narr;
}
This function is very simple version of the handy map method as implemented in many scripting languages like Python and Ruby. Essentially, it takes an array and a function then loops through the array passing each value in the array to the iterator function. It then returns a new array which contains the returned value of each function call.
var nums = map(["1", "2", "3"], parseInt); //=> [1, 2, 3]
function getElement(id) {
return document.getElementById(id);
}
var els = map(['a-div', 'a-form'], getElement); //=> returns an array of DOM Nodes
Now say you wanted to call a method on each of these such as toUpperCase(). You could do this:
var caps = map(['a', 'b', 'c'], function(letter) {
return letter.toUpperCase();
});
But what if you find yourself wanting to call lots of methods on objects in map(). You can generalise with a partially applied function:
function callMethod(method) {
return function(obj) {
return obj[method]();
}
}
This returns a function that will call the given method on any object you pass it:
var upperCase = callMethod('toUpperCase');
upperCase('a'); //=> returns 'A'
Now you can use this for your function in map:
map(['a', 'b', 'c'], callMethod('toUpperCase')); //=> ['A', 'B', 'C']
How elegant is that? This is just a simple example but lets get on to how this helps us with callbacks. Say we have an ajax function called request. It’s takes a url and a callback function for when it’s loaded. We want to update an element with the response:
request('comment.php', function(resp) {
document.getElementById('item').innerHTML = resp.responseText;
});
We can generalise the update callback with a curried function like this:
function update(id) {
return function(resp) {
document.getElementById(id).innerHTML = resp.responseText;
}
}
Now we can write our request call like this:
request('comment.php', update('item'));
Nice eh? How about if we made a whole raft of other curried functions to automate other types of response:
request('data.json', sendTo(processData));
request('form.php', updateForm('comments'));
request('time/now', insertAfter('header'))
request('thing.rjs', evaluateResponseIf('text/javascript'));
sendTo(), updateForm() and evaluateResponseIf() all are functions that return pre-built callback functions for common tasks, the implementation of which is left as an exercise for the reader (I hate it when people say that…well, back at ‘cha blogosphere!). In a large body of code creating a small amount of functions like this can make your code much more readable and maintainable.
There are tonnes of ways of using partial application in your scripts, not just for callbacks. I’d really like to see some of the libraries using techniques like this to simplify the function calls for common cases…
new Ajax.Request('entry/create', postFormAndUpdate('formname', 'mydiv'));
…would be quite nice. But of course, you can make your own.
by Daniel Finnie
Today's quiz would've been most useful in elementary school, where over half of the homework assignments were word search puzzles. The concept of these puzzles is simple enough that an elementary school student could understand it: given a box of letters, find a line containing the letters of a specified word in order.
For example, find the words ruby, dan, rocks, and matz in the following text:
U E W R T R B H C DC X G Z U W R Y E RR O C K S B A U C US F K F M T Y S G EY S O O U N M Z I MT C G P R T I D A NH Z G H Q G W T U VH Q M N D X Z B S TN T C L A T N B C EY B U R P Z U X M S
The correct answer in the correct output format:
+ + + R + + + + + ++ + + + U + + + + +R O C K S B + + + ++ + + + + + Y + + ++ + + + + + + + + M+ + + + + + + D A N+ + + + + + + T + ++ + + + + + Z + + ++ + + + + + + + + +Y B U R + + + + + +
Notice that the words can go backwards and diagonally, and can intersect one another. Searching is case insensitive.
The word search solver should accept input entered by the user after running the program, i.e., not exclusively through STDIN or a file, by entering the puzzle line by line, pressing return after each line. A blank line indicates the end of the puzzle and the start of the comma separated words to find. The following example shows how a user would enter the above puzzle, with descriptive text from the program removed.
$ ./wordsearch.rbUEWRTRBHCDCXGZUWRYERROCKSBAUCUSFKFMTYSGEYSOOUNMZIMTCGPRTIDANHZGHQGWTUVHQMNDXZBSTNTCLATNBCEYBURPZUXMSRuby, rocks, DAN, matZ
Now, by itself, this quiz is fairly simple, so I offer an additional challenge. Write a beautiful, extensible, and easily-modifiable program without looking at the extra credit before starting. When you're done, try implementing extra credit options using less than 5 or 6 (reasonable) lines of code.
* An output format superior to the one given. The output format given should remain the default unless both formats don't differ on a textual basis. That should sound cryptic until pondered, I can't give too much away!* Allow for "snaking" of answers, in other words, the letters composing a word don't have to be in a straight line.* An option to give a hint, i.e., "The word ruby traverses the bottom left and bottom right quadrants."* Decide what to do with accented letters.* Allow for wildcard letters.

I'm glad the people behind RubyForge have come out with a formal plan for handling 'abandoned' projects. I don't like the decision they made, but it's their's to make, so I guess I can't argue. Instead, I'd like to make sure I 'bus proof' my projects — if I get hit by a bus (or otherwise drop off the 'Net),
To me, running a project is both an opportunity and a responsibility. In starting
As I semi-jokingly stated for _why's Year in Review, 2006 for me could best be summed up by: "release lecture release consult release overwhelmed release conference release".
ActiveMessaging now has a new home at Google Code. As I barely have time to even post to this blog any more we also have a new maintainer: Andrew Kuklewicz.
Please direct all questions, thoughts, ideas to the new mailing list.

Suckbuster. From David Platt, a blog that chronicles software that sucks, and software that just works. And he’s asking for your help identifying the sucky and the worky.
The road to Lisp. Arto Bendiken takes on the challange and presents some of the better arguments I’ve read.
Cut off. And it still doesn’t work.
Next step. Brian Oberkirch [...]
I've noticed a lot of people asking questions about ajax, rjs, scriptaculous and other whizzy cool effects lately. So I thought I'd document a couple here so there's less confusion about some of the simpler effects. I've included an element toggle on a hyper link, a simple div that updates with data from an action using link_to_remote, and others. Enjoy.
You'll learn effects like these: Video of ajax effects
All of these examples assume you have included the default javascript files in your application.rhtml file:
<head>
<%= javascript_include_tag :defaults %>
</head>
The first of our simple effects is going to have to be the simple toggle (hide/show) of a div element. There is no remote call used in this, it simply uses javascript (generated by our ruby code) to show and hide a element of our choice.
<%= link_to_function "toggle with my div", "Element.toggle('to_toggle')" %>
<div id="to_toggle">
Now you see me, now you don't!
</div>
Next we're going to fire an action from a link_to_remote and then update a list of items on the page, this involves multiple code pieces in different files, keep up.
## app/views/words/index.rhtml
<ul id="sentence">
<li id="word_1">baby</li>
<li id="word_2">unzip</li>
<li id="word_3">my</li>
</ul>
<%= link_to_remote "WHAT?!?", :url => { :controller => 'words', :action => 'update' },
:loading => "Element.show('loading')" %>
<div id="loading" style="display:none;">Loading...</div>
## app/controllers/words_controller
def update
@word = "laptop bag!"
return if request.xhr?
end
## app/views/words/update.rjs
# hide the loading text
page.hide 'loading'
# insert a new li into the element with an id of sentence
page.insert_html :bottom, 'sentence', "<li id='word_4'>#{@word}</li>"
Notice how we use the same name for our rjs file as we did for the action we called, and then we ask the controller to return if the request was an xml http request (which is what ajax uses). This way if we want to do both rjs and standard requests with the update action we can.
I also demonstrated the use of a loading div here, but you could use a loading image as well, like a spinny circular thing or dots...or whatever takes your fancy.
Let's modify the above example to highlight the new element when it arrives, this one's far too easy. Add this to the bottom of update.rjs:
page.visual_effect :highlight, 'word_4', :duration => 3
Now when the element is added, you'll have your attention drawn to it. The duration can be left off because it's optional and defaults to 2 seconds, I just wanted to make you aware that it's there.
Again, modify our existing call and make it slide down instead of just appear, change the update.rjs to this:
# hide the loading text
page.hide 'loading'
# insert a new li into the element with an id of sentence
page.insert_html :bottom, 'sentence', "<li id='word_4' style='display:none;'>#{@word}</li>"
page.visual_effect :blind_down, 'word_4', :duration => 2
We added to our li item a style of display, and set it to none. This is standard inline css markup, so when the item is added to our page it's hidden. Then we use the blind_down visual effect to slide it down with a duration of 2 seconds.
I hope this helps all the ajax beginners get started with effects you can play with, be sure to check out the Rails api documentation for more scriptaculous effects.
Any questions boys and girls?
I have been working on optimizing my nginx.conf file as I use it on more and more sites. Thanks to folks on the nginx and mongrel mailing lists for some of these fixes. Main improvements is in gzip of dynamic and other content as well as setting the proxy buffers to 0 and a few improvemets in the proxy header settings. This conf also includes a second vhost for ssl that points to the same mongrel cluster so you can hanlde ssl and non ssl with the same cluster and rails request.ssl? helper will work correctly.
Another big improvement is with static file handling. The credit on this one goes to Zed Shaw. He notcies that the rewrites and regex tests for rails cached pages were getting run for every request including static images. So a request for /images/foo.jpg woudl get served in this manor:
/images/foo.jpg/index.html # no file found continue
/images/foo.jpg.html # no file found continue
/images/foo.jpg # good send it!
This is obviously a performance hit for static files as it has two extra regexes and two extra file stats for every static image. Suck, I wish I found this sooner. To fix this all we need to do is add this test right at the top before the other rewrite tests:
# If the file exists as a static file serve it directly without
# running all the other rewite tests on it
if (-f $request_filename) {
break;
}
In my benchmarks this does increase the speed of static files about 8%. Also allowing gzip on HTTP 1.0 requests made sure that the proper static assets are gzipped when possible. Also we force all proxied requests to be gzipped if they are the right content type. I also added more gziped content types and corrected a wrong one for javascript.
This is an important lesson about your production environment folks. With regards to what you accept as gospel from someone like me. “Trust but verify”. Zed was trying to track down how to do a custom rewrite for alternate cache directories and so he at my behest turned on the debug logging and consequently saw the rewrites happening on every static file. I haven’t been in the rewrite log for a while since I thought my config was good. So when you get config files from people like me off the net, please trust but verify on your own systems.
This new config is running close to 100 instances of nginx at Engine Yard. Nginx has proven to be an excellent choice for a front end proxy balancer for mongrel. It beats apache in all my tests now as far as non gzipped proxy requests, static file requests and it ties with apache for gzipped proxy requests. And its about 30 times more lightweight then apache.
If you were holding off to try nginx until it was proven out by others then let me tell you it has proven itself to me time and time again already as a very easy to manage, high performance options for rails deployment on mongrel. I don’t personally use apache2.2 right now for anything other than mod_svn for subversion over HTTP. But there is stirring of upcoming support for nginx and svn over webdav so stay tuned. When that happens I will happily drop apache from our rotation entirely. Of course take this with a grain of salt as always, I don’t have to support any php apps or legacy stuff right now, just rails. I haven’t personally used php with nginx yet but I see others getting fantastic results so I am not worried for when I may need it.
All in all this new config file performs significantly better then my old one. Somewhere on the order of 20% total improvement overall over the last config file. I have updated the link to poitn from the old article to the right confi file and I am linking it here again for your enjoyment:

Tip of the day: rcov.
Writing tests is all well and good, but how do you know when your application is sufficiently tested? Especially when you’re just learning how to do automated testing, it can sometimes feel pretty arbitrary. However, there are many different metrics for evaluating the efficiency of your tests, and one of the simpler to measure is code coverage. How much of your code do your tests exercise?
Mauricio’s “rcov” utility does just that. You use it to run your tests, and it then reports a percentage (total, as well as per file) of how many lines of code were executed. It even gives you a view of each file, with the untested lines in red! Really, really helpful. Your tests will run slower under rcov, but not much slower—and it is incredibly faster than other previous tools. Also, it works really well with Rails applications.
Now, those of you that are testing gurus will be quick to point out that relying solely on code coverage can be dangerous, and I will agree. Code coverage should not be the only metric you use to evaluate your tests. Ensuring that every line of code has been executed at least once does not even come close to guaranteeing that your application is correct, but it is a lot better than shooting tests randomly into your domain and hoping for the best.
Besides simple code coverage, others in the Ruby community are working all the time on different techniques for testing. You could do a lot worse than to follow what Ryan Davis is concocting with his ZenTest suite of tools.

The Rails Analyzer Tools are a very useful way to keep tabs on the performance of your site. They were written by Eric Hodel and have been open-sourced to the community by the Robot Co-Op.
The problem is that you need to install and run SysLogLogger to make it work. If you have more than one Rails app on a box, or if you don’t have root access to the box, or if you are on a shared host, you are out of luck.
No longer!
gem install production_log_analyzer
gem install rails_analyzer_tools
Download the logger replacement and put it in your lib directory. (I’ll make this into a proper plugin soon.)
In the Initializer section of environment.rb, add
require 'hodel_3000_compliant_logger'
config.logger = Hodel3000CompliantLogger.new(config.log_path)
For some reason, the standard script/server forces logging to work the old way. If I run mongrel_rails start, it works fine. I’m also running a production app with mongrel and it works as expected.
If you tail -f log/development.log you should see something like this:
Jan 03 10:08:09 topfunky rails[4535]: Rendered shared/_menu (0.14430)
Jan 03 10:08:09 topfunky rails[4535]: Rendered shared/_flashes (0.00882)
Jan 03 10:08:09 topfunky rails[4535]: Completed in 1.70117 (0 reqs/sec) | Rendering: 1.61409 (94%) | DB: 0.02340 (1%) | 200 OK [http://localhost/products/capistrano-concepts]
Deploy your app, or just try this out locally from the command-line.
$ pl_analyze log/development.log
Request Times Summary: Count Avg Std Dev Min Max
ALL REQUESTS: 33 0.226 0.304 0.005 1.695
OrdersController#show: 6 0.071 0.112 0.005 0.316
ProductsController#show: 3 0.306 0.061 0.231 0.381
ProductsController#home: 2 0.318 0.068 0.249 0.386
OrdersController#index: 2 0.328 0.206 0.123 0.534
PagesController#show: 2 0.432 0.047 0.385 0.479
ProductsController#index: 1 0.279 0.000 0.279 0.279
Slowest Request Times:
OrdersController#index took 0.534s
PagesController#show took 0.479s
ProductsController#home took 0.386s
PagesController#show took 0.385s
ProductsController#show took 0.381s
# DB times and Render times follow
rails_stat is also nice for seeing a live report of the performance of your app.
$ rails_stat log/development.log
~ 0.9 req/sec, 14.2 queries/sec, 19.9 lines/sec
~ 0.3 req/sec, 14.1 queries/sec, 17.0 lines/sec
Run the report in a cron task and send the results to yourself via email (see the -e flag to pl_analyze), or automate the reporting with Capistrano.
desc "Analyze Rails Log instantaneously"
task :pl_analyze, :roles => :app do
run "pl_analyze #{shared_path}/log/#{rails_env}.log" do |ch, st, data|
print data
end
end
desc "Run rails_stat"
task :rails_stat, :roles => :app do
stream "rails_stat #{shared_path}/log/#{rails_env}.log"
end
For more details on Capistrano, buy the new PeepCode Capistrano Concepts screencast.
For extra credit, use my Mint Pepper plugin and my Mint Rails Plugin to put nightly data into the database (also requires the setup of logrotate, to be discussed later).
Remember, this is not about maximum performance. These reports show you the actual performance of your app as it is being browsed, not the theoretical maximum performance.
As mentioned here Ruby trunk now contains YARV. YARV is a Virtual Machin for Ruby and Ruby trunk is what will become Ruby 1.9.1 (it is 1.9.0 as of now).
The benchmark looks really promising.
Nifty little application for Mac OS X.
SoundBoard ist an Application to play sounds. Yeah. You can define soundsets and load sounds into them. All sounds are accessible via the dock menu for quick intervention :)"

(This article is part of the Big Rewrite series.)
To add to the stress of the Big Bang comes another, mostly people-related issue. Almost all technology rewrites are driven by some technologist. Behind almost every technologist pushing for a Big Rewrite is a business person saying “But, why?” The question is valid. The product already works. It’s successful enough to even consider re-plumbing it, so we must have already gotten something right, no?
So, then come the justifications. They start with the real reasons the software is being rewritten (but usually censored to avoid the technologist looking like he or she screwed up big time on the initial development of the product). The system will be more maintainable. It will be easier to add features. “Oh yea? So we can do more features faster?” “Uh, yea.” “How much faster?” And so on.
As those discussions get heated and prove unsatisfactory, the list of promises gets longer. The system will be more scalable. System response time will improve for our customers. We will have greater uptime. And so on.
It’s rare, in fact, that a technology rewrite can deliver on all these fronts. A J2EE Web application may not prove in practice to provide higher availability than a mainframe application. Rails might be a more flexible and productive environment for a developer, but Rails apps slightly underperform equivalent PHP apps. So, you don’t sell Rails as something that will be faster than PHP. You sell it as something that is more flexible and maintainable, and will perform reasonably compared to a PHP application.
The piles of justification lead to piles of additional work and/or piles of mismatched expectations and disappointment after release.
(This article is part of the Big Rewrite series.)
When you do a technology rewrite, you want things to be clean. That’s usually a major goal in a project like this. And at the beginning of a Big Rewrite, while you’re still wide-eyed and hopeful for your application’s ultra-elegant, scalable, maintainable future, you’re faced with a question: Should we deliver the Rewrite incrementally or all in one big release? Now, imagine your existing infrastructure is a home-grown Oracle Pro*C-based CGI framework with its own cookie-based authentication mechanism which relies on carnal knowledge of an aging mainframe ERP system. Incremental deliveries means making the new technology work within the dirty framework of the old system. One big release would mean we could just turn off the old system, turn on the new one, and keep our new efforts isolated and pristine.
In most cases, it’s the Big Bang approach that wins the argument.
Now picture yourself as a developer or project leader nine months into this project. The old system, still in production, has been patched and enhanced along side the new one as you’ve been developing it. You haven’t had time to keep up with each and every change that took place in the old system. As a result, on top of behavioral changes, you’ve got an ever-evolving database schema to port to the new platform. And the new system’s wish list has gotten so out of control, that there are major differences between the old and the new. To top it all off, working from the old system as a specification didn’t work, and you’re way behind schedule due to misunderstood requirements and rework.
The table has been set. The guests are on their third course. And now you have to come along and replace the table on which they’re eating without disturbing their meal.
On a big system with a lot of customers, data migration can be a huge problem. Not only do we have to keep track of what gets migrated when, but we have to actually perform the migration at some point. The Big Bang sounds like a lovely idea until you get to the actual event, and you realize it’s kind of like preparing for a world title boxing match when you know it’s the first and last time you’ll ever compete. The processes and software you have to create, the attention you have to pay before you can create an event like this is often as consuming, complex, and potentially disastrous as the system development effort itself.
But by making it a Big Bang release, you’ve maximized the chances that you’ll be behind schedule when you get to the end, and you’ve therefore maximized the chances that you won’t spend enough time preparing. This results in a bad time for both you and your customers.
Unfortunately, perhaps due to something intrinsic in human nature, this scenario is a cliche for Big Rewrite projects.
I love TextMate, it's beautiful, efficient, and extensible to the nth degree. So as I was running though some tests I thought I'd make my own theme based on Sunburst, and here's what I came up with:

I'll bundle it up as a theme if anyone is interested, but for now it's mine, all mine!
Edit: Grab the succulent theme from here.
Please comment below if you use /like/dislike the theme, thanks.

Just a note, this post is a work in progress, and should see updates about twice a week. Hopefully it's useful even while it's incomplete.
Representing Ruby Objects
To start with, it's probably worth describing a bit about how rubinius source is laid out, then we can dive into the specifics about Ruby objects.
The rubinius source tree is laid out like this (omitting stuff we're not interested
A while ago, Mauricio Fernandez posted an excellent Guide to Ruby Internals. Since YARV, JRuby, and rubinius are all drawing more attention, I thought it would be great to see parallel guides to each of these platforms as well. I'm going to try to take on rubinius, but I'll happily link to anyone doing the others.
Here's a quick table of contents. It's not complete, nor are the sections

Double of half. “But I think it worth it - to sacrifice three times slowdown for doubling the speed almost arbitrarily and almost effortlessly.” Freudian slip?
swap(ctrl, cmd) A handy reference to what every OS/X user knows, and what a non-OS/X user like me finds bewildering.
Eye candy. KDE4 promises some serious eye candy with SVG rendering. [...]

This time around, I'm interviewing Christian Hellsten, the co-author of Beginning Ruby on Rails E-Commerce (I interviewed Jarkko Laine the other co-author here).
Christian, would you please introduce yourself?
Christian: I'm a father of two, a software consultant, and as of lately founder and CEO of Aktagon.
Why do you do outside of Ruby on Rails devleopment? Any hobbies?
Christian: I
Ads