codahale.com٭blog

ringtones and graphicslaffy taffy ringtonebell ringtones freebleeding ringtone throughcinguar ringtones
Coda Hale lives in Berkeley, CA, where he writes about Ruby on Rails, usability, web design and development, and the occasional bit about bicycles.

Tacking into the wind

A weather forecast for Berkeley, CA, saying 'tons of rain,' '18mph winds,' and 'I hate you, Coda.'

I hate you too, Weather.

My ride home from work today had the following thematic elements:

  1. Torrential rain.
  2. Being totally soaked within the first 30 seconds.
  3. Insane traffic.
  4. 20mph+ cross-winds.
  5. Thunder.
  6. Lightning.
  7. The sound of limbs breaking in the trees lining the street.
  8. An inch of water on the road.
  9. Rain coming in almost parallel to the ground.

Now, if you’ll excuse me, I have to go do laundry, because my clothes aren’t wet enough.

1 comment »

So close… so very close…

Loaded suite example_test
Started
F
Finished in 0.041 seconds.

  1) Failure:
test_main_page(TestCodablog)
    [./lib/responsible_markup.rb:87:in `assert_valid_html'
     example_test.rb:7:in `test_main_page']:
Main page of codablog is not valid XHTML.
  Line 227, Column 154: “Rails” is not a member of a group specified for any attribute
    …or “Rails Sucks” Articles”>5 comments &raquo;</a>…
                   ^
  Line 405, Column 2262: character “&” is the first character of a delimiter but occurred as data
    …”>Ruby Code & Style</a></li><li><a href=”http://pod…
                   ^
  Line 227, Column 159: an attribute value literal can occur in an attribute specification list only
 after a VI delimiter
    …ails Sucks” Articles”>5 comments &raquo;</a>                             </d…
                   ^
  Line 232, Column 171: “Rails” is not a member of a group specified for any attribute
    …les for “Rails Sucks” Articles”>5</a>          <spa…
                   ^
  Line 232, Column 176: an attribute value literal can occur in an attribute specification list only
 after a VI delimiter
    …or “Rails Sucks” Articles”>5</a>          <span cla…
                   ^
  Line 405, Column 51: there is no attribute “onClick”
    …nk” onClick=”toggleBloglines(); return false;”>Blog…
                   ^

Get your validation on!
And mind you, I went and fixed these errors right after I posted this.

Leave a comment »

Grumpypants McGee

I was on the BART this morning when I realized something: trolling the intarweb looking for articles on how Ruby can’t work or Rails is just a toy and then writing long, tedious rebuttals doesn’t make me happy. It’s something I feel like I have to do; as if the world would be horribly misinformed if I let someone’s “Array has too many methods” comment slide. But you know what? That’s not my job; no one cares; and any effort I expend jabbering into the wind about how, no, Array#last is quite useful, thanks–that effort is wasted.

Array too complicated for you? Declare those methods private. Problem solved. Can’t figure out Rails? Well, I sure can. And you know what? It’s made programming fun again. I get to extend the language I work with instead of compensating for it. I write elegant code on a daily basis, and at the end of the week, I refactor it all to make it even better. For a guy like me, that’s the difference between a soul-crushing 9-5 and a wonderful working environment.

Molly’s post on stank standardistas cinched it for me. Yeah, I can bitch and moan about people misunderstanding a wide variety of things (e.g., Ruby, Rails, web standards, nonviolence, consensus, Thomas Dolby), but it doesn’t really produce anything. From here on out, every time I read about someone complaining about this, that, or the other, I’m going to take that irritation I feel and convert it into energy for one of my projects.

So what’s next? Well, I’m working on a plugin for Rails that provides unit test assertions for markup validity, unobtrusive Javascript, and other things we should be doing more often. It should be finished over the weekend.

Leave a comment »

Java and Ruby partisans: You’d think they’d get along better

There are honest critiques of Ruby. I’ll put that up front. It’s a fun language, but there are definitely areas which appear to have been designed by martians. But when Java developers lash out at Martin Fowler’s assertion that things like Array#first and Array#last are useful, their point tends to get buried in a flurry of misunderstanding. That’s a shame, since it’s a good point, too.

For example, take Elliotte Rusty Harold’s criticism of the Array class in Ruby. Much of what he says is true: Array#abbrev is almost useless, and there’s plenty of cruft to consider in Ruby’s standard classes. Making matters worse is that the documentation for these classes (outside of the Pickaxe book) is piss-poor, ranging from non-existent (REXML?) to delirious (YAML’s pony parade), to pathologically laconic (TMail). Given this wealth of targets for critique, it’s odd that Elliotte chose to bag on Array, which is by contrast well-documented. Finally, the vast majority of his issues with the Array class are due to misunderstandings of the methods (which can be blamed on the documentation) and of Ruby conventions and idioms (which can be blamed on him not being a Ruby programmer).

For example:

On Array#*:

“Returns a new array built by concatenating the int copies of self.” I’ve thought and I’ve thought, and I still can’t figure out when you might need this.

Removing this method would mean removing matrix multiplication (v. useful), which is the real point of Array#*. This is a nitpick for the purpose of nitpicking; it wouldn’t alter Array’s method list at all.

On Array#<=>:

A comparison between arrays. However, without me stating it here, can you understand how to tell whether two arrays are greater than, equal to, or less than each other? There’s more than one possibility here. This needs to be pulled out into a separate interface that allows for different comparison algorithms.

Um… it uses the <=> method from the object of each element, which means that the comparison algorithms it uses are object-specific. The “underspecification” here is that comparison operators are implemented at the class level where it belongs, not at the primitive level, like Java.

On Array#compact!:

But compacting an array and sometimes returning nil? Does anyone ever use this? There’s also a perfectly good method to compact an array and return it, without ever returning nil. That’s a lot more useful. I only care whether the list now contains any nil objects or not, not whether it once contained nil objects.

First, the exclamation point denotes this method as a “destructive” method, meaning it operates on the object in question rather than returning the results of its operation. Having a destructive version of #compact means we don’t have to constantly do silly things like blah = blah.compact all the time.

Second, in Ruby nil and false both evaluate to false in a boolean condition. So if you want to know if any elements are nil and then remove them, #compact! comes in handy:


results = do_something_complicated
if results.compact!
  puts 'One or more of the results were nil.'
else
  puts 'Everything was A-OK!'
end

On Array#to_a:

Is Ruby not object oriented? Is there some deep, dark reason we can’t just use an instance of the subclass as an instance of the superclass?

See Object#to_a, from which Array descends.

On Array#each_index:

Am I missing something, or is this just a for loop across the array indexes? Why not just use a for loop, or whatever Ruby’s equivalent is?

If I was a Java programmer, code blocks would confuse and frighten me too. Why not a loop? Because we have code blocks; it’s Ruby. More importantly, this functionality is provided by the Enumerable module, and can be very useful.

On Array#at:

As near as I can figure, this is exactly the same as using array brackets except it uses a method call. If there is a difference, it’s pretty subtle. DRY, anyone?

First, the square brackets is a method call. Second, #at is faster and is intended for use when you need to access one specific element quickly. Array#[] is quite a bit more flexible, but slightly slower. Third, this isn’t repetition because Array#[] uses the underlying code of Array#at when passed a single integer as a parameter. DRY applies to the number of times you write the code, not the number of times you call it.

On Array#pop, #push, #shift, and #unshift:

Someone pushed a stack into the list. Didn’t we learn from that mistake in Java? (OK. push is really just append, but still, pop? And if you have pop why do you need last? Does anyone here remember DRY?)

Pop isn’t the same thing as last, and he’d know this if he’d paid attention. Array#pop removes and returns the last element, whereas #last returns the last element. And which is repeating yourself more: adding two methods to Array to wrap all FILO stack functionality, or hauling off and adding a separate class? In which ways do an Array and a Stack differ? Well, those two methods. Not every data structure needs its own class, especially when it’s just variations on a theme. Need a Queue? You could add another class with its own API, or you could add two more methods: #shift and #unshift. FIFO and FILO, and you only added a total of four methods. Seems kinda straightforward to me.

Now, Elliotte’s a smart guy, but it looks like he went to the doc page, saw a big list of methods, and freaked out. And that’s a shame, since there are a lot of methods in Array which could use the boot, either into another module (or a requireable module, like they did [poorly] with Date and its friends), or into the special hell designated for poorly-thought-out methods.

My hit list for Array?

  1. #length: Stick with #size, since it’s the Ruby idiom.
  2. #assoc and #rassoc: Provide a simple transition to a Hash instead.
  3. #fetch: If anything, this should be named #at!.
  4. #zip: By martians, for martians. What the hell do people do with this?
  5. #abbrev: See #zip. Twice.

As you could have guessed, I’m a fan of Ruby’s rich method lists, because they reduce the amount of code that I have to write, and let me focus more on the actual problem at hand and less on working around the language. If I had a nickle for each time I’ve typed something like this:


for(var i=0;i<somethingBig.count-1;i++) {
  print(int_to_str(i) + ": " + somethingBig.items[i]);
};

I would have gladly paid that nickle to substitute it with this:


something_big.each_index do |i|
  puts "#{i} : #{something_big.items[i]}”
end

Not a huge thing, but it matters.

5 comments »

Get your eager load on

Holy crap, check this out:

Eager loading with cascaded associations

Now that would make my life a lot easier. Arbitrarily large joins, constructed via the power of Ruby? Yeah, I’ll take that. This, combined with Ezra’s ez_where plugin, just brought ActiveRecord way, way past the big leagues.

Rails 1.1 is gonna bring some serious ruckus.

Leave a comment »