【问题标题】:Retrieve list of instance methods that are defined in rails class excluding inherited and included methods检索在 rails 类中定义的实例方法列表,不包括继承和包含的方法
【发布时间】:2019-04-21 20:54:09
【问题描述】:

我的 Rails 项目中有一个类 Product,我正在尝试检索在我的文件中定义的类的实例方法列表(不是继承方法或通过 mixin 包含)。这是我班级的一个小样本:

class Product
  include Mongoid::Document
  include Mongoid::Paperclip
  include Mongoid::Search
  include Mongoid::Slug
  include Mongoid::Timestamps
  extend Enumerize
    def product_image
    image.url(:small) unless image.nil?
  end

  def product_school_level
    self.school_levels.join ' | '
  end

  def product_grades
    self.grades.where(degree_ids: nil).pluck(:name).uniq.join ' | '
  end
end

我尝试使用Product.instance_methods(false)。但是,这仍然会返回很多我不需要的方法,这里有一个小示例: :_run_post_process_callbacks, :aliased_fields, :_post_process_callbacks, :_run_image_post_process_callbacks, :_image_post_process_callbacks, :_validation_callbacks, :nested_attributes?, :_run_touch_callbacks, :readonly_attributes?, :_run_save_callbacks, :aliased_fields?, :_save_callbacks, :localized_fields?, :readonly_attributes, :领域?, :pre_processed_defaults?, :_update_callbacks, :post_processed_defaults?, :字段, :_id_default

我在其中一些方法上运行了Product.new.method(:_run_post_process_callbacks).source_location,以尝试检查它们的来源。看来他们都来自active_support。 我从来没有在我的课程中包含 active_support,所以我猜 rails 项目中的类会自动包含 active_supports 方法?如果没有任何继承语法 (

【问题讨论】:

    标签: ruby-on-rails ruby inheritance mixins activesupport


    【解决方案1】:

    您看到的许多(大多数?全部?)这些额外方法都是使用Module#define_method 创建的。如果您深入挖掘active_support 的源代码,您会看到这一点。 (您没有直接包含active_support,但它被一个或多个Mongoid 模块拉入。)

    所以这些实际上是模型类的有效实例方法,这就是它们包含在instance_methods(false) 中的原因。在 mixins 中“常规”定义的其他方法,例如 #freeze,由 instance_methods(true) 报告,而不是由 instance_methods(false) 报告。

    我认为您可能需要做一些事情来根据源位置过滤列表。大致如下:

    my_methods = Product.instance_methods(false).select do |m|
      Product.instance_method(m).source_location.first.ends_with? '/product.rb'
    end
    

    【讨论】:

    • 我不明白你对 Module#define_method 的解释:apidock.com/ruby/Module/define_method。我已经检查过了,实际上当您在 Parent 类或稍后混入的模块中使用 define_method 时,Child.instance_methods(false) 不会返回该方法
    • @DavidGeismar。是的,define_method 可用于在包含类中定义方法。这是如何完成的示例:gist.github.com/showaltb/da9e8773211f9e7b62d2a52ec2047eb2。 (这不是active_support 使用的确切技术,但效果是一样的。)
    猜你喜欢
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    相关资源
    最近更新 更多