【问题标题】:Why use 'instance_eval' instead of creating a method?为什么使用“instance_eval”而不是创建方法?
【发布时间】:2018-09-12 08:31:31
【问题描述】:

这是一个代码示例:

class Book
  def initialize
    @v = "abc"
  end
end

b = Book.new
b.instance_eval do
  def book_name
  end
end

为什么我们使用instance_eval 创建一个方法(book_name)而不是在类Book 中添加book_name 方法?在上述情况下,使用 instance_eval 创建的方法 (book_name) 只能由对象 b 访问。有什么特别的用例吗?

【问题讨论】:

  • 请编辑将Class Book更改为class Book

标签: ruby instance-eval


【解决方案1】:

instance_eval 在需要某种元编程时非常有用,例如在实例初始化期间或在框架内部定义方法时。

为什么要使用它?在这些情况下,它通常比调用 define_method 更快,如果同时添加一堆方法,只会使方法缓存失效一次。

在您的具体示例中,该方法仅在 b 实例上创建,使其成为所谓的 singleton method,这意味着它仅存在于此特定实例中。作者本可以使用eval,但由于它在更全局的范围内评估代码,因此被认为是不安全的。

编辑:

如果您使用b 作为接收者定义方法,也会产生相同的效果

def b.book_name
end

【讨论】:

    【解决方案2】:

    此代码的作者希望 book_name 成为仅属于 b 的方法。如果他在类定义中创建,它将属于类Book的每个对象。

    【讨论】:

    • 这是我们使用 instance_eval 的唯一原因
    • 这个问题已经提到了。 “在上述情况下,使用 instance_eval 创建的方法(书名)只能由对象 b 访问”
    • @JagdeepSingh :我看到问题已经在此期间进行了编辑。
    • @rohankharvi :不,instance_eval 还有其他几种用途,例如从外部访问对象的实例变量。另外,给对象添加方法也可以通过不同的方式实现。
    • @JagdeepSingh 在这种情况下,define_singleton_method 将是实现相同结果的更惯用方式
    猜你喜欢
    • 2012-04-03
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 2011-08-23
    • 1970-01-01
    • 2012-03-17
    相关资源
    最近更新 更多