Sunday, November 25, 2007

Ruby Shorthand

Justin.tv's web code is written in Ruby. I've found myself using the same collection idioms over and over, so I've abstracted several of them into a file called shorthand.rb.



Most of our web code consists of manipulating collections in one form or another, which is probably why all the shorthand methods are for that. I'm particular proud of my % operator, which I believe is a specialized mapcar in spirit. Without further ado, code!




module Enumerable
def %(field)
map {|o| o.send(field)}
end
end

class Hash
def keys_sorted_by_value(options = Hash.new, &block)
limit = options[:limit] || size
offset = options[:offset] || 0

sorted = map.sort_by do |key, value|
if block
yield(key, value)
else
value
end
end

sorted.reverse! if options[:reverse]

sorted.map {|key, value| key}.slice(offset, limit) || Array.new
end

def hmap
h = dup
keys.each do |k|
h[k] = yield h[k]
end
h
end

def to_params
map {|k, v| "#{k}=#{CGI::escape v.to_s}"}.join("&")
end
end


class Array
def hash_by(field)
h = Hash.new
each {|o| h[o.send(field)] = o}
h
end

def center_first
centered = Array.new
last_pushed = false
each do |x|
centered.push(x) unless last_pushed
centered.unshift(x) if last_pushed
last_pushed = !last_pushed
end
centered
end

def random_subset(n=size)
shuffle.slice(0, n)
end

def shuffle
sort_by { rand }
end

def divide
evens = Array.new
odds = Array.new
each_with_index do |x, i|
if i % 2 == 0
evens << x
else
odds << x
end
end
[evens, odds]
end

def remove!(item)
reject! {|x| x == item}
end

def remove(item)
reject {|x| x == item}
end
end


Other coders: If you have your own idioms like these, I'd love to see them! Post them!

No comments: