Skip to content

Instantly share code, notes, and snippets.

@corbanbrook
Created October 27, 2009 21:00
Show Gist options
  • Save corbanbrook/219956 to your computer and use it in GitHub Desktop.
Save corbanbrook/219956 to your computer and use it in GitHub Desktop.
1 dimensional list comprehension
# 1 dimensional list comprehension
module Kernel
def list &block
Comprehension::List.new &block
end
end
module Comprehension
class List
def initialize &block
@result = []
@expression = block if block_given?
@variables = Object.new
# creates a basic struct pattern
def @variables.add_to_scope sym
metaclass = class << self; self; end
metaclass.send :attr_accessor, sym
end
def @variables.set sym, value
self.send "#{sym}=".to_sym, value
end
end
def ranges ranges, &condition
ranges.each_pair do |sym, range|
@variables.add_to_scope sym
range.each do |i|
@variables.set sym, i
if block_given?
if @variables.instance_eval &condition
@result << @variables.instance_eval(&@expression)
end
else
@result << @variables.instance_eval(&@expression)
end
end
end
@result
end
end
end
list{ x * 16 }.ranges(:x => 0..16) { x % 4 == 0 }
#=> [0, 64, 128, 192, 256]
word = "spam"
list{ [word[0,i], word[i, word.length]] }.ranges(:i => 0..word.length)
#=> [["", "spam"], ["s", "pam"], ["sp", "am"], ["spa", "m"], ["spam", ""]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment