Brian Buckley wrote:
>> 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.
>>
>
> I'm not sure I'd agree that it is hackish to set @instance_variables
> (or perhaps to use a setter instead) to capture learned info.  A
> naming convention might help (maybe remove the "?' and add "_reason")
>
> class Foo
>   attr_accessor :valid_reason
>   def valid?
>   ...
>   self.valid_reason = "age is too young"
>   false
>   end
> end

IMHO it's bad practice to store this info in the instance.  It really
doesn't belong there; you run into all sorts of problems (race conditions
in concurrent apps, consistence - you need to clear this when the instance
state changes...).

The best solution seems to be to use an exception.

class Foo
  attr_accessor :name

  def ensure_valid
    self.name or raise "Empty name."
  end
end

begin
  f=Foo.new
  f.ensure_valid
  f.do_stuff()
rescue RuntimeError => e
  $stderr.puts "Invalid because of: #{e.message}"
end

Kind regards

    robert