[snip]

> I'm thinking that one possible way to shorten my calls would be to use
> instance-eval in #select, #map and #sort_by so i could do it like
> this:
> sales.select{value > 50000}.map{buyer}.sort_by{age}

Here's a trivial implementation of that idea:

module Relational
  def project(&block)
    map { |x| x.instance_eval(&block) }
  end

  def where(&block)
    select { |x| x.instance_eval(&block) }
  end

  def order_by(&block)
    sort_by { |x| x.instance_eval(&block) }
  end
end

class Buyer < Struct.new(:name, :age)
end

class Sale < Struct.new(:value, :buyer)
end

alice = Buyer["Alice", 30]
bob = Buyer["Bob", 40]
charlie = Buyer["Charlie", 50]

sales = [
         Sale[80000, alice],
         Sale[40000, bob],
         Sale[60000, charlie],
        ]

class Array
  include Relational
end

p sales.where{ value > 50000 }.project{ buyer }.order_by{ age }
# => [#<struct Buyer name="Alice", age=30>, #<struct Buyer
name="Charlie", age=50>]

# But it becomes uglier when you want to do this:
p sales.where{ value > 50000 }.project{ [value, buyer] }.order_by{ self[1].age }
# => [[60000, #<struct Buyer name="Alice", age=30>], [80000, #<struct
Buyer name="Charlie", age=50>]]

# Better to do it this way round:
p sales.where{ value > 50000 }.order_by{ buyer.age }.project{ [value, buyer] }
# => [[60000, #<struct Buyer name="Alice", age=30>], [80000, #<struct
Buyer name="Charlie", age=50>]]

However, in practice, I don't use it. Ruby's block syntax is perfectly
elegant as it is. Why not be content with it?

Regards,
Sean