title: What's the variable scope within `class_eval` string?
body: <p>I am using <code>class_eval</code> to write code to be executed under the context of current class. In the following code, I want to add a counter for changes of attribute values. </p>
  
  <pre><code>class Class
    def attr_count(attr_name)
      attr_name = attr_name.to_s
      attr_reader attr_name # create the attribute's getter
      class_eval %Q{
        @count = 0
        def #{attr_name}= (attr_name)
          @attr_name = attr_name
          @count += 1
        end
  
        def #{attr_name}
          @attr_name
        end
      }
      end
    end
  class Foo
    attr_count :bar
  end
  
  f = Foo.new
  f.bar = 1
  </code></pre>
  
  <p>My understanding of <code>class_eval</code> is that it evaluates the block <strong>in the context of the runtime class</strong> - in my case, under <code>class Foo</code>. I expect the above code <strong>runs similar as</strong>:</p>
  
  <pre><code>class Foo
    attr_count :bar
    @count = 0
    def bar= (attr_name)
      @attr_name = attr_name
      @count += 1
    end
  
    def bar
      @attr_name
    end
  end
  </code></pre>
  
  <p>However the above code resulted in error saying, the error is caused by <code>@count += 1</code>. I cannot figure out why <code>@count</code> has <code>nil:NilClass</code> as its super?</p>
  
  <pre><code>(eval):5:in `bar=': undefined method `+' for nil:NilClass (NoMethodError)
  </code></pre>
  
  <p>On the other hand, @selman has given a solution to put <code>@count</code> assignment within the instance method and it works. </p>
  
  <pre><code>class Class
    def attr_count(attr_name)
      #...
      class_eval %Q{
        def #{attr_name}= (attr_name)
          @attr_name = attr_name
          if @count
            @count += 1
          else
            @count = 1
          end
        end
        #...
      }
    end
  end
  </code></pre>
  
  <p>Why changes the variable scope works? How does <code>class_eval</code> execute its following string?</p>