0

I don't understand why this isn't working. I've only been programming in ruby for a few months now but I feel like I at least know the basics, and this seems to me like it is basic. Why wont this each iterator capitalize each element in the array? I feel like this should work, it feels like a no brainer. I feel like I have done things like this a million times before and they worked as intended, but for some reason this will not work? Is it something I am misunderstanding about how arrays work? I felt like that was the case, but when I do puts array[0].capitalize it capitalizes the element as intended. Why wont the each iterator do the same? This is absolutely driving me nuts and is basically standing in the way of a larger project where I do something similar.

array = []

array << "apple"
array << "banana"
array << "peach"

array.each do |x|

    x.capitalize

end

puts array #returns all non-capitalized words
puts array[0].capitalize #returns Apple...wtf why doesn't for loop work then?!?
puts "apple".capitalize #returns Apple as expected
pjs
  • 18,696
  • 4
  • 27
  • 56
A Dragon
  • 13
  • 2
  • If you also used `puts` inside of the loop to show the value of `x`, you would see that `x` doesn't change with the code that you're using. Example: `puts x; puts x.capitalize; puts x`. –  May 19 '14 at 22:12

6 Answers6

4

The problem is the method you're calling. capitalize makes no modification to the string, but rather returns a new string. You want to call capitalize!:

x = "apple"
puts x.capitalize # "Apple"
puts x # "apple"
x.capitalize!
puts x # "Apple"

Another option would be to create a new array using collect like so:

array = ["apple"]
new_array = array.collect do |x|
  x.capitalize
end
puts array # ["apple"]
puts new_array # ["Apple"]
Charlie
  • 7,181
  • 1
  • 35
  • 49
  • 1
    Besides using `captailize!`, you could also just assign `x = x.capitalize` too, which is also a more common method to do this in many other languages. –  May 19 '14 at 22:09
  • 2
    It's true (being a reformed Java guy, it makes more sense :) ), but be careful, the assignment will not work within the each block to update the array. You get into [pass-by-value territory](http://stackoverflow.com/questions/1872110/is-ruby-pass-by-reference-or-by-value). – Charlie May 19 '14 at 22:19
0

When you do

x.capitalize

it returns a copy of the string. To do what you want, you should change that line to

x.capitalize!

which will modify the existing element, instead of returning a copy.

Waynn Lue
  • 11,344
  • 8
  • 51
  • 76
0

capitalize creates anew string and do not modify starting string. Use capitalize! instead capitalize or map! instead of each.

BroiSatse
  • 44,031
  • 8
  • 61
  • 86
0

I just did a quick test in irb and array.map will create a new array with the idividuals capitalized. array.each will iterate through and do whatever you want to copies of the values in the array, but not change the array. If you wanted to change the array I would try

array = array.map do |x|
  x.capitalize
end
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
Jimi Kimble
  • 504
  • 5
  • 10
0

And here is a slightly more advance ruby way of doing it:

array.map! &:capitalize
hirolau
  • 13,451
  • 8
  • 35
  • 47
-1

The best thing you can do is to go to irb in your terminal and simple put a puts inside your loop to see what is actually going on. There, you can see that each time the output is capitalized and that's correct, but the each method does nothing to the array. It just iterates for each element. That's the reason that the final output is non-capitalized elements.

array = []

array << "apple"
array << "banana"
array << "peach"

array.each do |x|

  puts x.capitalize

end

Printed values in irb:

Apple
Banana
Peach

but the actual returned value is this => ["apple", "banana", "peach"]

appostolis
  • 2,294
  • 2
  • 13
  • 15
  • Returned values? There isn't a single method call in your example(`Array#[], Array#<<, Array#each, String#capitalize`) that returns 3 strings on 3 separate lines. Final output? I don't think so. – 7stud May 19 '14 at 22:38
  • Sorry, you're right. What I meant was if you actually put that code in irb, these values are going to be returned. I will update my answer. Thanks. – appostolis May 19 '14 at 22:40
  • `if you actually put that code in irb, these values are going to be returned` Sorry wrong again: irb shows both output and returned values. You have to know which is which. The best bet is not use irb at all and then you won't be confused about which is which. – 7stud May 19 '14 at 22:43
  • Definitely not the best bet. First of all, there is a reason the symbol => exists, in order to not be confused which is which. – appostolis May 19 '14 at 22:47