`class_eval`字符串中的变量范围是什么? [英] What's the variable scope within `class_eval` string?

查看:88
本文介绍了`class_eval`字符串中的变量范围是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用class_eval编写要在当前类的上下文中执行的代码.在下面的代码中,我想添加一个计数器来更改属性值.

I am using class_eval 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.

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

我对class_eval的理解是,它在运行时类的上下文中评估块 -在我的情况下,是在class Foo下.我希望上面的代码运行类似于:

My understanding of class_eval is that it evaluates the block in the context of the runtime class - in my case, under class Foo. I expect the above code runs similar as:

class Foo
  attr_count :bar
  @count = 0
  def bar= (attr_name)
    @attr_name = attr_name
    @count += 1
  end

  def bar
    @attr_name
  end
end

但是,以上代码导致错误提示,该错误是由@count += 1引起的.我不知道为什么@countnil:NilClass作为其超级键?

However the above code resulted in error saying, the error is caused by @count += 1. I cannot figure out why @count has nil:NilClass as its super?

(eval):5:in `bar=': undefined method `+' for nil:NilClass (NoMethodError)

另一方面,@ selman提供了一种解决方案,可以将@count分配放入实例方法中,并且可以正常工作.

On the other hand, @selman has given a solution to put @count assignment within the instance method and it works.

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

为什么更改变量作用域有效? class_eval如何执行其后续字符串?

Why changes the variable scope works? How does class_eval execute its following string?

推荐答案

它与class_eval无关,而与@count无关.如果在类级别定义此变量,它将是class instance variable而不是instance variable.

it is not about class_eval it is about @count. if you define this variable at class level it will be a class instance variable not an instance variable.

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{
      def #{attr_name}= (attr_name)
        @attr_name = attr_name
        if @count
          @count += 1
        else
          @count = 1
        end
      end

      def #{attr_name}
        @attr_name
      end
    }
  end
end

class Foo
  attr_count :bar
end

f = Foo.new
f.bar = 1

这篇关于`class_eval`字符串中的变量范围是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆