Thursday, March 19, 2009

Bastardized recursion

I seem to be posting less. I've been thinking about why that is. Perhaps, less things are surprising to me now (i.e. I'm not learning as much as before). When doing this Rails stuff, the bulk is standard fare, and only occasionally do you run into something mildly interesting. I have been queuing up posts, however. Between work, small side projects, reading, and hanging, there's less time than before.

I stumbled on something, which I saw in the Rails source once. Thought I'd share.

Say I have a :blog that has_many :posts. But Posts are subclassed to have many different types. But I wanted that post_type information from Blog in different formats. Originally, it looked something like this

class Blog
has_many :posts

def post_types
Post.subclasses
end

def post_names
post_types.map { |pt| pt.name.gsub('Post::','') }
end

def post_string
post_names.map { |n| "'" + n + "'" }.join(",")
end
end

Since they progressively built off of each other, I figured I can use a bastardized recursion, like I saw in find() in ActiveRecord::Base.

class Blog
has_many :posts

def post_types(format = :classes)
case format
when :classes
Post.subclasses
when :names
post_types(:classes).map { |pt| pt.name.gsub('Post::','') }
when :string
post_types(:names).map { |n| "'" + n + "'" }.join(",")
end
end
end


Seems alright. Reduces the clutter of functions that are related to each other, so I'm on the lookout for being able to reduce related functions together like that. tip~!

Updated:
Found this reverse engineering brief on obfuscated code that recites the 12 days of Christmas. It uses the same technique that I described above. I suppose as always, case statements can be abused.