Skip to content

Commit

Permalink
Improve Array.wrap in ActiveSupport (#683)
Browse files Browse the repository at this point in the history
* Improve Array.wrap in ActiveSupport

* move signature to more generic file
  • Loading branch information
nickjer authored Oct 7, 2024
1 parent f885365 commit ddba0c6
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 39 deletions.
5 changes: 5 additions & 0 deletions gems/activesupport/6.0/_test/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,8 @@ class TestAttrInternal
"Matz".presence_in("Matzuyama")&.in?(%w[Yukihiro Matz Matsumoto])
ActiveSupport::TimeZone['Asia/Tokyo'].to_s
Time.find_zone(Object.name)

Array.wrap(nil)
Array.wrap([1, 2, 3])
Array.wrap("hello")
Array.wrap({a: 1, b: 2})
39 changes: 0 additions & 39 deletions gems/activesupport/6.0/activesupport-generated.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -2138,45 +2138,6 @@ class Array[unchecked out Elem]
def inquiry: () -> ActiveSupport::ArrayInquirer[Elem]
end

class Array[unchecked out Elem]
# Wraps its argument in an array unless it is already an array (or array-like).
#
# Specifically:
#
# * If the argument is +nil+ an empty array is returned.
# * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
# * Otherwise, returns an array with the argument as its single element.
#
# Array.wrap(nil) # => []
# Array.wrap([1, 2, 3]) # => [1, 2, 3]
# Array.wrap(0) # => [0]
#
# This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
#
# * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
# moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
# an array with the argument as its single element right away.
# * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
# raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
# * It does not call +to_a+ on the argument, if the argument does not respond to +to_ary+
# it returns an array with the argument as its single element.
#
# The last point is easily explained with some enumerables:
#
# Array(foo: :bar) # => [[:foo, :bar]]
# Array.wrap(foo: :bar) # => [{:foo=>:bar}]
#
# There's also a related idiom that uses the splat operator:
#
# [*object]
#
# which returns <tt>[]</tt> for +nil+, but calls to <tt>Array(object)</tt> otherwise.
#
# The differences with <tt>Kernel#Array</tt> explained above
# apply to the rest of <tt>object</tt>s.
def self.wrap: (untyped object) -> untyped
end

module ActiveSupport
module BigDecimalWithDefaultFormat
# nodoc:
Expand Down
41 changes: 41 additions & 0 deletions gems/activesupport/6.0/activesupport.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,47 @@ class String
def foreign_key: (?boolish separate_class_name_and_id_with_underscore) -> String
end

class Array[unchecked out Elem]
# Wraps its argument in an array unless it is already an array (or array-like).
#
# Specifically:
#
# * If the argument is +nil+ an empty array is returned.
# * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
# * Otherwise, returns an array with the argument as its single element.
#
# Array.wrap(nil) # => []
# Array.wrap([1, 2, 3]) # => [1, 2, 3]
# Array.wrap(0) # => [0]
#
# This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
#
# * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
# moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
# an array with the argument as its single element right away.
# * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
# raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
# * It does not call +to_a+ on the argument, if the argument does not respond to +to_ary+
# it returns an array with the argument as its single element.
#
# The last point is easily explained with some enumerables:
#
# Array(foo: :bar) # => [[:foo, :bar]]
# Array.wrap(foo: :bar) # => [{:foo=>:bar}]
#
# There's also a related idiom that uses the splat operator:
#
# [*object]
#
# which returns <tt>[]</tt> for +nil+, but calls to <tt>Array(object)</tt> otherwise.
#
# The differences with <tt>Kernel#Array</tt> explained above
# apply to the rest of <tt>object</tt>s.
def self.wrap: (nil) -> []
| [T] (_ToAry[T] array_like) -> Array[T]
| [T] (T ele) -> [T]
end

module ActiveSupport
# Rescuable module adds support for easier exception handling.
module Rescuable
Expand Down
5 changes: 5 additions & 0 deletions gems/activesupport/7.0/_test/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,8 @@
ActiveSupport::TimeZone['Asia/Tokyo'].to_s
Time.find_zone(Object.name)
Time.zone.now.to_fs

Array.wrap(nil)
Array.wrap([1, 2, 3])
Array.wrap("hello")
Array.wrap({a: 1, b: 2})

0 comments on commit ddba0c6

Please sign in to comment.