Clued in about Classes? Are you sure?

Thus completing the mathematical proof that consumed twelve chalkboards, Prof. Grizzletooth grinned a grizzly toothy grin at his students. Then he toothed a toothy grizzle. Then, self-consciously, he simply grizzled a tooth. Finally, he pointed at the last line, which simply said ‘1 = 2′. “Ah, the sheer beauty of it!” giggled Grizzletooth, “Proof by contradiction. It is sort of like when you are playing Clue and you realize that Mr. Brown could not have been in the study at the same time as Prof. Plum, who had possession of the Revolver, meaning that the real murderer was Col. Mustard, who did the dastardly deed in the Convervatory with the Knife.”

The class was dazed, but still chuckled. They wanted to be excited about whatever-the-hell Grizzly was talking about, but somewhere in the proof they got lost. More precisely, 90% of the class was completely dumbfuddled and befounded (they couldn’t figure out which) around line 2, when Grizzletooth made use of the Houdini Conjecture.

What does this have to do with Rails, you say? Quite simply, the good thing about being a Grizzletoothy student is that you realize that you are confused — and you realize it early.

Myself, on the other hand, sometimes pretend like I understand something at first, only later to discover that I completely skimmed over something important. Looking back, I realize that maybe I should have stopped at line 2 and said “what on earth is happening here?”

Take for example, the following code snippet. This is as easy as it gets, right?

class PersonController < ApplicationController
  layout :standard
  def index
  end
end

Paired with the other usual files in the proper places (index.rhtml and standard.rtml), we’re off and running. But I intend to demonstrate that something is happening here, from a language point of view, that I’ve overlooked until now.

Let’s examine this file, line by line. On line 1, we define the class and what it inherits from. On line 2, we call the method named “layout” and pass the parameter ‘standard’. On lines 3 and 4, we define the “index” method. The index method is empty, but is still useful; it just so happens that Rails automatically calls “render :index” for us.

But wait a minute, what is going on with line 2? How can we call a method on the first line inside of a class definition? That seems a bit sudden, don’t you think? What scope are we in, anyway? I mean, I don’t even know if we in the Conservatory or the Lounge! And what in tarnation is a Conservatory anyhow? Do you keep rare birds and reptiles in there?

To put it another way, at what point does line 2 get executed? Whenever an instance of the class is created? Some other time? I don’t know if this craziness is due to Ruby or Rails or both, but moments like this call for some Ol’ Janx Spirit.

I’ll let you know when I figure this one out. I’m going to go investigate in the Library, right after I smack Miss Scarlet over the head with the Lead Pipe.

DRY

Trevor McChattergee is the kind of person that you never want to be stuck with on a long airplane flight. Don’t be fooled; he seems nice enough at first, but he just doesn’t know when to say when.

I’m not talking about drinking, either. Trevor is guilty of a problem that does not have a 12 step solution. Let me paint you a picture. In situations where normal people use 5 words, Trevor uses 50.

In Ruby, this translates to:
@trevor = Person.new( :bullshit_factor => 10)

Instead of the socially acceptable few minutes of banter — and then back to your in-flight entertainment, Trevor activates the Enterprise’s Tractor Beam and monopolizes your attention for the next 1000 miles of your life. Just be glad the plane flies at least 200 mph, or you might eventually decide that trying out skydiving into the Midwest is preferable to Trevor’s company.

You’ve all been there. You all have met someone from the McChattergee family. Bless their hearts. (BTW, this is the Texan version of Marlon Brando saying “The Horror!”)

Yes, to put it mildly, Trevor is holy crusader against the “evil” concept of brevity. “The experience that we call life cannot be neatly compacted into fastidious little morsels or maxims or the like,” Trevor interjects, “rather, any true connoseur of life must fully articulate his emotional compunction to the fullest and most expansive degree attainable given his vocabulary and…” WHACK!

Wow, talk about audience participation. It appears that one of my readers has decided to articulate his feelings towards Trevor with panache, sending Trevor flying across the cabin while flying the friendly skies, thereby shortening the conversation, getting things moving in the right direction as it were, to… OUCH! I get the idea. Enough about Trevor. I promise to talk about Rails!

But first, have you met Billy McChattergee, the developer? He’s Trevor’s cousin. And brother. (Bizarre, yes, but understandable when you realize the fractal dimension of the McChattergee family tree approaches 1 over time.) Trevor and Billy share the same last name for a reason. Billy never uses 5 lines of code when 50 will do just fine.

@billy = Person.new( :coding_bullshit_factor => 10)

Being on a programming team with Billy has a few advantages. Actually, just one. You get the opportunity to get a haircut while reading Billy’s tangled mess of codeshit, because you are going to become a hairy gorilla by the time you are done. (My apologies to the women out there! — you will become hairy gorilla-ettes!) Seriously, I propose a contest. If you can read Billy’s latest code faster than I can read Paradise Lost, I’ll submit myself to torture. (By torture, I mean watching 5 minutes of FOX News. My apologies to those who actually watch FOX News and consider it to be fair and balanced.)

What do Trevor and Billy have to do with Rails? Rails is the antithesis of the McChattergees. Rails is based on the DRY principle — Don’t Repeat Yourself. Look! Trevor regains consciousness, rubs a huge knot on his head, and interjects: “Rails in based on the the DRY principle…” WHACK.

Anyhow, there are many ways to achieve DRY Nirvana.

So far, in my reading about Rails, I have seen lots of side-notes about how Rails helps you stay DRY. But I don’t think I’ve seen an all-in-one place explanation of how to stay DRY. I will try to summarize some key points here.

Let me first say this: it takes some experience to realize when you are repeating yourself and how to fix it. The two are connected. Where you are repeating yourself (in a view template, for example) helps suggest a solution (helpers or layouts).

  • If one or more (1+) view files (i.e. .RHTML files) share common Ruby code, you probably should factor it out into a helper file. (Agile Web Development with Rails, will give you all of the details. If you are seconding the Second Edition, check out section 22.2.)
  • If 1+ view files share common markup (HTML), you should probably factor it out into a layout file.
  • If 1+ methods in a controller file shares common code, you probably should factor it into a private method.
  • If a helper file and a private controller method share code, what do you do? AWDwR says, “You can add controller methods into the [view] template using helper_method.” But it also warns, “Think hard before doing this — you risk mixing business and presentation logic. See the documentation for helper_method for details.” Incidentally, I think I’ve stumbled across a place in my code where I have a legitimate use for helper_method. I will try to remember to post about that if it pans out.
  • If you specify attributes in your model files AND in your database schema (or migrations) you risk contaminating your fine Rails’ pedigree with McChattergee. AWDwR suggests in Chapter 17.2 to trust your database schema (i.e. ActiveRecord will handle the model attributes for you, provided that you follow the naming conventions.)
  • If you find yourself using internal URLs for navigation between pages or otherwise, you probably aren’t DRY. You are not even close, as Rails encourages the use of Rails’ routing. See 20.2.

But let me warn against taking DRY to the extreme. Joel on Software has a chapter in his book about “Architecture Astronauts”. Let me interpret what this means in this context. This kind of astronaut is really good at abstraction, which can be good in moderation. But the AA goes too far. To the moon, and beyond. He (or she) goes so far with abstraction that these abstractions become impractical.

I suspect that there is a trade-off at work here. Each time something is abstracted, you may gain generality and insight. But at the same time, you risk losing radio contact with your audience / community / mother ship. In other words, you begin speaking another language. Granted, your new language may be superior (clearer, less ambiguous, and with built in error control) — but have you taken the time to teach others how to speak it? Even if they do understand, maybe speaking your language involves serious computational time — everytime you speak in a generality, your audience must translate it to particulars.

Hopefully the consistency and higher-level picture that an abstraction gives is worth this cost! Think about it. Does elegance (as perceived by the architecture astronaut gods) trumps usability (by the everyday coders or new guys)? Who is going to carry the banner for your new language? The elites? Or the everyday speaker?

In conclusion, Trevor McChattergee is the kind of person that you never want to be stuck with on a long airplane flight. Don’t be fooled; he seems nice enough at first, but he just doesn’t know when to say when.

Fulltext Searching

Detective O’Malley was furiously at work. “So many suspects, so little time,” he muttered to himself. Such a dastardly crime had to be solved — and soon!

O’Malley recounted the details of the crime. It was a rainy day in October at a public library in Austin. The head librarian had arrived at 7 am to unlock the doors. Everything seemed normal at first. But then — the horror! — she noticed the card catalogs HAD GONE MISSING. What would the library’s patrons do? How would they find the information they were looking for? It seemed that, in a single act of perpetration, the perpetrator (or perpetrators) had rendered the library virtually useless.

Unfortunately, the story gets worse. It was not just a single act of sinisterness — the criminals had doubled down on their diabolical debauchery. How? In their evil wake they left a personal computer that enabled a Web-based, full-text search of the library. The irony was almost painful — the library, in fact, was not virtually useless! It was virtually awesome!

This mockery was simply unacceptable. On whose authority dare their do this? Full-text searching, of course, was a black art — an enigma shrouded in a mystery enveloped in a vague, incomplete sentence… O’Malley could smell sinister smeared all over this one.

But still, in a sick way, O’Malley was impressed. It was a professional job. The locks were picked, not broken. No prints could be found. The security system, strangely, was deactivated, but not harmed. All the unshelved books had been re-filed. The Web seach engine was based on Ruby on Rails. The user interface was clean, elegant, and standards-compliant. The library’s carpet was vacuumed and their plants watered and fertilized. All of Bill O’Reilly’s and Ann Coulter’s books had been placed in the recyling bins, as a humble suggestion.

It was too strange. O’Malley knew there was a clue in there somewhere. His initial hunch was badly off-target: a search in the yellow pages for “criminals with green thumbs” was fruitless. Luckily, his colleague, Dr. Rapp, pointed O’Malley down a different path. “This Ruby on Rails thing is quite the rage right now,” said Rapp, “You might want to work that angle.”

“Right!” said O’Malley. He called in his investigatory team and posed this question: “How could these evil masterminds use Ruby on Rails to conduct a full-text search?”

The team went furiously to work. In a few hours, the investigation led to these primary suspects:

  • Ferret
  • Hyper Estraier
  • MySQL full text engine
  • PostgreSQL full text indexing

O’Malley will need some time to carry out the full investigation, but Chief McMillan expected the results the day after yesterday. Hopefully O’Malley can stay away from that Old Janx Spirit.

Tarantino on Rails

I thought about back-tracking to that fateful day when I first starting learning Rails. Then you all could marvel in this journey. You could live vicariously through me. You could share my triumphs and weep with me at my failures.

But no! That would be too boring of a story. Instead, this will be Ruby on Rails, Tarantino-style. I’m going to jump right in in the middle of the action. The plot will already be quite twisted, the characters developed. Where does that leave you, the audience? Probably confused at first. But trust me, it will all fit together at the end.

Won’t you pour me one more of that sinful Old Janx Spirit.

Learning Ruby on Rails is quite an adventure. What kind of adventure? It is remarkably like drinking Old Janx Spirit.

Oh don’t give me none more of that Old Janx Spirit
No, don’t give me none more of that Old Janx Spirit
For my head will fly, my tongue will lie, my eyes will fry and I may die
Won’t you pour me one more of that sinful Old Janx Spirit.

Ruby, the language, is awesome. By awesome, I mean awesome in a scary way. The power you have at your disposal can be used for extreme good or extreme evil. (At least from the perspective of 1’s and 0’s, which surely outnumber most life forms on the planet.) Ruby lets you can define classes at run-time. You can redefine classes if you want. Meta-programming in abundance is yours!

Rails, scissors-in-hand, runs full-speed with Ruby, doing things only idiomatic languages can do. Have you noticed that Rails brags a lot about being idiomatic? Does that mean that idiots can automatically use it without any problems?

I’m not the only one who thinks the Ruby on Rails is a bit awe-inspiring. Take this excerpt from Agile Web Development with Rails (the version 2 pdf) for example. It is titled “Why extending base classes doesn’t lead to the apocalypse”.

The awe that seeing 5.months + 30.minutes for the first time generates is usually replaced by a state of panic shortly thereafter. If every one can just change how integers work, won’t that lead to a complete and utterly unmaintainable spaghetti land of hell? Yes, if every one did that all the time, it would. But they don’t, so it doesn’t.

Trust me, it only takes one drink of Ruby on Rails, and you’ll be coming back for more.

Follow

Get every new post delivered to your Inbox.