Languages I Want to Learn

I’ve fallen off the wagon of late in learning “a language a year” (as The Pragmatic Programmer advises). I have a long list of languages to learn, but I thought I’d try and narrow it down to a top five. Here goes:

  • “Io”:http://www.iolanguage.com/ – the more I work in OO the more I am drawn to prototype-based OO; and all the Io code samples I’ve seen are beautiful.
  • “Smalltalk”:http://www.squeak.org/ – one of those languages I feel like I already know from many years of tangential exposure, but it would be nice to be able to build a real app in it.
  • “Scala”:http://www.scala-lang.org/ – learning Haskell left behind a lingering itch to play with powerful type systems that help rather than hinder, and Scala seems like a pragmatic environment in which to do so.
  • “Clojure”:http://clojure.org/ – the early buzz is growing on this one. Good documentation for a young language, and I like a lot of the design decisions.
  • “PROLOG”:http://en.wikipedia.org/wiki/Prolog – the only language in this list which would actually expose me to a programming paradigm I am not terribly familiar with.

You keep using that word “distributed”…

People keep telling me that GitHub is the “killer app” of git. Perhaps they meant “productivity killer”?

!http://virtuouscode.com/wp-content/uploads/2008/10/github-is-down.png!

I submit to you that if your distributed version control workflow has a single point of failure that can bring your work to a crashing halt, you haven’t grokked distributed version control.

I’ve been watching with some concern as more and more people have adopted git, not so much on technical merits, but on the simple fact that GitHub exists. Don’t get me wrong – GitHub is a terrific service which set a new bar in usability for managed source control hosting. But by focusing on GitHub, it seems like the focus has moved away from the distributed nature of git and right back to an SVN-style centralized model (albeit one with easier branching). Today’s wailing and gnashing of teeth reaction to GitHub downtime seems to confirm this trend.

Perhaps it has something to do with the fact that git makes hosting your own public repository “absurdly complicated”:http://weblog.masukomi.org/2008/03/11/sharing-a-public-git-repo-over-http-flow-chart compared to “other tools”:http://weblog.masukomi.org/2008/03/11/sharing-a-public-darcs-repo-over-http-flow-chart.

Whatever it is, I hope GitHub users take this opportunity to take a keener interest in the D in DVCS.

Corporate Leave Policies?

Quick question: if your company has a defined leave policy (i.e. you’re not a freelancer), what is it? How much paid time off/vacation do you get a year? And if you happen to know, how much paid paternity/maternity leave are you eligible for?

Thanks!

Class.new and .inherited()

In Ruby, the typical way to define a class is using the class keyword:

class Foo
  # ...
end

The class keyword, however, is effectively just syntax sugar for the Class constructor:

Foo = Class.new
  # ...
end

Using Class.new is occasionally preferable, e.g. when you want an anonymous class which isn’t assigned to a constant:

@myclass = Class.new
  # ...
end

I like to use this technique for certain metaprogramming tasks, and when testing/spec-ing modules:

describe MyModule
  before :each do
    @test_class = Class.new do
      include MyModule
    end
  end

  # ...

end

There are a few subtle semantic differences between the class keyword and Class.new. Because the Class constructor uses a block to define the contents of the class, it can reference the surrounding lexical scope:

>> method_name = "foo"
=> "foo"
>> class KeywordClass
>>   define_method(method_name) do
?>       puts "hello"
>>     end
>>   end
NameError: undefined local variable or method `method_name' for KeywordClass:Class
        from (irb):3
>> DynamicClass = Class.new do
?>     define_method(method_name) do
?>       puts "hello"
>>     end
>>   end
=> DynamicClass
>> DynamicClass.new.foo
hello
=> nil

I’d known about this difference for a long time. The other day I came across another difference between these two methods of class definition which was new to me, and can lead to potentially surprising behavior. It concerns the order of execution and the .inherited() callback.

When a parent class defines a class method called inherited:

class A
  def self.inherited(other)
    puts "in A.inherited"
  end
end

And then that class is subclassed:

class B < A
  puts "in class B body"
end

The order of execution is 1) run the A.inherited callback; then 2) execute the class definition body. You can see this if you run the above two blocks; the output will be:

in A.inherited
in class B body

If, however, we try to inherit from A dynamically, using the Class constructor:

C = Class.new(A) do
  puts "in class C body"
end

The output is reversed:

in class C body
in A.inherited

I’m not sure if either of these behaviors is right or wrong, per se; but it can catch you by surprise if you are expecting dynamic class definition to have the same order of operations as the keyword form. In particular, it can lead to some confusing side effects when using certain libraries that extend the behavior of Ruby’s classes. For instance, I discovered this difference while working on some code that used the class-inheritable attributes feature of ActiveSupport:

myclass = Class.new do
  class_inheritable_accessor :bar
  self.bar = 42
end
>> myclass.bar
=> nil
>> # hey!  where'd the value of bar go?! 

As it turns out, class_inheritable_accessor and its friends work by defining Object.inherited to initialize some variables that ActiveSupport uses for bookkeeping. In the dynamic form of the class definition, the class body would assign values to the inheritable attributes – and then Object.inherited would be called back, re-initializing the variables and wiping out my assigned values. The solution was to separate the class creation and definition into two steps:

myclass = Class.new
myclass.instance_eval do
  class_inheritable_accessor :bar
  self.bar = 42
end

So there you go, another, lesser-known semantic distinction between “static” and “dynamic” class definition in Ruby.

Switching to Disqus

I’ve been pretty unsatisfied with the default WordPress commenting system for a number of reasons. And I’ve received several complaints about the way OpenID was being handled in comments. I’ve switched the comments over to being managed by “Disqus”:http://disqus.com. Hopefully this will address the issues and be more convenient for all concerned.

Always something new

After 5-6+ years of working with Ruby, I am still periodically reminded of features I’d forgotten about. Today it was the fact that you can override the backtick operator:

>> def `(cmd)
>>   puts "Do you really want to #{cmd}?"
>>   end
=> nil
>> `rm -rf *`
Do you really want to rm -rf *?
=> nil

The Trifecta of FAIL; or, how to patch Rails 2.0 for Ruby 1.8.7

It’s an oft-stated fact that most disasters result not from a single point of failure but from a combination of failures reinforcing each other. I wouldn’t term the problem I ran into last Friday a disaster, but it certainly cost me several hours of time trying to find a workaround.

Culprit #1: Rails

Rails’ ActiveSupport added a handy little method called #chars to the String class. In and of itself this doesn’t seem like such a bad thing, and a lot of other handy methods in ActiveSupport are built on top of #chars. However, as we’ll see, taking advantage of Ruby’s open classes to extend core types has a way of drawing the unwanted attention from the Law of Unintended Consequences.

Culprit #2: Ruby

It’s not set in stone anywhere, but there’s a fairly well accepted convention in open source projects that versions are divided into a major version, a minor version, and a tiny or patch version. New major versions indicate API-breaking changes. A new minor version may introduce new features, but existing code should continue to work as-is. And a new tiny version indicates that the API remains fixed; the only difference is that bugs have been fixed and security holes patched.

Ruby 1.8.7 is a minor release masquerading as a tiny release. Among the features backported into 1.8.7 from Ruby 1.9 is a new #chars attribute. Unfortunately, it is incompatible with the Rails 2.0 implementation of #chars. This, incidentally, is a prime example of one of the subtler ways that patching the core classes can bite you. Even if you are adding new methods rather than re-writing existing ones, the chances are good that someone else will have the same idea only with a slightly different implementation and semantics. Bang, incompatibility.

Culprit #3: MacPorts

We have an app which has not yet been ported to Rails 2.1. This, in itself, would not have been a problem; we can keep running it under Ruby 1.8.6 with Rails 2.0, no problem. However, I have a nasty habit of trying to keep my software up to date. So I run sudo port upgrade outdated periodically, and watch all the errors from unmaintained ports go scrolling across my terminal for 24 hours or so.

The last time I did this, one of the ports that did manage to build was Ruby. Version 1.8.7. The next time I ran our app, it of course promptly crashed.

This is the point at which I discovered something I hadn’t realized about MacPorts: it has no downgrade path. Coming from the world of Debian, Ubuntu, and apt-get, I just expected any package management system to handle the case where the user specifies an older version to be installed.

In fact, there’s a way to do it in MacPorts, but it’s painful.

Fail.

fail owned pwned pictures
So there I was with a broken app, no time in the iteration to upgrade it to Rails 2.1, and no easy way to get back to Ruby 1.8.6. Lame.

Rescue

After bitching and moaning on Twitter for awhile, I decided Bob helps those who help themselves, so I took a look at the crash backtrace I was getting. I traced it back to a line in vendor/rails/activesupport/lib/activesupport/core_ext/string/access.rb:

        def first(limit = 1)
          chars[0..(limit - 1)].to_s
        end

In the Rails 2.0 version of String#chars, #chars returns an Array or Array-like object which can be subscripted with #[]. The Ruby 1.8.7 version, by contrast, returns an Enumerable::Enumerator.

“That’s easy enough” thought I, and, fully expecting that patching this one issue would just reveal another incompatibility, and another, and another…, I changed the code to:

        def first(limit = 1)
          chars.to_a[0..(limit - 1)].to_s
        end

Lo and behold, the app worked perfectly.

Of course, YMMV. But as a quick kludge this one was surprisingly painless.

Lessons Learned

Here’s what I took away from this experience:

  1. Be wary of adding methods to core classes. What could possibly go wrong? More than you think.
  2. Patch releases should be true patch releases. It’s tempting to include a neat new feature as a bonus –
    again, what could possibly go wrong? Resist this urge.
  3. Macs are shiny, but for industrial-strength development support, nothing beats a Debian-based system with APT.
  4. Every now and then taking a clawhammer to vendor code is the shortest (short-term) way from point A to point B. Personally I prefer to either keep this kind of change local or, if necessary, version it with something like Piston, rather than maintaining it as a monkey-patch.
[ad#PostInline]