rbs icon indicating copy to clipboard operation
rbs copied to clipboard

[Hash] Update Hash's signatures and tests to be correct

Open sampersand opened this issue 2 months ago • 1 comments

PHEW! This was a long one, but now Hash is finally done!

This PR updates all of the definitions within hash.rbs to be more correct, as well as modernizes the entire Hash_test.rb file, which was still using the old format.

A complete list of functional changes is below. Bolded ones are important.

  • Hash::_Pair[K, V] is added; Hash.[] and Hash#to_h use it.
  • Hash::_Equals is added. Used by Hash#{assoc,has_value?,rassoc}.
  • Hash.[] has been changed to return instances in the Hash[a: 1] and Hash[[:a, 1]] cases, and now uses _Pair
  • Hash.try_convert returns nil in the untyped case.
  • Hash#{<,>,<=,>=} all now accept hash[untyped, untyped]
  • Hash#[] now accepts Hash::_Key
  • Hash#any?'s signature has been fixed: the block form actually is a tuple, and now uses Enumerable::_Pattern
    • It would be nice to eventually change Enumerable::_Pattern to take a generic
  • Hash#{assoc,rassoc,has_value?,key} now all take Hash::_Equals
  • Hash#compact returns an instance. There's no real good way to represent the return value for the function, but instance is more accurate than Hash[K, V]
  • Hash#deconstruct_keys now has an untyped argument, as it's ignored
  • Hash#{default,dig,delete,except,fetch,fetch_values,has_key?,slice,values_at} now all accept Hash::_Key, and any related blocks also do as well
  • Hash#default_proc now returns a (^(self, _Key) -> V)?. I'm not sure if this self is legal, or needs to be an instance (or even Hash[K, V], though I don't like that because it doesnt account for Hash subclasses)
  • Hash#default_proc= is similarly plagued with Hash#default_proc's concern. Also, the three branches were split up.
  • Hash#each{,_key,_value}'s blocks now returns void not untyped
  • Hash#flatten now explicitly handles a level of 0, and now accepts ints
  • Hash#{merge,merge!} now both accept hash. Unfortunately, for merge return type is Hash, but really it should be "instance[A | K, B | V]"
  • Hash#freeze has been added
  • Hash#replace now accepts hash
  • The alias pairs size/length, filter/select, and filter!/select! have been swapped, to more closely match documentation. (Other aliases which matched the documentation haven't been touched)
  • Hash#to_h's block form can now return _Pair[A, B]
  • Hash#{transform_keys{,!}} variants with hash arguments ({a: 1}.transform_keys(a: :b) #=> {b: 1}) have been added
  • Hash#initialize's proc now accepts an instance

sampersand avatar Oct 31 '25 03:10 sampersand

Pushed a new version which retains %a{implicitly-returns-nil} on []. removing that should be another PR.

sampersand avatar Nov 04 '25 02:11 sampersand