From: "Aleksi Niemelä" Date: 2000-11-09T04:23:27+09:00 Subject: [ruby-talk:6175] Lazy operators > Finally, I'd like to mention something that I have sometimes wished > for - referring to previously mentioned variables or cached results. > This is probably the ultimate in lazy programming, I don't know, > but how many times have you wished you could stop repeating > yourself in the following cases? > > if a == "up" || a== "down" || a == "around" then ..... > > Why not: if a == "up" ^or^ "down" ^or^ "around" ....... > > if month > 2 && month < 7 || month == 11 then ..... > > Why not: if month > 2 ^and^ < 7 ^or^ == 11 then ..... Oh, this must be your lucky day. I just noticed my version of Ruby (which has started to show some signs of hackery) include Lazy operators. :) That means you can write the above code as if _(month, _ > 2, And < 7, Or == 11 ) Here you have too. - Aleksi module Kernel class LazyComparator attr_accessor :op, :cmp, :value def initialize(op, cmp, value) @op, @cmp, @value = op, cmp, value end def evaluate(truth, var) truth2 = var.method(@cmp).call(@value) case @op when "and" return( truth and truth2) when "or" return(truth or truth2) end end end class LazyOperator def initialize(op) @op = op end def < other LazyComparator.new(@op, "<", other) end def > other LazyComparator.new(@op, '>', other) end def == other LazyComparator.new(@op, '==', other) end end def _(*ops) return And if ops.size == 0 var = ops.shift truth = true ops.each { |op| truth = op.evaluate(truth, var) } truth end _ = LazyOperator.new("and") And = LazyOperator.new("and") Or = LazyOperator.new("or") end for month in 1...12 printf("%2d", month) if _(month, _ > 2, And < 7, Or == 11 ) puts " true" else puts " false" end end puts for a in ["around", "inside out"] if _(a, _ =="up", Or == "down", Or == "around") puts a else puts "no " + a end end # Let me add that the last is easier to write for a in ["around", "inside out"] if %w(up down around).include? a puts a else puts "no " + a end end Outputting: 1 false 2 false 3 true 4 true 5 true 6 true 7 false 8 false 9 false 10 false 11 true around no inside out around no inside out