@@ -129,8 +129,25 @@ def self.default; @default end
129129 def self . global ; @global if defined? ( @global ) end
130130
131131 # A hash of hard-coded configurations, indexed by version number or name.
132+ # Values can be accessed with any object that responds to +to_sym+ or
133+ # +to_r+/+to_f+ with a non-zero number.
134+ #
135+ # Config::[] gets named or numbered versions from this hash.
136+ #
137+ # For example:
138+ # Net::IMAP::Config.version_defaults[0.5] == Net::IMAP::Config[0.5]
139+ # Net::IMAP::Config[0.5] == Net::IMAP::Config[0.5r] # => true
140+ # Net::IMAP::Config["current"] == Net::IMAP::Config[:current] # => true
141+ # Net::IMAP::Config["0.5.6"] == Net::IMAP::Config[0.5r] # => true
132142 def self . version_defaults ; @version_defaults end
133- @version_defaults = { }
143+ @version_defaults = Hash . new { |h , k |
144+ # NOTE: String responds to both so the order is significant.
145+ # And ignore non-numeric conversion to zero, because: "wat!?".to_r == 0
146+ ( h . fetch ( k . to_r , nil ) || h . fetch ( k . to_f , nil ) if k . is_a? ( Numeric ) ) ||
147+ ( h . fetch ( k . to_sym , nil ) if k . respond_to? ( :to_sym ) ) ||
148+ ( h . fetch ( k . to_r , nil ) if k . respond_to? ( :to_r ) && k . to_r != 0 r) ||
149+ ( h . fetch ( k . to_f , nil ) if k . respond_to? ( :to_f ) && k . to_f != 0.0 )
150+ }
134151
135152 # :call-seq:
136153 # Net::IMAP::Config[number] -> versioned config
@@ -153,18 +170,17 @@ def self.[](config)
153170 elsif config . nil? && global . nil? then nil
154171 elsif config . respond_to? ( :to_hash ) then new ( global , **config ) . freeze
155172 else
156- version_defaults . fetch ( config ) do
173+ version_defaults [ config ] or
157174 case config
158175 when Numeric
159176 raise RangeError , "unknown config version: %p" % [ config ]
160- when Symbol
177+ when String , Symbol
161178 raise KeyError , "unknown config name: %p" % [ config ]
162179 else
163180 raise TypeError , "no implicit conversion of %s to %s" % [
164181 config . class , Config
165182 ]
166183 end
167- end
168184 end
169185 end
170186
@@ -413,41 +429,50 @@ def defaults_hash
413429
414430 version_defaults [ :default ] = Config [ default . send ( :defaults_hash ) ]
415431
416- version_defaults [ 0 ] = Config [ :default ] . dup . update (
432+ version_defaults [ 0 r ] = Config [ :default ] . dup . update (
417433 sasl_ir : false ,
418434 parser_use_deprecated_uidplus_data : true ,
419435 parser_max_deprecated_uidplus_data_size : 10_000 ,
420436 ) . freeze
421- version_defaults [ 0.0 ] = Config [ 0 ]
422- version_defaults [ 0.1 ] = Config [ 0 ]
423- version_defaults [ 0.2 ] = Config [ 0 ]
424- version_defaults [ 0.3 ] = Config [ 0 ]
437+ version_defaults [ 0.0 r ] = Config [ 0 r ]
438+ version_defaults [ 0.1 r ] = Config [ 0 r ]
439+ version_defaults [ 0.2 r ] = Config [ 0 r ]
440+ version_defaults [ 0.3 r ] = Config [ 0 r ]
425441
426- version_defaults [ 0.4 ] = Config [ 0.3 ] . dup . update (
442+ version_defaults [ 0.4 r ] = Config [ 0.3 r ] . dup . update (
427443 sasl_ir : true ,
428444 parser_max_deprecated_uidplus_data_size : 1000 ,
429445 ) . freeze
430446
431- version_defaults [ 0.5 ] = Config [ 0.4 ] . dup . update (
447+ version_defaults [ 0.5 r ] = Config [ 0.4 r ] . dup . update (
432448 responses_without_block : :warn ,
433449 parser_use_deprecated_uidplus_data : :up_to_max_size ,
434450 parser_max_deprecated_uidplus_data_size : 100 ,
435451 ) . freeze
436452
437- version_defaults [ 0.6 ] = Config [ 0.5 ] . dup . update (
453+ version_defaults [ 0.6 r ] = Config [ 0.5 r ] . dup . update (
438454 responses_without_block : :frozen_dup ,
439455 parser_use_deprecated_uidplus_data : false ,
440456 parser_max_deprecated_uidplus_data_size : 0 ,
441457 ) . freeze
442458
443- version_defaults [ 0.7 ] = Config [ 0.6 ] . dup . update (
459+ version_defaults [ 0.7 r ] = Config [ 0.6 r ] . dup . update (
444460 ) . freeze
445461
446- current = VERSION . to_f
462+ # Safe conversions one way only:
463+ # 0.6r.to_f == 0.6 # => true
464+ # 0.6 .to_r == 0.6r # => false
465+ version_defaults . to_a . each do |k , v |
466+ next unless k . is_a? Rational
467+ version_defaults [ k . to_f ] = v
468+ end
469+
470+ current = VERSION . to_r
447471 version_defaults [ :original ] = Config [ 0 ]
448472 version_defaults [ :current ] = Config [ current ]
449- version_defaults [ :next ] = Config [ current + 0.1 ]
450- version_defaults [ :future ] = Config [ 0.7 ]
473+ version_defaults [ :next ] = Config [ current + 0.1 r]
474+
475+ version_defaults [ :future ] = Config [ 0.7 r]
451476
452477 version_defaults . freeze
453478
0 commit comments