On 3/31/2011 06:44, Gunther Diemant wrote:
> Consider something like this
> 
> class Foo
>   def set_bar(value)
>     @bar = value
>   end
> 
>   def some_method
>     @bar ? "@bar is not nil or false" : "@bar is not set"
>   end
> end
> 
> If ruby raises an error when you call some_method before set_bar, you are
> forced to write a initialize method with @bar = nil in it.

It's good advice to always initialize all of your instance variables
before attempting to use them.  You don't have to initialize them in
your constructor, but failing to initialize them at all will generate
warnings upon reference when ruby is run with the -w option:

$ export RUBYOPT=-w

$ irb
irb(main):001:0> class Foo
  end
end
irb(main):002:1>   def set_bar(value)
irb(main):003:2>     @bar = value
irb(main):004:2>   end
irb(main):005:1>
irb(main):006:1*   def some_method
irb(main):007:2>     @bar ? "@bar is not nil or false" : "@bar is not set"
irb(main):008:2>   end
irb(main):009:1> end
=> nil
irb(main):010:0> Foo.new.some_method
(irb):7: warning: instance variable @bar not initialized
=> "@bar is not set"


Modules make things a bit tricky if you want them to use their own
instance variables.  In these cases, you should probably use the
defined? operator to ensure that if the instance variable is undefined
that you initialize it then:

module Foo
  def set_bar(value)
    @bar = value
  end

  def some_method
    "@bar = '#{__bar}'"
  end

  private

  # Always use the to reference @bar's value so that it is sure
  # to be initialized.
  def __bar
    @bar = "some value" unless defined?(@bar)
    @bar
  end
end

class A
  include Foo
end

a = A.new
puts a.some_method

a = A.new
a.set_bar("foobar")
puts a.some_method


Running the above with ruby -w should not print any warnings.

-Jeremy