【问题标题】:Rails scope defined in a class_eval block or instance_eval block?在 class_eval 块或 instance_eval 块中定义的 Rails 范围?
【发布时间】:2017-05-06 01:11:24
【问题描述】:

我对文档中 ActiveSupport::Concern 上的 this 示例感到有些困惑:

module M
  def self.included(base)
    base.extend ClassMethods
    base.class_eval do
      scope :disabled, -> { where(disabled: true) }
    end
  end

  module ClassMethods
    ...
  end
end

self.included 在您在类中包含或扩展模块时调用。 base 指的是对象,不管是类对象还是对象实例。 extend on base 将包含 Module 中的方法作为 base 上的单例方法。 include 会将方法添加到类对象的实例中。

然而,class_eval 也用于向类对象的实例添加实例方法。然而,scope 是一个类方法:

添加一个用于检索和查询对象的类方法。

既然scope是一个类方法,为什么这个例子使用class_eval而不是instance_eval

【问题讨论】:

标签: ruby-on-rails ruby


【解决方案1】:

class_evalinstance_eval 更强大。

使用类 eval,您可以在类的上下文中评估代码,允许您定义和调用类方法、实例方法等:

Greeter = Class.new

Greeter.class_eval do
  def self.friendly?
    true
  end

  def say_hi
   "Howdy!"
  end
end

donato = Greeter.new
donato.say_hi # => "Howdy!"
Greeter.friendly? # => true

instance_eval 反而以目标实例作为接收者来评估代码,因此如果您尝试定义实例方法,则必须更加狡猾:

Greeter = Class.new

Greeter.instance_eval do
  def friendly?
    true
  end

  define_method(:say_hi) { "Howdy!" }
end

donato = Greeter.new
donato.say_hi # => "Howdy!"

【讨论】:

    猜你喜欢
    • 2011-04-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 2011-05-23
    • 1970-01-01
    • 2019-03-29
    相关资源
    最近更新 更多