3

I'm newbie in Ruby (frankly, I've just started learning it for fun, without any future plans), and I've noticed strange behaviour of loops. I assume my problem comes from lacks in knowledge in the mechanics of Ruby.

boysNames = ["Martin", "Lucas", "John"]

#class only for one method. I know it's not absolutely correct, but huh I'm just learning Ruby
class Human
    def initialize(name)
        @name = name;
    end
   String name = ""

   def getName()
       puts @name;
    end
end

Array boys = []




#create objects
for x in boysNames
    tempBoy = Human.new(x)
    boys.push(tempBoy)
end

#output for class

puts "Method 1: for in loop \n"
for x in boys
    puts x.getName()
end


puts "\nMethod 2: manual array[var] \n"
boys[0].getName()
boys[1].getName()
boys[2].getName()

puts "\nMethod 3: .each do \n"
boys.each do |i|
    puts i.getName()
end

#output for Array

puts "Method 1: for in loop \n"

for x in boysNames
    puts x
end


puts "\nMethod 2: manual array[var] \n"
puts boysNames[0]
puts boysNames[1]
puts boysNames[2]

puts "\nMethod 3: .each do \n"
boysNames.each do |i|
    puts i
end


#loop through the boys array
puts "\nboys array:  \n"
for x in boys
    puts x
end

So my question is: Why when I loop through the array everything is fine, and when I loop through the class, my results are divided by newlines? Are there any "invisible" objects that I couldn't find? As you can see my last loop found only three objects with different places in the memory.

I will be pleased, if the answer contains explanation of "how it works".

Thank you in advance ;)

P.S. Output:

Method 1: for in loop 
Martin

Lucas

John


Method 2: manual array[var] 
Martin
Lucas
John

Method 3: .each do 
Martin

Lucas

John

Method 1: for in loop 
Martin
Lucas
John

Method 2: manual array[var] 
Martin
Lucas
John

Method 3: .each do 
Martin
Lucas
John

boys array:  
#<Human:0x007f2a586db788>
#<Human:0x007f2a586db648>
#<Human:0x007f2a586db5d0>

P.S.S. I'm using this as the Ruby interpreter/compiler (I heard that Ruby can also be compiled, so...)

Tomasz Durda
  • 134
  • 1
  • 9
  • 1
    Since you're learning, I'll point out some coding style you should be aware of. You don't need type annotations such as `String name`, just go for `name`. Same with `Array boys = []`, just use `boys = []`. And Ruby uses `snake_case` rather than `camelCase`. I always like checking community driven best practices repos such as [this](https://github.com/bbatsov/ruby-style-guide) to learn the language more idiomatically! Hope it helps. Have fun learning Ruby, it's a wonderful language! – Frank Kair Sep 16 '17 at 15:17
  • Thank you for helpful advices. `String name` lets me know what's type of data is 'name'. When it comes to code optimization I absolutely agree with you I wasn't aware of snake_case habit in Ruby. Good to know! – Tomasz Durda Sep 16 '17 at 15:26

1 Answers1

4

You're calling puts x.getName(), but getName() already has puts inside of it.

puts adds a newline to the end of each argument if there is not one already.

print does not add a new line.

(What is the difference between print and puts?)

Frank Kair
  • 451
  • 4
  • 13
  • Thank you. It's such a stupid mistake, that I flush when I think about it :D – Tomasz Durda Sep 16 '17 at 15:22
  • 3
    Actually, since "puts" always returns nil, the method `getName` returns nil. `puts nil` results in an empty string (from nil.to_s) plus a newline (added by `puts`). – steenslag Sep 16 '17 at 15:56