在这个问题上:
您可以调用foo.methods并获取所有方法。但这并不能获得所有方法。使用ActiveStorage的Rails中的示例:
Image.first.specimens.first.methods.include?(:variant)
# => false
Image.first.specimens.first.respond_to?(:variant)
# => true
Image.first.specimens.first.variant
Traceback (most recent call last):
1: from (irb):3
ArgumentError (wrong number of arguments (given 0, expected 1))
Image.first.specimens.first.method(:variant)
# => #<Method: ActiveStorage::Attachment(id: integer, name: string, record_type: string, record_id: integer, blob_id: integer, created_at: datetime)#variant>
Run Code Online (Sandbox Code Playgroud)
鉴于正在引发ArgumentError,因此respond_to?可以抓取该方法,它确实具有variant方法。但是没有显示.methods。如何查看方法的完整列表?
也许您错过了链接文章公认答案中的最后一段。如何在Ruby中列出对象的所有方法?:
补充说明::has_many不会直接添加方法。相反,ActiveRecord机制使用Ruby method_missing和responses_to技术来即时处理方法调用。结果,这些方法未在方法方法结果中列出。
为了使代码示例更加清楚:
class Foo
def hello
puts 'Hello'
end
def method_missing(name, *args, &block)
case name
when :unknown_method
puts "handle unknown method %s" % name # name is a symbol
else
super #raises NoMethodError unless there is something else defined
end
end
end
foo = Foo.new
p foo.respond_to?(:hello) #-> true
p foo.respond_to?(:unknown_method) #-> false
foo.unknown_method #-> 'handle unknown method unknown_method'
foo.another_unknown_method #-> Exception
Run Code Online (Sandbox Code Playgroud)
该方法unknown_method从未定义过,但是有一种方法可以处理未知方法。因此,该类给人的印象是现有方法,但是没有。
也许如何动态获取方法的源代码,以及该方法位于哪个文件中有助于获取有关内容的信息:
Foo.instance_method(:method_missing).source_location
Run Code Online (Sandbox Code Playgroud)
当定义自己的时method_missing,还应该更改respond_to?with 的行为。respond_to_missing?
def respond_to_missing?(method, *)
return method == :unknown_method || super
#or if you have a list of methods:
#~ return %i{unknown_method}.include?(method) || super
#or with a regex for
#~ method =~ /another_(\w+)/ || super
end
end
Run Code Online (Sandbox Code Playgroud)
有关详细信息,另请参见`respond_to?`与`respond_to_missing?`。
| 归档时间: |
|
| 查看次数: |
140 次 |
| 最近记录: |