Created
January 29, 2012 01:48
-
-
Save sdeming/1696658 to your computer and use it in GitHub Desktop.
predicate method chaining
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
module PredicateMethods | |
module Firewalls | |
class Allow | |
def initialize(what) | |
@wrappee = what | |
end | |
def method_missing(name, *args, &blk) | |
begin | |
@wrappee.send(name, *args, &blk) | |
rescue NoMethodError | |
eval "#{name} *args, &blk" | |
end | |
end | |
end | |
class Deny | |
def method_missing name, *args, &blk | |
self | |
end | |
end | |
end | |
def define_predicate name, predicate | |
name = name.to_s.sub(/\?$/, '') | |
p, m = :"#{name}?", :"#{name}" | |
send(:define_method, p) do |*args, &blk| | |
predicate.call(*args) | |
end | |
send(:define_method, m) do |*args, &blk| | |
if send(p, *args) | |
if blk | |
blk.call | |
else | |
@_predwrapper ||= Firewalls::Allow.new(self) | |
end | |
else | |
Firewalls::Deny.new | |
end | |
end | |
end | |
end | |
class T | |
extend PredicateMethods | |
define_predicate :yep, lambda { true } | |
define_predicate :nope, lambda { false } | |
define_predicate :maybe, lambda { |eh| eh } | |
end | |
x = T.new | |
x.yep.puts "x:Yep" | |
x.yep.yep.yep.yep { puts "x:Yeeeeep" } | |
x.nope.nope.nope.nope { puts "x:Nooooope" } | |
x.nope.puts "x:Nope" | |
x.yep.nope.puts "x:Nuh uh" | |
x.puts "x:I should raise NoMethodError" rescue nil | |
y = T.new | |
y.nope.puts "y:Nope" | |
y.puts "y:I should raise NoMethodError" rescue nil | |
y.maybe(true).puts "y:Maybe" | |
y.yep.maybe(true).yep.puts "y:Yep-Maybe-Yep" | |
y.maybe(false).puts "y:Maybe not" | |
Scott, don't end your sentences in prepositions. It clearly breaks reading comprehensibility then. Oops.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated to accomplish my goals. Rainman is for far more complex mechanisms. This is really just about replacing code like:
with:
I have a few things that are pretty deeply nested that was using lambda's for. This cleans it up quite a bit.