# TITLE: # # K-Combinators, Tap and Returning # # SUMMARY: # # Veriations on K-Combinator, namely #tap and # #returning, and returning's alias #with. # # AUTHORS: # # - Mikael Brockman # -Thomas Sawyer # module Kernel # Yield self -and- return self. def tap(&b) if block_given? b.arity == 1 ? yield(self) : instance_eval(&b) end self end # require 'facets/functor' # # # Yield self -and- return self. # # def tap(&b) # if block_given? # b.arity == 1 ? yield(self) : instance_eval(&b) # self # else # Functor.new{ |op, *args| self.send(op, *args); self } # end # end # A Ruby-ized realization of the K combinator. # # returning Book.new do |book| # book.title = "Imperium" # book.author = "Ulick Varange" # end # # Also aliased as #with. # # def foo # with values = [] do # values << 'bar' # values << 'baz' # end # end # # foo # => ['bar', 'baz'] # # Technically, #returning probably should force the return of # the stated object irregardless of any return statements that # might appear within it's block. This might differentiate # #returning from #with, however it also would require # implementation in Ruby itself. def returning(obj=self) yield obj obj end alias :with :returning # Repeat loop until it yeilds false or nil. def complete loop { break unless yield } end end # _____ _ # |_ _|__ ___| |_ # | |/ _ \/ __| __| # | | __/\__ \ |_ # |_|\___||___/\__| # =begin test require 'test/unit' class TCKernel < Test::Unit::TestCase def test_returning foo = returning( values = [] ) do values << 'bar' values << 'baz' end assert_equal( ['bar', 'baz'], foo ) end def test_tap x = "foo" r = ("foobar".tap{ gsub! /bar/, '' }) assert_equal(x, r) end def test_tap_array x = [1,2,3] x.tap{ |a| assert_equal(x, a) } end end =end