Here's something I cooked up this evening. Nothing too epic, but it's a neat illustration of metaprogramming with ruby.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
class Symbol | |
def pipe(method) | |
proc { |array| array.send(method) { |elem| elem.send(self) } } | |
end | |
def detect | |
pipe(:detect) | |
end | |
def select | |
pipe(:select) | |
end | |
alias :filter :select | |
def reject | |
pipe(:reject) | |
end | |
end | |
class Array | |
alias :old_pipe :| | |
def |(other) | |
case other | |
when Symbol | |
self.map { |elem| elem.send(other) } | |
when Proc | |
other.call(self) | |
else | |
old_pipe(other) | |
end | |
end | |
end | |
a = [' foo ', ' bar ', ' ', ' baz '] | |
puts a.inspect # => [" foo ", " bar ", " ", " baz "] | |
puts (a | :strip).inspect # => ["foo", "bar", "", "baz"] | |
puts (a | :strip | :upcase).inspect # => ["FOO", "BAR", "", "BAZ"] | |
puts (a | :strip | :upcase | :empty?.reject).inspect # => ["FOO", "BAR", "BAZ"] | |
puts (a | :strip | :upcase | :empty?.select).inspect # => [""] |
Ruby allows you to reopen classes and add methods to them. You can also
make a Module
and include
that in a class to add methods. I've added
four methods to the Symbol
class and overridden one method in the
Array
class (using alias
to keep the old method around since super
doesn't quite work).
Now we can pipe arrays like bash using a simple syntax! Wee!