Skip to content

Instantly share code, notes, and snippets.

@senny
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save senny/02ee933cc75e7ac8093f to your computer and use it in GitHub Desktop.
Save senny/02ee933cc75e7ac8093f to your computer and use it in GitHub Desktop.
`Array#flatten` ignores `respond_to_missing?` when calling `to_ary`

This issue was reported on bugs.ruby-lang.org: https://bugs.ruby-lang.org/issues/11465

The issue appears when using Array#flatten on an instance of Array containing instances of a Class that implements method_missing. Ruby still calls #to_ary even when said class implements respond_to_missing? and returns false for to_ary. Everything works when the class also overwrites respond_to?.

Questions:

  1. Is it expected that respond_to_missing? has no effect in the scenario above?
  2. Should a possible workaround rather define a respond_to? method or overwrite to_ary and return nil?

Context:

The problem was found when working on a issue reported on the Rails tracker: rails/rails#21296

class RespondToMissing
def respond_to_missing?(method, stuff)
return false if method == :to_ary
super
end
def method_missing(*args)
super
end
end
class RespondTo
def respond_to?(method)
return false if method == :to_ary
super
end
def method_missing(*args)
super
end
end
trace = TracePoint.new(:raise) do |tp|
p tp.raised_exception
puts tp.raised_exception.backtrace.join("\n")
puts
end
trace.enable
p RespondToMissing.new.respond_to? :to_ary # => false
p RespondTo.new.respond_to? :to_ary # => false
[RespondTo.new].flatten
# no internal exceptions are raised
[RespondToMissing.new].flatten
# #to_ary is being called and internal NoMethodError is raised.
# OUTPUT:
# false
# false
# #<NoMethodError: undefined method `to_ary' for #<RespondToMissing:0x007fd57322ce78>>
# script.rb:10:in `method_missing'
# script.rb:38:in `flatten'
# script.rb:38:in `<main>'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment