| 
									
										
										
										
											2024-01-11 19:22:16 -08:00
										 |  |  | # typed: strict | 
					
						
							| 
									
										
										
										
											2023-11-29 15:18:14 +00:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Hash | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # Returns a new hash with `self` and `other_hash` merged recursively. | 
					
						
							| 
									
										
										
										
											2023-11-29 15:18:14 +00:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ### Examples | 
					
						
							| 
									
										
										
										
											2023-11-29 15:18:14 +00:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # h1 = { a: true, b: { c: [1, 2, 3] } } | 
					
						
							|  |  |  |   # h2 = { a: false, b: { x: [3, 4, 5] } } | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # h1.deep_merge(h2) # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } } | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-29 15:18:14 +00:00
										 |  |  |   # | 
					
						
							|  |  |  |   # Like with Hash#merge in the standard library, a block can be provided | 
					
						
							|  |  |  |   # to merge values: | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # h1 = { a: 100, b: 200, c: { c1: 100 } } | 
					
						
							|  |  |  |   # h2 = { b: 250, c: { c1: 200 } } | 
					
						
							|  |  |  |   # h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val } | 
					
						
							|  |  |  |   # # => { a: 100, b: 450, c: { c1: 300 } } | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2024-01-12 15:17:12 -08:00
										 |  |  |   def deep_merge(other_hash, &block) | 
					
						
							|  |  |  |     dup.deep_merge!(other_hash, &block) | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2023-11-29 15:18:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # Same as {#deep_merge}, but modifies `self`. | 
					
						
							| 
									
										
										
										
											2023-11-29 15:18:14 +00:00
										 |  |  |   def deep_merge!(other_hash, &block) | 
					
						
							|  |  |  |     merge!(other_hash) do |key, this_val, other_val| | 
					
						
							| 
									
										
										
										
											2024-01-11 19:22:16 -08:00
										 |  |  |       if T.unsafe(this_val).is_a?(Hash) && other_val.is_a?(Hash) | 
					
						
							|  |  |  |         T.unsafe(this_val).deep_merge(other_val, &block) | 
					
						
							|  |  |  |       elsif block | 
					
						
							|  |  |  |         yield(key, this_val, other_val) | 
					
						
							| 
									
										
										
										
											2023-11-29 15:18:14 +00:00
										 |  |  |       else | 
					
						
							|  |  |  |         other_val | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |