From: "Jörg Mittag" Date: 2009-01-08T08:49:50+09:00 Subject: [ruby-core:21208] Re: Definable != is a Bad Thing??? Kornelius Kalnbach wrote: > Daniel Luz wrote: >> What I personally don't like about this is that it gives you a false >> sense of control. We still can't handle && and || > the problem is short-circuit evaluation, I guess. this one should not > run the command: > > false && `rm -rf .` > > it has to be part of the AST, and can't be changed at runtime. AFAIK, > you can't translate "a && b" into a method call in Ruby. they are more > like "and" and "or". the ternary operator (cond ? truecase : falsecase) > is another example - which is a shortcut for if-then-else. and you don't > want to redefine that ^^ I was bored, so I went ahead and implemented it: . There is actually absolutely nothing original or hard about this: I took the API straight from Smalltalk, the implementation dates all the way back to Lisp and the specs were pretty much cut&pasted from the RubySpec project. On the subject of RubySpec: all specs still pass, with the exception of the ones that deal with operator precedence, of course. This is pretty much the gist of the implementation: class FalseClass def if; end def ifelse _ = nil, else_branch = ->() {} else_branch.call end def and; self end def or; yield end def not; true end end class TrueClass def if yield if block_given? end def ifelse then_branch = ->() {}, _ = nil then_branch.call end def and; yield end def or; self end def not; false end end Straight from the README: B001e - A message-sending based re-implementation of Boolean operators in pure Ruby. Abstract -------- B001e is a message-sending based re-implementation of the Boolean operators 'and', 'or' and 'not' and the Boolean expressions 'if' and 'unless' in pure Ruby. Lazy Evaluation / Short-circuiting is achieved through the use of blocks and lambda expressions. What ==== This library contains sample re-implementations of the Boolean operators 'and', 'or' and 'not' and the Boolean expressions 'if' and 'unless', in pure Ruby. The style is heavily inspired by Smalltalk and its relatives: the operators become messages that take block parameters and are sent to the conditionals. Operator / keyword style: if c1 && c2 t elsif c3 ei else e end becomes: c1.and { c2 }.ifelse ->() { t }, ->() { c3.ifelse ->() { ei }, ->() { e } } How === All the operators become methods. The logic is achieved through polymorphism: basically, 'NilClass' and 'FalseClass' get one set of implementations, 'Object' gets the opposite set. Lazy Evaluation is achieved with blocks: if a block is not supposed to be evaluated, it is simply never 'yield'ed to. Where ===== At GitHub , of course! Installation ============ gem install JoergWMittag-b001e Usage ===== begin require 'rubygems'; rescue LoadError else begin gem 'JoergWMittag-b001e', '~> 0.0.1'; rescue Gem::LoadError; end end require 'b001e' true.and { nil.or { 42 } }.if { puts "It's true!" } # Equivalent to: if true && (nil || 42) then puts "It's true!" end false.ifelse ->() { puts "You'll never see this." }, ->() { puts 'But this!' } # Equivalent to: if false then puts "You'll never see this." else puts 'But this!' end Acknowledgements ================ Style ----- The API style is heavily influenced by Smalltalk. Implementation -------------- The implementation is literally textbook: every introductory CS text should have it. Specs ----- The Specs were directly lifted from the RubySpec project. License ======= My original work is licensed under the MIT X11 License. The RubySpec license is also MIT X11. Greetings, jwm.