When I was young, access to computers wasn’t quite as readily available as it is today. Undeterred, I used to ride my bike up to the University of Maryland. My mother once wondered what I was doing with all those college students, so she stopped by. As luck would have it, just as she entered the room, a college student approached me and asked for help with her assignment.
This was remarkable on a number of levels, and all the more so once you realized that the college actually paid a student to provide free help with assignments. The important difference between the help he (and it inevitably was a he) provided and the help I provided was that he generally sneered at the person, told them that they did it all wrong, and then proceeded to completely rewrite their assignment for them. In the process, they learned nothing. By contrast, I would take the time to understand what they were trying to do, and suggest a few small changes.
My heroes today are those that are able to pop the hood, and look inside and look for small changes. Using tweezers if necessary. These types of people eschew complex frameworks, and instead are able to write their own on a moments notice. And when things go wrong, they take ownership of the problem.
I was reminded of all this when I observed the humorous exchange between Tim Bray and Leon Spencer. While my response isn’t going to be as entertaining, I suspect that it will be a bit more educational.
Let’s start with Tim’s example. I assert that what he wants to do can be done with an existing framework. I’ll demonstrate using XML::Builder
@w = Builder::XmlMarkup.new @w.tag! :html do @w.tag! :head do @w.tag! :title, 'Atom Protocol Excerciser Report' @w.nl! @w.tag! :link, :rel => 'stylesheet', :type => 'text/css', :href => '/ape/ape.css' end @w.nl! @w.tag! :body do @w.tag! :h2, 'The Ape says:' @w.nl! if @header @w.tag! :p, @header @w.nl! end @w.tag! :ol do @w.nl! @steps.each do |step|
Let’s review the changes. For starters, I removed some parenthesis. This is merely a matter of style, and reasonable people can have differing opinions on what’s best here.
Second, there is no need for an explicit call to
text; both can be readily inferred by the data types of the arguments.
tag!. While someone with a background in XML would certainly prefer the term
element, there is no denying that
tag requires fewer keystrokes. In any case, if element is preferred, Ruby has open classes, and an alias for this method could certainly be added.
Then there is the matter of the exclamation mark. It is intended to draw your attention to the fact that something special is going on here: and in this case it is the use of the syntax that was explicitly designed to support special cases like
<a-a_a/>. As an aside, one need not handle namespaces in this manner, for those who are interested, look in to the rdoc notes for details.
What’s nice is that when this special case isn’t needed, the code reduces further:
@w = Builder::XmlMarkup.new @w.html do @w.head do @w.title 'Atom Protocol Excerciser Report' @w.nl! @w.link :rel => 'stylesheet', :type => 'text/css', :href => '/ape/ape.css' end @w.nl! @w.body do @w.h2 'The Ape says:' @w.nl! if @header @w.p @header @w.nl! end @w.ol do @w.nl! @steps.each do |step|
I suspect that I can simplify further, but hopefully my approach is clear: I’m not taking something, throwing it out, and rewriting it. I prefer to incrementally improve it. I’ve also been careful to show how the original requirements can be addressed. Requirements like the ability to handle the full range of allowable XML element names, including those that can’t conveniently be expressed as method names. In the process, I’ve glossed over how I handled the desire for a shorthand for inserting a newline, those that are interested can explore the full source.
I assert that all of this is important to people who want to be able to pop the hood. And in closing, I’ll take a look at a few artifacts that Leon has produced: XHTML 1.0, RSS 2.0, Atom 1.0.
My questions are:
- Why assert that your HTML is XHTML 1.0 Strict, when it isn’t even well formed? Simply declare it as HTML Transitional and be done with it.
- Why place the author name in a field designed for an email address, especially as there is a more suitable alternative available?
- Why include a bogus type when the attribute itself is optional?
I suspect it is because Leon’s value system is different, and the desire to be able to pop the hood isn’t quite so strong in this one.