Skip to content

Instantly share code, notes, and snippets.

@pvande
Created April 2, 2009 00:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pvande/88966 to your computer and use it in GitHub Desktop.
Save pvande/88966 to your computer and use it in GitHub Desktop.
Blocks are nice, but there are uses -- especially in Enumerable -- for
which the most common case seems unnecessarily verbose. What follows
is a proposed alternative convention, and a lightweight implementation
of a small part of that convention.
I'm interested in hearing feedback related to the convention and any
associated / hidden dangers involved.
numbers = [ -2, -1, 0, 1, 2 ]
words = %w(GitHub is Logical Awesome)
# Summary: Everything must be passed via blocks.
numbers.map
# => [ -2, -1, 0, 1, 2 ]
numbers.map { |e| e.abs }
# => [ 2, 1, 0, 1, 2 ]
numbers.map { |e| e + 2 }
# => [ 0, 1, 2, 3, 4 ]
numbers.select { |e| e >= 0 && e < 2 }
# => [ 0, 1 ]
numbers.reject { |e| e.zero? }.length
# => 4
numbers.all? { |e| e > 0 }
# => false
words.map { |e| e.reverse }
# => [ 'buHtiG', 'si', 'lacigoL', 'emosewA' ]
words.any? { |e| e.empty? }
# => false
numbers = [ -2, -1, 0, 1, 2 ]
words = %w(GitHub is Logical Awesome)
# Summary: Methods of arity zero can be simplified by using
# Symbol#to_proc. Blocks for everything else.
numbers.map
# => [ -2, -1, 0, 1, 2 ]
numbers.map(&:abs)
# => [ 2, 1, 0, 1, 2 ]
numbers.map { |e| e + 2 }
# => [ 0, 1, 2, 3, 4 ]
numbers.select { |e| e >= 0 && e < 2 }
# => [ 0, 1 ]
numbers.reject(&:zero?).length
# => 4
numbers.all? { |e| e > 0 }
# => false
words.map(&:reverse)
# => [ 'buHtiG', 'si', 'lacigoL', 'emosewA' ]
words.any?(&:empty?)
# => false
numbers = [ -2, -1, 0, 1, 2 ]
words = %w(GitHub is Logical Awesome)
# Summary: Simple expressions can be simplified by calling
# methods on a proxy object. Complex expressions can still
# be written with a block.
numbers.map
# => <Proxy Object>
numbers.map.abs
# => [ 2, 1, 0, 1, 2 ]
numbers.map + 2
# => [ 0, 1, 2, 3, 4 ]
numbers.select { |e| e >= 0 && e < 2 }
# => [ 0, 1 ]
# Also, (numbers.select >= 0).select < 2
numbers.reject.zero?.length
# => 4
numbers.all? > 0
# => false
words.map.reverse
# => [ 'buHtiG', 'si', 'lacigoL', 'emosewA' ]
words.any?.empty?
# => false
class Proxy
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
def initialize(method, obj)
@method, @obj = method, obj
end
def method_missing(*args, &blk)
@obj.send(@method) { |e| e.send(*args, &blk) }
end
def inspect
"#{@obj.inspect}.#{@method} { |e| e.??? }"
end
end
class Array
alias :verbose_map :map
def map(*args, &b)
if block_given?
self.verbose_map(*args, &b)
else
Proxy.new(:map, self)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment