On Mon, 13 Feb 2006 eastcoastcoder / gmail.com wrote: > Very often I have a question method, which, in some cases, the caller > would want to know why as well. > > Examples: > > def valid? > end > > def abort? > end > > Ruby does not allow subclassing true and false, so, if these methods > return one of those, they can't return any additional info. But > sometimes the caller needs additional info, as in: > > if !valid? logger.warn "Not valid: #{why not?}" > > What is the best way to handle this? I could have those methods set > @instance_variables, but this seems a little hackish, and could > introduce race conditions. > > Is there anyway to return false, "reason", or something of that sort? > What is the preferred, idiomatic way of doing this? use a block to return info: harp:~ > cat a.rb class C def initialize(x) @x = x end def valid?() if @x == 42 true else yield "x is not 42" rescue nil false end end end c = C::new 43 unless c.valid?{|reason| warn "not valid : #{ reason }" } # do something end c = C::new 42 c.valid?{|reason| warn "not valid : #{ reason }" } harp:~ > ruby a.rb not valid : x is not 42 or invert your logic so info can be added: harp:~ > cat a.rb class C def initialize(x) @x = x end def invalid?() @x == 42 ? false : "x is not 42" end end c = C::new 43 if((reason = c.invalid?)) puts reason end c = C::new 42 if((reason = c.invalid?)) puts reason end harp:~ > ruby a.rb x is not 42 hth. -a -- happiness is not something ready-made. it comes from your own actions. - h.h. the 14th dali lama