Skip to content

Instantly share code, notes, and snippets.

@yoshikischmitz
Last active August 29, 2015 14:01
Show Gist options
  • Save yoshikischmitz/221f4cab02ba38a35c07 to your computer and use it in GitHub Desktop.
Save yoshikischmitz/221f4cab02ba38a35c07 to your computer and use it in GitHub Desktop.
# This extends the Array class with a special method called each_[insert integer here]
# For example, each_1 invokes the block for every single element in an array, each_2 invokes the block for
# each pair, each_3 for triples, so on and so forth. This is a purely educational example of using
# metaprogramming to replicate functionality using patterns rather hard coding a new method for each
# new case you need to account for.
class Array
def method_missing(meth, *args, &block)
if meth.to_s =~ /^each_(\d+)$/
run_each_by_num($1.to_i, &block)
else
super
end
end
# Iterates through self in increments of num, yielding the current
# range as an array
def run_each_by_num(num, &block)
self.inject(0) do |curr|
break if curr >= self.length
yield self[curr..(curr - 1 + num)]
curr += num
end
end
end
a = Array.new([2,3,4,5,8,0,1,3,4,5])
# Outputs: [2] [3] [4] [5] [8] [0] [1] [3] [4] [5]
# Note: the preceding and following examples ignore newlines.
a.each_1 do |x|
puts "#{x}"
end
# Outputs: [2, 3, 4, 5] [8, 0, 1, 3] [4, 5]
a.each_4 {|x| puts "#{x}"}
# Outputs: [2, 3, 4, 5, 8] [0, 1, 3, 4, 5]
a.each_5 do |x|
puts "#{x}"
end
# Outputs: [2, 3, 4, 5, 8, 0, 1, 3, 4] [5]
a.each_9 do |x|
puts "#{x}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment