如何在Ruby中列出对象的所有方法?


112

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

我有一个@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!记住要“检查”最能回答您问题的答案。同时,对任何您认为有用/有帮助的问题的答案进行投票。
拉里K

Answers:


209

下面将列出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是用于Classes和Class实例的方法。

这是我的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方法结果中列出。


2
尽管由于某些方法仅在调用method_missing时才创建(例如,动态查找器),所以可能还不完整
Frederick Cheung

如果我尝试responses_to?我收到一个方法丢失的错误。我正在application.html.erb内部运行此文件
Dirk,

@Dirk-可能不存在该方法...我建议您提出一个新问题,在其中显示您的AR类定义是什么,然后询问您认为:has_many应该提供的特定方法。你也有匹配的:belongs_to吗?Rails的AR资本化和多元化规则导致许多误入歧途……
Larry K

@拉里 谢谢-我可以使用.to_yaml获取列表。看起来像这样:----:sketches-:sketch_ids-:sketches =-:sketch_ids =-::before_add_for_sketches-:before_add_for_sketches?<许多省略> ........如何访问这些方法?(也让我对文档表示赞赏:)
Dirk

:has_many 的文档显示了许多添加的方法。其他是Rails更高版本的新增功能。这些包括“ before_add_for”等。它们是“关联回调”-参见本文档的
Larry K

9

模块#instance_methods

返回一个数组,该数组包含接收方中的公共实例方法和受保护实例方法的名称。对于模块,这些是公共和受保护的方法。对于一个类,它们是实例方法(不是单例方法)。没有参数或参数为false时,将返回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




1

假设用户has_many帖子:

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

1

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

Parser.new.methods - Object.new.methods

1

如果您正在查找由实例响应的方法列表(在您的情况下为@current_user)。根据红宝石文件编制方法

返回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.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.