From: "Jesús Gabriel y Galán" Date: 2010-03-26T16:20:36+09:00 Subject: Re: Creating a gsub! method for Arrays On Fri, Mar 26, 2010 at 3:49 AM, Derek Cannon wrote: > I'm new to Ruby. I'm trying to add a method to the Array class that adds > the functionality of gsub! to arrays. > > Looking around the internet, I found a keyword know as detect { } which > allows me to get the elements of the array. Testing it, I find the > following code: > > class Array >  def test >    detect { |x| puts x} >  end > end > > ...prints out all the elements in the array. However, when I try: > > class Array >  def gsub!(pattern, replacement) >    detect { |x| >      x.gsub!(pattern, replacement) >      } >  end > end > > ...the result is only a modification of the first element in the array. > For example, the following code: > > x = ["Hello", "there", "world", "how", "are", "you?"] > x.gsub!(/[aeiou]/, "_") > puts x > > outputs only: > H_ll_ > there > world > how > are > you? > > Does anyone know what I'm doing wrong? http://ruby-doc.org/core/classes/Enumerable.html#M003123 detect (Iprefer find) will iterate the enumerable yielding each element to the block until one returns true, and will return that element: [1,2,3,4].find {|i| i > 2} # => 3 In the first example you are calling puts in the block which always returns null, so the detect never stops its iteration and it goes through all the elements. In your "real" code, you use gsub! in the block. gsub! returns the modified string if it changed it, or nil if no replacement was made, so you saw in your example that was stopping after the first element, because it managed to change it with the replacement. As you have discovered, you should use each to iterate through the full enumerable. Jesus.