`Enumerable#{one?,none?,all?,any?} to take pattern argument [Ruby2.5]

parent 421819dc
......@@ -451,20 +451,30 @@ module Enumerable
##
# call-seq:
# enum.none? [{ |obj| block }] -> true or false
# enum.none?(pattern) -> true or false
#
# Passes each element of the collection to the given block. The method
# returns <code>true</code> if the block never returns <code>true</code>
# for all elements. If the block is not given, <code>none?</code> will return
# <code>true</code> only if none of the collection members is true.
#
# If a pattern is supplied instead, the method returns whether
# <code>pattern === element</code> for none of the collection members.
#
# %w(ant bear cat).none? { |word| word.length == 5 } #=> true
# %w(ant bear cat).none? { |word| word.length >= 4 } #=> false
# %w{ant bear cat}.none?(/d/) #=> true
# [1, 3.14, 42].none?(Float) #=> false
# [].none? #=> true
# [nil, false].none? #=> true
# [nil, true].none? #=> false
def none?(&block)
if block
def none?(pat=NONE, &block)
if pat != NONE
self.each do |*val|
return false if pat === val.__svalue
end
elsif block
self.each do |*val|
return false if block.call(*val)
end
......@@ -479,6 +489,7 @@ module Enumerable
##
# call-seq:
# enum.one? [{ |obj| block }] -> true or false
# enum.one?(pattern) -> true or false
#
# Passes each element of the collection to the given block. The method
# returns <code>true</code> if the block returns <code>true</code>
......@@ -486,16 +497,26 @@ module Enumerable
# <code>true</code> only if exactly one of the collection members is
# true.
#
# If a pattern is supplied instead, the method returns whether
# <code>pattern === element</code> for exactly one collection member.
#
# %w(ant bear cat).one? { |word| word.length == 4 } #=> true
# %w(ant bear cat).one? { |word| word.length > 4 } #=> false
# %w(ant bear cat).one? { |word| word.length < 4 } #=> false
# %w{ant bear cat}.one?(/t/) #=> false
# [nil, true, 99].one? #=> false
# [nil, true, false].one? #=> true
#
# [ nil, true, 99 ].one?(Integer) #=> true
# [].one? #=> false
def one?(&block)
def one?(pat=NONE, &block)
count = 0
if block
if pat!=NONE
self.each do |*val|
count += 1 if pat === val.__svalue
return false if count > 1
end
elsif block
self.each do |*val|
count += 1 if block.call(*val)
return false if count > 1
......@@ -510,6 +531,71 @@ module Enumerable
count == 1 ? true : false
end
# ISO 15.3.2.2.1
# call-seq:
# enum.all? [{ |obj| block } ] -> true or false
# enum.all?(pattern) -> true or false
#
# Passes each element of the collection to the given block. The method
# returns <code>true</code> if the block never returns
# <code>false</code> or <code>nil</code>. If the block is not given,
# Ruby adds an implicit block of <code>{ |obj| obj }</code> which will
# cause #all? to return +true+ when none of the collection members are
# +false+ or +nil+.
#
# If a pattern is supplied instead, the method returns whether
# <code>pattern === element</code> for every collection member.
#
# %w[ant bear cat].all? { |word| word.length >= 3 } #=> true
# %w[ant bear cat].all? { |word| word.length >= 4 } #=> false
# %w[ant bear cat].all?(/t/) #=> false
# [1, 2i, 3.14].all?(Numeric) #=> true
# [nil, true, 99].all? #=> false
#
def all?(pat=NONE, &block)
if pat != NONE
self.each{|*val| return false unless pat === val.__svalue}
elsif block
self.each{|*val| return false unless block.call(*val)}
else
self.each{|*val| return false unless val.__svalue}
end
true
end
# ISO 15.3.2.2.2
# call-seq:
# enum.any? [{ |obj| block }] -> true or false
# enum.any?(pattern) -> true or false
#
# Passes each element of the collection to the given block. The method
# returns <code>true</code> if the block ever returns a value other
# than <code>false</code> or <code>nil</code>. If the block is not
# given, Ruby adds an implicit block of <code>{ |obj| obj }</code> that
# will cause #any? to return +true+ if at least one of the collection
# members is not +false+ or +nil+.
#
# If a pattern is supplied instead, the method returns whether
# <code>pattern === element</code> for any collection member.
#
# %w[ant bear cat].any? { |word| word.length >= 3 } #=> true
# %w[ant bear cat].any? { |word| word.length >= 4 } #=> true
# %w[ant bear cat].any?(/d/) #=> false
# [nil, true, 99].any?(Integer) #=> true
# [nil, true, 99].any? #=> true
# [].any? #=> false
#
def any?(pat=NONE, &block)
if pat != NONE
self.each{|*val| return true if pat === val.__svalue}
elsif block
self.each{|*val| return true if block.call(*val)}
else
self.each{|*val| return true if val.__svalue}
end
false
end
##
# call-seq:
# enum.each_with_object(obj) { |(*args), memo_obj| ... } -> obj
......
......@@ -100,6 +100,7 @@ end
assert("Enumerable#none?") do
assert_true %w(ant bear cat).none? { |word| word.length == 5 }
assert_false %w(ant bear cat).none? { |word| word.length >= 4 }
assert_false [1, 3.14, 42].none?(Float)
assert_true [].none?
assert_true [nil, false].none?
assert_false [nil, true].none?
......@@ -109,8 +110,21 @@ assert("Enumerable#one?") do
assert_true %w(ant bear cat).one? { |word| word.length == 4 }
assert_false %w(ant bear cat).one? { |word| word.length > 4 }
assert_false %w(ant bear cat).one? { |word| word.length < 4 }
assert_true [1, 3.14, 42].one?(Float)
assert_false [nil, true, 99].one?
assert_true [nil, true, false].one?
assert_true [ nil, true, 99 ].one?(Integer)
assert_false [].one?
end
assert("Enumerable#all? (enhancement)") do
assert_false [1, 2, 3.14].all?(Integer)
assert_true [1, 2, 3.14].all?(Numeric)
end
assert("Enumerable#any? (enhancement)") do
assert_false [1, 2, 3].all?(Float)
assert_true [nil, true, 99].any?(Integer)
end
assert("Enumerable#each_with_object") do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment