You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ActiveSupport::OrderedOptions returns true for .respond_to?(:call), which breaks various duck-type approach to detect callable objects. Example is pretty popular carrierwave-aws gem which checks if one of the options is callable by checking respond_to?(:call).
There is no reason to return true for any possible key. OpenStruct also returns 'nilfor non-existing keys, butrespond_to?only returnstruefor existing keys. On the other hand someone did it on purpose, otherwise why implementrespond_to_missing?as hard-codedtrue`, so I'm not sure if there was no higher design here.
# frozen_string_literal: truerequire"bundler/inline"gemfile(true)dosource"https://rubygems.org"git_source(:github){ |repo| "https://github.com/#{repo}.git"}gem"rails"# If you want to test against edge Rails replace the previous line with this:# gem "rails", github: "rails/rails", branch: "main"endrequire"active_support"require"active_support/core_ext/object/blank"require"minitest/autorun"classBugTest < Minitest::Testdeftest_ordered_options_respond_toassertActiveSupport::OrderedOptions.new.update(aaa: 1).respond_to?(:aaa)refuteActiveSupport::OrderedOptions.new.respond_to?(:call)endend
Expected behavior
ActiveSupport::OrderedOptions.new.respond_to?(:call) # => should return false
This is how it works. We can assign any value to it via options.foo= or get any value from it via options.foo (and get nil back if there is no any). There are tests for this class testing exactly this.
So, I do not think that this can or should be changed.
@fatkodima I see you yourself mentioned the issue of respond_to returning true to everything in this discussion. respond_to used in many places as standard duck-type approach. I think that even though OrderedOptions returns nil on any non-existing field and any field= method works, it doesn't respond_to? to follow it. Yes, it causes inconsistency, but it helps preserve the duck-typing pattern.
I don't think there can be any code that is dependent on respond_to? being true for OrderedOptions because given it's hard-coded to true, there's no meaning to this, so I see no damage changing it to be consistent with OpenStruct.
ActiveSupport::OrderedOptions
returnstrue
for.respond_to?(:call)
, which breaks various duck-type approach to detect callable objects. Example is pretty popular carrierwave-aws gem which checks if one of the options is callable by checkingrespond_to?(:call)
.There is no reason to return true for any possible key. OpenStruct also returns 'nil
for non-existing keys, but
respond_to?only returns
truefor existing keys. On the other hand someone did it on purpose, otherwise why implement
respond_to_missing?as hard-coded
true`, so I'm not sure if there was no higher design here.Steps to reproduce
Expected behavior
ActiveSupport::OrderedOptions.new.respond_to?(:call) # => should return false
Actual behavior
ActiveSupport::OrderedOptions.new.respond_to?(:call) # => returns true
System configuration
Rails version: 7.0.8.1
Ruby version: 3.0.4
The text was updated successfully, but these errors were encountered: