Here''s my review of Chapter 3: As the author says, this is a transitional chapter. The first chapter was an introduction to Ruby, and the second was a similar introduction to Rails. Now we begin the real purpose of the book, which is to dig into the Ruby behind the Rails. Periodically the question arises on this list about how much Ruby you need to know in order to do Rails. Chapter 3 provides an elegant answer to that question, which boils down to four main issues: 1. Knowing Ruby helps you understand how Rails is handling your application behind the scenes 2. If you know Ruby, you can go beyond the common Rails idioms and techniques 3. The Rails source code is written in Ruby, so you can dig into the framework and possibly revise and extend it 4. Ruby applications integrate naturally with Rails, so you can write Ruby programs that incorporate Rails functionality. For me at least, this isn''t a hard sell. I teach software development training courses for a living, and that means I always need to be prepared to answer questions about how the technologies actually work under the hood. To pick a simple example, many times I''ve encountered page designers with little real programming experience who want to know if they can learn JavaServer Pages without knowing any Java. The answer is "yes, but really no". In other words, you might get away with it for a while, but you''re going to be very limited in what you can do. Plus, you won''t really understand how JSPs work unless you''ve learned about servlets, and so on. The author frames this issue very elegantly by pointing out two things: 1. Rails feels like a domain-specific language (DSL), so much so that you can forget there''s a powerful programming language behind it, and 2. Rails coding often feels like you''re simply doing configuration. It looks like you''re simply setting the values of some variables, when in fact you''re invoking Ruby methods in a transparent way. As a simple example, the author discusses "has_many :editions". To Rails developers without a Ruby background, this looks like you''re simply setting a variable. Rubyists (how do you spell that, anyway?) know that in fact you''re invoking the has_many method in the super class with the ":editions" symbol as an argument. It''s a good point - I rarely think about that until it is pointed out to me. The DSL that is Rails comes with many common conventions which in fact simplify Ruby considerably. I have to admit that when I first dove into this field and started reading the pickaxe book (Programming Ruby by Dave Thomas for those who don''t know - get thee to www.pragmaticprogrammers.com <http://www.pragmaticprogrammers.com/> and buy it if you don''t have it), I didn''t find Ruby nearly as "simple" as everyone says. In fact, compared to Java, Ruby is actually much more complicated! I know that sounds strange, but note that the criticisms of Java on this list often come down to the explosion of libraries, frameworks, and supporting technologies in the J2EE world, not the language itself. The basic language is in fact pretty simple, certainly much simpler than its C++ predecessor. When I teach Java to new developers I only have to help them get over the object-oriented hurdle and then they''re okay. The syntax and idioms are actually pretty intuitive. I rarely hear anyone talking about an "obfuscated Java" competition. Ruby, on the other hand, gives you dozens of different ways of doing the same things. Its Perl heritage throws a huge legacy of regular expressions and metaphors at a nuby. Ruby also adds concepts like blocks, lambda functions, mixins, and more. All of that makes Ruby extremely powerful, but IMHO give it quite a learning curve. Rails helps that whole process by establishing a small set of simple conventions that help a newcomer get going quickly. Simply the fact that because the Rails community has agreed that you''ll never see "has_many(:editions)" or its even more explicit cousin "send("has_many", "editions".intern)", everything becomes much clearer and easier. I often compare this to the fact that writing free verse is extraordinarily easy, so there''s a lot of it and most of it is appallingly bad. On the other hand, too many conventions can be overly constricting - even computers can write fugues, and only they would bother doing so any more. The author uses the example of YAML to illustrate that Rails feels like its configuration rather than programming. I wondered about that myself - why introduce a completely separate technology in the midst of Rails? The answer apparently comes back to the Ruby YAML library, which sees a YAML file as a nested Ruby hash and can convert between those formats easily. The next section illustrates some of what this knowledge buys you. A common theme is that its Ruby heritage implies that Rails does not intend for a developer to confine themselves to already-developed Rails tags, but in fact encourages expansion. DHH himself has said as much on many occasions, stating the normal open source argument that if you see a problem or something you want to improve, go ahead and do it; you''ve got the source code, so take advantage of it. What I hadn''t realized is how much the Ruby basis makes that easy and natural to do so. The author illustrates this idea in several ways. The first area is adding functionality to a controller. To do so, he shows a sample from a live Rails application, the Ruby Change Request site (http://www.rcrchive.net <http://www.rcrchive.net/> ). There he points out that the site authors were able to achieve easy sorting capabilities in the displayed table by adding a short, relatively simple Ruby function. He then writes a "link_to_order" method on top of the normal Rails "link_to" method as an example of an application helper for the view. Moving to adding functionality to models, the author starts by overriding the "before_create" method in a model class. This is a classic example of the Template Method design pattern (in its "hook" variant) from the so-called Gang-of-Four, which I''m sure the author knows but doesn''t state explicitly. Then he points out that you can add new functions to the model classes and invoke them as you please. I suppose the Java analog would be to talk about overriding callback methods in Struts, and adding methods other than getters and setters to JavaBeans. I should mention that here is where I had my one problem with this chapter. On page 83 of the book (page 21 of 29 in my PDF file), the author parenthetically remarks that you can try out the new "before_create" method by changing the description of one of the records to NULL, reinitializing the database with it, and noticing that the description field now says "standard". When I did that the description stayed NULL, puzzling me for a while until I realized I''d re-run the SQL script directly and therefore bypassed all the added Rails functionality. :-) When I did the console demo at the end of the chapter (and therefore used the framework to do the inserts), it worked as advertised. Finally the author writes a Ruby application to convert legacy data (in YAML format, of all things) into saved data in a database that follows Rails conventions. It''s an interesting application, which uses Rails by creating objects of the proper type and invoking their save method. This last demo provides the needed segue to talk about the Rails console, invoked by "ruby script/console". Though I''d used that script once or twice, I hadn''t realized that it was simply an irb session with the components preloaded. While that is seriously cool, I imagine it means you can''t invoke controller methods there. Still, it''s a great tool to have handy. In summary, for me at least this was the best chapter of the book so far and also showed how this book is different from all the other Rails books currently available. I can''t wait to see the next chapters. Ken Kousen -- Kenneth A. Kousen, Ph.D. President Kousen IT, Inc. <http://www.kousenit.com> http://www.kousenit.com <mailto:ken.kousen@kousenit.com> ken.kousen@kousenit.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060220/676cd8da/attachment-0001.html