【问题标题】:How to list all methods for an object in Ruby?如何在 Ruby 中列出对象的所有方法?
【发布时间】:2011-12-21 19:25:06
【问题描述】:

如何列出特定对象可以访问的所有方法?

我有一个@current_user 对象,在应用程序控制器中定义:

def current_user
  @current_user ||= User.find(session[:user_id]) if session[:user_id]
end

并想在视图文件中查看我可以使用哪些方法。具体来说,我想看看:has_many 关联提供了哪些方法。 (我知道:has_many 应该提供什么,但想检查一下。)

【问题讨论】:

  • 澄清一下,你想要@current_user上可调用的方法吗?
  • @Dirk,欢迎来到 stackoverflow!请记住“检查”最能回答您的问题的答案。还可以对任何您认为有用/有帮助的任何问题的答案进行投票。

标签: ruby-on-rails ruby


【解决方案1】:

下面将列出User类拥有的基础Object类没有的方法...

>> User.methods - Object.methods
=> ["field_types", "maximum", "create!", "active_connections", "to_dropdown",
    "content_columns", "su_pw?", "default_timezone", "encode_quoted_value", 
    "reloadable?", "update", "reset_sequence_name", "default_timezone=", 
    "validate_find_options", "find_on_conditions_without_deprecation", 
    "validates_size_of", "execute_simple_calculation", "attr_protected", 
    "reflections", "table_name_prefix", ...

请注意,methods 是类和类实例的方法。

这是我的 User 类所具有的 ActiveRecord 基类中没有的方法:

>> User.methods - ActiveRecord::Base.methods
=> ["field_types", "su_pw?", "set_login_attr", "create_user_and_conf_user", 
    "original_table_name", "field_type", "authenticate", "set_default_order",
    "id_name?", "id_name_column", "original_locking_column", "default_order",
    "subclass_associations",  ... 
# I ran the statements in the console.

请注意,由于 User 类中定义的(许多)has_many 关系而创建的方法在methods 调用的结果中

添加请注意 :has_many 不直接添加方法。相反,ActiveRecord 机器使用 Ruby method_missingresponds_to 技术来动态处理方法调用。因此,methods 方法结果中没有列出这些方法。

【讨论】:

  • 虽然这可能不完整,因为某些方法仅在调用 method_missing 时创建(例如动态查找器)
  • 如果我尝试 responds_to?我收到一个方法丢失错误。我在 application.html.erb 中运行它
  • @Dirk -- 可能该方法不存在...我建议您提出一个新问题,在其中显示您的 AR 类定义是什么,然后询问您认为应该使用的具体方法:has_many提供。你也有匹配的:belongs_to 吗? Rails 对 AR 的大小写和复数规则让很多人误入歧途……
  • @Larry。谢谢 - 我可以使用 .to_yaml 获取列表。它看起来像这样: --- - :sketches - :sketch_ids - :sketches= - :sketch_ids= - :before_add_for_sketches - :before_add_for_sketches? ........我如何访问这些方法? (指向我也很感激的文档:)
  • :has_many 的docs 显示了许多添加的方法。其他的对于更高版本的 Rails 来说是新的。其中包括“before_add_for”等。它们是“关联回调”——参见doc 的那部分
【解决方案2】:

或者只是 User.methods(false) 只返回该类中定义的方法。

【讨论】:

    【解决方案3】:

    Module#instance_methods

    返回一个数组,其中包含接收器中公共和受保护实例方法的名称。对于一个模块,这些是公共和受保护的方法;对于一个类,它们是实例(不是单例)方法。不带参数或带假参数时,返回 mod 中的实例方法,否则返回 mod 和 mod 的超类中的方法。

    module A
      def method1()  end
    end
    class B
      def method2()  end
    end
    class C < B
      def method3()  end
    end
    
    A.instance_methods                #=> [:method1]
    B.instance_methods(false)         #=> [:method2]
    C.instance_methods(false)         #=> [:method3]
    C.instance_methods(true).length   #=> 43
    

    【讨论】:

      【解决方案4】:

      你可以的

      current_user.methods
      

      为了更好的上市

      puts "\n\current_user.methods : "+ current_user.methods.sort.join("\n").to_s+"\n\n"
      

      【讨论】:

        【解决方案5】:

        其中之一呢?

        object.methods.sort
        Class.methods.sort
        

        【讨论】:

          【解决方案6】:

          如果您正在查看由实例响应的方法列表(在您的情况下为 @current_user)。根据 ruby​​ 文档methods

          返回 obj 的公共和受保护方法的名称列表。 这将包括 obj 的祖先中可访问的所有方法。如果 可选参数为false,它返回一个obj的数组 公共和受保护的单例方法,数组将不包括 obj 中包含的模块中的方法。

          @current_user.methods
          @current_user.methods(false) #only public and protected singleton methods and also array will not include methods in modules included in @current_user class or parent of it.
          

          另外,您还可以检查方法是否可以在对象上调用?

          @current_user.respond_to?:your_method_name
          

          如果您不想要父类方法,那么只需从中减去父类方法。

          @current_user.methods - @current_user.class.superclass.new.methods #methods that are available to @current_user instance.
          

          【讨论】:

            【解决方案7】:

            假设用户有_many 个帖子:

            u = User.first
            u.posts.methods
            u.posts.methods - Object.methods
            

            【讨论】:

              【解决方案8】:

              阐述@clyfe 的回答。您可以使用以下代码获取实例方法的列表(假设您有一个名为“Parser”的对象类):

              Parser.new.methods - Object.new.methods
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-04-19
                • 1970-01-01
                • 1970-01-01
                • 2020-06-06
                • 2012-12-28
                • 2017-06-13
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多