#:title: NackClass #-- # NackClass # v 1.0 # # Copyright (c) 2005 Thomas Sawyer # # Ruby License # # This module is free software. You may use, modify, and/or redistribute this # software under the same terms as Ruby. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. # # # $Id: nack.rb,v 1.0 2005/04/28 03:10:10 transami Exp $ # # ========================================================================== # Revision History :: # YYYY.MM.DD Ver. Dev. Description # -------------------------------------------------------------------------- # 2005.04.28 1.0 Trans * Minor modifications to documentation. # ========================================================================== # To Do :: # * I beleive this class has even more potential yet. # It would be interesting to see if a catch/try correction # facility could be built into it too. # ========================================================================== #++ # = Description # # The NackClass is is like the NilClass except one step down. # Nack is never used to to mean nothingness or emptiness. # The Nack class is only used to report something is "a miss" w/o # the system raising an Exception. It's a mechanism for # lazy error evaluation. # # == Usage # # def scalar( x ) # if x.kind_of?(Enumerable) # return nack(ArgumentError, "Value must not be enumerable") # end # x # end # # a = scaler( 1 ) #=> 1 # b = scaler( [1,2] ) #=> nack # b.first #=> ArgumentError (previous) # # a = nail scaler( 1 ) #=> 1 # b = nail scaler( [1,2] ) #=> ArgumentError # # == Author(s) # # * Thomas Sawyer # class InvalidNackError < ArgumentError end class NackClass attr_reader :error, :data def initialize(error=nil, *data, &ctrl) if Class === error and error <= Exception @error = error.new(*data) elsif error.kind_of?( Exception ) @error = error elsif error.kind_of?( String ) @error = StandardError.new(error) elsif error == nil @error = StandardError.new else raise InvalidNackError end @data = data @ctrl = ctrl end def call(*args) @ctrl.call(*args) end def call_with_data @ctrl.call(*@data) end def raise_error raise @error end def to_s; "n/a"; end def ==(x) x.is_a?(NackClass) end def method_missing(meth, *args) raise_error end end module Kernel def nack(err=nil, *data, &ctrl) NackClass.new(err, *data, &ctrl) end end # private Object method def nail( arg ) if NackClass === arg arg.raise_error else return arg end end #class NilClass # def method_missing(meth, *args) # nack() # end #end