For example:
a = [1,2,3,4,5]
a.delete_if { |x| x > 3 }
is equivalent to:
a = [1,2,3,4,5]
a.delete_if.each.each.each.each { |x| x > 3 }
I know a.delete_if
returns an enumerator. But how does it know it should delete object when the ea开发者_运维问答ch
block returns true? How to implement delete_if
by hand(and in Ruby)?
You can take a look at the Rubinius source code: enumerable module
Here an example of the reject method:
def reject
return to_enum(:reject) unless block_given?
ary = []
each do |o|
ary << o unless yield(o)
end
ary
end
In the implementation of delete_if
, the code can verify the value returned from yield
to decide whether or not to delete the given entry from the array.
You can read Implementing Iterators in the Programming Ruby guide for more details, but it would looks something like:
class Array
def delete_if
reject { |i| yield i }.to_a
end
end
The above uses yield
to pass each item in the array to the block associated with the call to delete_if
, and implicitly returns the value of the yield
to the outer reject
call.
精彩评论