wrote:
> 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
I like this solution the best. Unlike the solutions involving
exceptions or multiple return values, it still allows valid? to be used
as an ordinary boolean function when you don't care about the reason why
something's not valid, yet doesn't have the race conditions involved in
the side-effect solutions.
That said, I think part of the reason there's no agreed upon idiom for
this is because it would have been more idiomatic in Ruby to not even
have the valid? method. Instead an exception would have been thrown as
soon as the object became invalid, and the exception would have
contained the reason. Having your class have a valid? method seems like
how you'd design things in a language which doesn't have exceptions.
Adam