`class_eval` 字符串中的变量范围是什么?

2024-05-11

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

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。我期望上面的代码运行类似于:

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。我不明白为什么@count has nil:NilClass作为其超级?

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

另一方面,@selman 给出了一个解决方案@count在实例方法中进行赋值并且它有效。

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执行它的下面的字符串?


这不是关于class_eval这是关于@count。如果您在类级别定义此变量,它将是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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

`class_eval` 字符串中的变量范围是什么? 的相关文章

随机推荐

  • Watir 脚本偶尔返回 Net::ReadTimeout 错误

    我有一个 Watir 脚本 偶尔会意外地返回此错误 Net ReadTimeout 我搜索了这个错误并发现这个问题 https stackoverflow com questions 47452276 watir get sometimes
  • 非 Activity 类中的 findViewById

    对此我仍然相对较新 在我在活动类 MainActivity 中使用的非活动类 MyLocation 中查找视图时遇到问题 我正在使用 MyLocation 来获取经度和纬度 我想在使用 GPS 或网络时突出显示文本视图 为此 我需要在非活动
  • Pytesseract,尝试检测屏幕上的文本

    我将 MSS 与 pytesseract 结合使用 尝试在屏幕上读取以确定正在监视的区域中的字符串 我的代码如下 import Image import pytesseract import cv2 import os import mss
  • C# 泛型重载 - 编译器无法确定正确的调用

    我不明白为什么编译器无法解析此处使用的正确重载 代码如下 只有一个版本的 Add 是合适的 BigFoo 是一个 IFoo 并且不实现 IEnumerable 其中 T 是一个 IFoo 但它坚持报告含糊之处 有任何想法吗 我尝试添加第二个
  • Delphi DataSnap REST 服务器从 TStream 返回 JSON 数组,而不是二进制

    我有一个与 Android 客户端通信的 REST 服务器 我将它从 XE3 ish 升级到 Berlin 其中一个服务器方法返回一个包含 jpeg 的 TStream 并且工作得很好 很高兴将图像作为二进制图像返回 升级到 Berlin
  • 如何向 WordPress.com 上托管的 WordPress 博客添加语法突出显示?

    我希望为我的 WordPress 博客提供一个好的语法荧光笔 我有哪些选择 我经常看到它具有颜色鲜艳的语法突出显示和复制到剪贴板的选项 有谁知道这是什么工具吗 在 wordpress com 上 您无法安装插件 因此您必须使用 Wordpr
  • 如何在Python中完美地将单元素列表转换为元组? [复制]

    这个问题在这里已经有答案了 所以我正在尝试这样做 tuple 1 我期望的输出是 1 但是 我得到了这个 1 但如果我这样做 tuple 1 2 它工作完美 像这样 1 2 这太奇怪了 我不知道为什么元组函数会导致这个结果 请帮我解决它 这
  • 从 DoubleLinkedList 中删除重复项

    我正在尝试删除 C 中的重复项 我已经设法使用对象默认构造函数将对象设置为 null 但我无法将其从列表中完全删除 此代码还删除了两个对象 而不仅仅是一个 这是另一个问题的转帖 我的代码和部分帖子已更改 如何按全名从双向链表中删除重复项 h
  • MongoDB 查询返回空数组

    有一个基本的 Express 应用程序连接到几乎 0 5 GB 的 MongoDB 数据库 当我运行时 router get function req res next medical data find State CT function
  • 从 google Drive 自行下载 xlsx 文件

    所以 我正在尝试制作一个小脚本 它将使用谷歌驱动器API下载一个Excel文件 通过遵循谷歌API教程 我遇到了两个错误 无法读取未定义的 on 属性 和 请求的转换是不支持 这是代码 const fs require fs const r
  • 如何手动推断表达式的类型

    给定 Haskell 函数 head filter fst 现在的问题是如何手动 手动 找到类型 如果我让 Haskell 告诉我我得到的类型 head filter fst Bool b gt Bool b 但我想了解仅使用所用函数的签名
  • 无法在 SBT 中运行 Apache Spark 相关单元测试 - NoClassDefFoundError

    我有一个简单的单元测试 使用SparkContext 我可以在 IntelliJ Idea 中运行单元测试 没有任何问题 但是 当尝试从 SBT shell 运行相同的测试时 我收到以下错误 java lang NoClassDefFoun
  • 跟踪 C++ 中递归函数被调用的次数

    我正在尝试编写一个程序 该程序具有一个参数是字符串向量的函数 我想在该函数上使用递归 但每次调用该函数时 我想更改参数 例如 fun stringArray i 其中 i 是调用该函数的次数 因此 以更简单的方式 如下所示 但我需要跟踪函数
  • 用于裁剪和转置视频的 FFMPEG 命令放大后质量较差

    我正在尝试将尺寸通常为 960x720 的 mp4 视频转换为方形 480 480 视频 但它通常看起来被压扁 命令是 y i s vf crop 480 480 transpose d threads 5 metadata s v rot
  • Python 中最宽容的 HTML 解析器是什么?

    我有一些随机的 HTML 我使用 BeautifulSoup 来解析它 但在大多数情况下 gt 70 它会令人窒息 我尝试使用Beautiful soup 3 0 8和3 2 0 3 1 0以上有一些问题 但结果几乎相同 我可以从我的脑海中
  • 如何在UIWindow中添加视图?

    我想添加一个视图UIWindow与以下代码 AppDelegate delegate AppDelegate UIApplication sharedApplication delegate UIWindow window delegate
  • Javascript 连接 [重复]

    这个问题在这里已经有答案了 我在在线 javascript 测验中发现了以下代码片段 我无法理解这种串联在 JS 中是如何工作的 有人可以解释一下这是如何工作的吗 output foo output foo Javascript 尝试应用
  • swift:移动动画

    我在故事板中有 viewController 还有4个正方形 我想将我的方块放在视图中 首先我想显示两个正方形 如果我按下按钮 我希望我的红色 2 个方块向左移动 然后显示接下来的 2 个蓝色方块 就像这部动画 我需要创建一个scrollV
  • 为什么我的原生 C++ 代码在 Android 上运行速度比 Java 慢很多?

    我将 Java 代码的某些部分移植到 C 以加快 Android 上的计算速度 这是一个物理子例程 我发现本机代码的运行速度比 Java 代码慢几倍 我认为我的项目配置可能有问题 或者可能是数组处理有问题 所以我在 HelloAndroid
  • `class_eval` 字符串中的变量范围是什么?

    我在用class eval编写要在当前类的上下文中执行的代码 在下面的代码中 我想添加一个用于属性值更改的计数器 class Class def attr count attr name attr name attr name to s a