@@ -2496,41 +2496,98 @@ def idle_done
2496
2496
end
2497
2497
end
2498
2498
2499
+ RESPONSES_DEPRECATION_MSG =
2500
+ "Pass a type or block to #responses, " \
2501
+ "set config.responses_without_block to :frozen_dup " \
2502
+ "or :silence_deprecation_warning, " \
2503
+ "or use #extract_responses or #clear_responses."
2504
+ private_constant :RESPONSES_DEPRECATION_MSG
2505
+
2499
2506
# :call-seq:
2507
+ # responses -> hash of {String => Array} (see config.responses_without_block)
2508
+ # responses(type) -> frozen array
2500
2509
# responses {|hash| ...} -> block result
2501
2510
# responses(type) {|array| ...} -> block result
2502
2511
#
2503
- # Yields unhandled responses and returns the result of the block.
2512
+ # Yields or returns unhandled server responses. Unhandled responses are
2513
+ # stored in a hash, with arrays of UntaggedResponse#data keyed by
2514
+ # UntaggedResponse#name and <em>non-+nil+</em> untagged ResponseCode#data
2515
+ # keyed by ResponseCode#name.
2516
+ #
2517
+ # When a block is given, yields unhandled responses and returns the block's
2518
+ # result. Without a block, returns the unhandled responses.
2519
+ #
2520
+ # [With +type+]
2521
+ # Yield or return only the array of responses for that +type+.
2522
+ # When no block is given, the returned array is a frozen copy.
2523
+ # [Without +type+]
2524
+ # Yield or return the entire responses hash.
2525
+ #
2526
+ # When no block is given, the behavior is determined by
2527
+ # Config#responses_without_block:
2528
+ # >>>
2529
+ # [+:silence_deprecation_warning+ <em>(original behavior)</em>]
2530
+ # Returns the mutable responses hash (without any warnings).
2531
+ # <em>This is not thread-safe.</em>
2532
+ #
2533
+ # [+:warn+ <em>(default since +v0.5+)</em>]
2534
+ # Prints a warning and returns the mutable responses hash.
2535
+ # <em>This is not thread-safe.</em>
2536
+ #
2537
+ # [+:frozen_dup+ <em>(planned default for +v0.6+)</em>]
2538
+ # Returns a frozen copy of the unhandled responses hash, with frozen
2539
+ # array values.
2504
2540
#
2505
- # Unhandled responses are stored in a hash, with arrays of
2506
- # <em>non-+nil+</em> UntaggedResponse#data keyed by UntaggedResponse#name
2507
- # and ResponseCode#data keyed by ResponseCode#name. Call without +type+ to
2508
- # yield the entire responses hash. Call with +type+ to yield only the array
2509
- # of responses for that type.
2541
+ # [+:raise+]
2542
+ # Raise an +ArgumentError+ with the deprecation warning.
2510
2543
#
2511
2544
# For example:
2512
2545
#
2513
2546
# imap.select("inbox")
2514
- # p imap.responses("EXISTS", &:last)
2547
+ # p imap.responses("EXISTS").last
2515
2548
# #=> 2
2549
+ # p imap.responses("UIDNEXT", &:last)
2550
+ # #=> 123456
2516
2551
# p imap.responses("UIDVALIDITY", &:last)
2517
2552
# #=> 968263756
2553
+ # p imap.responses {|responses|
2554
+ # {
2555
+ # exists: responses.delete("EXISTS").last,
2556
+ # uidnext: responses.delete("UIDNEXT").last,
2557
+ # uidvalidity: responses.delete("UIDVALIDITY").last,
2558
+ # }
2559
+ # }
2560
+ # #=> {:exists=>2, :uidnext=>123456, :uidvalidity=>968263756}
2561
+ # # "EXISTS", "UIDNEXT", and "UIDVALIDITY" have been removed:
2562
+ # p imap.responses(&:keys)
2563
+ # #=> ["FLAGS", "OK", "PERMANENTFLAGS", "RECENT", "HIGHESTMODSEQ"]
2564
+ #
2565
+ # Related: #extract_responses, #clear_responses, #response_handlers, #greeting
2518
2566
#
2567
+ # ===== Thread safety
2519
2568
# >>>
2520
2569
# *Note:* Access to the responses hash is synchronized for thread-safety.
2521
2570
# The receiver thread and response_handlers cannot process new responses
2522
2571
# until the block completes. Accessing either the response hash or its
2523
- # response type arrays outside of the block is unsafe.
2572
+ # response type arrays outside of the block is unsafe. They can be safely
2573
+ # updated inside the block. Consider using #clear_responses or
2574
+ # #extract_responses instead.
2575
+ #
2576
+ # Net::IMAP will add and remove responses from the responses hash and its
2577
+ # array values, in the calling threads for commands and in the receiver
2578
+ # thread, but will not modify any responses after adding them to the
2579
+ # responses hash.
2524
2580
#
2525
- # Calling without a block is unsafe and deprecated. Future releases will
2526
- # raise ArgumentError unless a block is given.
2527
- # See Config#responses_without_block.
2581
+ # ===== Clearing responses
2528
2582
#
2529
2583
# Previously unhandled responses are automatically cleared before entering a
2530
2584
# mailbox with #select or #examine. Long-lived connections can receive many
2531
2585
# unhandled server responses, which must be pruned or they will continually
2532
2586
# consume more memory. Update or clear the responses hash or arrays inside
2533
- # the block, or use #clear_responses.
2587
+ # the block, or remove responses with #extract_responses, #clear_responses,
2588
+ # or #add_response_handler.
2589
+ #
2590
+ # ===== Missing responses
2534
2591
#
2535
2592
# Only non-+nil+ data is stored. Many important response codes have no data
2536
2593
# of their own, but are used as "tags" on the ResponseText object they are
@@ -2541,19 +2598,24 @@ def idle_done
2541
2598
# ResponseCode#data on tagged responses. Although some command methods do
2542
2599
# return the TaggedResponse directly, #add_response_handler must be used to
2543
2600
# handle all response codes.
2544
- #
2545
- # Related: #extract_responses, #clear_responses, #response_handlers, #greeting
2546
2601
def responses ( type = nil )
2547
2602
if block_given?
2548
2603
synchronize { yield ( type ? @responses [ type . to_s . upcase ] : @responses ) }
2549
2604
elsif type
2550
- raise ArgumentError , "Pass a block or use #clear_responses"
2605
+ synchronize { @responses [ type . to_s . upcase ] . dup . freeze }
2551
2606
else
2552
2607
case config . responses_without_block
2553
2608
when :raise
2554
- raise ArgumentError , "Pass a block or use #clear_responses"
2609
+ raise ArgumentError , RESPONSES_DEPRECATION_MSG
2555
2610
when :warn
2556
- warn ( "DEPRECATED: pass a block or use #clear_responses" , uplevel : 1 )
2611
+ warn ( RESPONSES_DEPRECATION_MSG , uplevel : 1 )
2612
+ when :frozen_dup
2613
+ synchronize {
2614
+ responses = @responses . transform_values ( &:freeze )
2615
+ responses . default_proc = nil
2616
+ responses . default = [ ] . freeze
2617
+ return responses . freeze
2618
+ }
2557
2619
end
2558
2620
@responses
2559
2621
end
0 commit comments