diff --git a/lib/net/imap.rb b/lib/net/imap.rb index 2f44d8a4..19dd89a1 100644 --- a/lib/net/imap.rb +++ b/lib/net/imap.rb @@ -2498,11 +2498,13 @@ def idle_done RESPONSES_DEPRECATION_MSG = "Pass a type or block to #responses, " \ - "set config.responses_without_block to :silence_deprecation_warning, " \ + "set config.responses_without_block to :frozen_dup " \ + "or :silence_deprecation_warning, " \ "or use #extract_responses or #clear_responses." private_constant :RESPONSES_DEPRECATION_MSG # :call-seq: + # responses -> hash of {String => Array} (see config.responses_without_block) # responses(type) -> frozen array # responses {|hash| ...} -> block result # responses(type) {|array| ...} -> block result @@ -2532,6 +2534,10 @@ def idle_done # Prints a warning and returns the mutable responses hash. # This is not thread-safe. # + # [+:frozen_dup+] + # Returns a frozen copy of the unhandled responses hash, with frozen + # array values. + # # [+:raise+ (planned future default)] # Raise an +ArgumentError+ with the deprecation warning. # @@ -2603,6 +2609,13 @@ def responses(type = nil) raise ArgumentError, RESPONSES_DEPRECATION_MSG when :warn warn(RESPONSES_DEPRECATION_MSG, uplevel: 1) + when :frozen_dup + synchronize { + responses = @responses.transform_values(&:freeze) + responses.default_proc = nil + responses.default = [].freeze + return responses.freeze + } end @responses end diff --git a/lib/net/imap/config.rb b/lib/net/imap/config.rb index c7be267b..4f2ae899 100644 --- a/lib/net/imap/config.rb +++ b/lib/net/imap/config.rb @@ -237,6 +237,15 @@ def self.[](config) # Prints a warning and returns the mutable responses hash. # This is not thread-safe. # + # [+:frozen_dup+] + # Returns a frozen copy of the unhandled responses hash, with frozen + # array values. + # + # Note that calling IMAP#responses with a +type+ and without a block is + # not configurable and always behaves like +:frozen_dup+. + # + # (+:frozen_dup+ config option was added in +v0.4.17+) + # # [+:raise+ (planned future default)] # Raise an ArgumentError with the deprecation warning. # diff --git a/test/net/imap/test_imap_responses.rb b/test/net/imap/test_imap_responses.rb index 911a3434..aaa61d43 100644 --- a/test/net/imap/test_imap_responses.rb +++ b/test/net/imap/test_imap_responses.rb @@ -166,6 +166,15 @@ def assert_responses_warn assert_equal [], imap.responses["FAKE"] end assert_empty stderr + # opt-in to future behavior + imap.config.responses_without_block = :frozen_dup + stderr = EnvUtil.verbose_warning do + assert imap.responses.frozen? + assert imap.responses["CAPABILITY"].frozen? + assert_equal(%w[IMAP4REV1 NAMESPACE MOVE IDLE UTF8=ACCEPT], + imap.responses["CAPABILITY"].last) + end + assert_empty stderr end end