Python Slices vs Ruby blocks


A couple of my Python colleagues tried to impress me today with Python's named slices feature. The way it works is like that:

 s = list('helloworld!')
  => ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd', '!']
WORLD = slice(5, 10)
s[WORLD]
 => ['w', 'o', 'r', 'l', 'd']

So you can have your own customised slicing mechanism that you can apply to any list. Which is kind of cool. That prompted me to demonstrate how we can do the same thing with Ruby. Luckily, in Ruby world we have blocks, procs and lambdas, the ultimate play-dough that allows us to stretch and flex in every direction.

​s = ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd', '!']
  => ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd', '!']
world = proc {|x | x.slice(5, 10)}
world[s]
 => ["w", "o", "r", "l", "d", "!"]

​so we can do things like:

first = proc { |x| x.slice(0) }
first[s]
=> "h"

or even things that we can't do with Python's named slicing, since it doesn't allow us to pass the receiver as an argument to the block (x in the example below)

last = proc {|x| x.slice x.length-1, x.length}
last[%w(dog rabbit fox cat)]
=> ["cat"]

or

median = proc {|x| x.slice(x.length / 2) }
median[%w(dog rabbit cat)]
=> "rabbit"

and of course we're not just restricted to slicing arrays,

domain_extractor = proc { |x| x.gsub(/.+@([^.]+).+/, '\1') }
domain_extractor["fred@mydomain.co.uk"]
=> "mydomain"

and since a block is just an anonymous Proc object, we can use it with any method that accepts Proc parameters ​

email_list = ["fred@mydomain.com", "john@gmail.com", "mary@yahoo.co.uk"]
=> ["fred@mydomain.com", "john@gmail.com", "mary@yahoo.co.uk"]
email_list.map(&domain_extractor)
=> ["mydomain", "gmail", "yahoo"]

Blocks and Procs (a.k.a lambdas) are ideal for some quick, reusable functionality or for when defining a full-blown method would be too much, but also for more serious uses such as callbacks and deferred execution. IMHO, they are a fundamental part of what makes Ruby such a flexible and powerful language. Learn them, use them, enjoy them :)