3

Creating a class Square which has a constructor and a methiod to calculate the area of the square.

class Square
  def initialize(side)
    @side = side
  end

  def printArea
    @area = @side * @side
    puts "Area is: #{@area}"
  end
end

Creating 2 objects and adding them to an array

array = []
array << Square.new(4)
array << Square.new(10)

for i in array do
  array[i].printArea
end

How do i acces the objects inside the array? I get an error: no implicit conversion of Square into Integer.

1
  • You may also wish to push two objects in one line like: array.push Square.new(4), Square.new(10) Commented Nov 9, 2016 at 23:23

3 Answers 3

5

The other answers explained what to do to fix. I intend to explain WHY you got that error.

Pay attention to your code:

array = []
array << Square.new(4)
array << Square.new(10)

for i in array do
    array[i].printArea
end

You created an empty array and then inserted two Square instances in it, right?

Then, when you wrote for i in array do, what do you think i would contain? Of course i would contain the objects in array, i.e., i would contain the Square instances!!! You are saying it! i in array says i is the content of the positions of the array, not its index.

If you write

for i in array do
    p i.class
end

you'll see something like

Square
Square

It happens that Ruby only accepts integer as array indexes. Then, when you mentioned array[i] you were, in fact, saying something like array[Square], and Ruby was trying to see those Square object as integers, in order to use them as array indexes. And it was failing, of course, because there is no implicit conversion of Square into Integer, and this is the error you got.

I explain a bit more about this is this article of my blog.

Sign up to request clarification or add additional context in comments.

Comments

4

The for construct is hardly ever used in Ruby code. Instead you'd write:

array.each do |square|
  square.printArea
end

This iterates over the array and returns each square object, which is what your code does as well. i is not an index, it's an element in the array.

As a note, Ruby strongly encourages method names and variables to be of the form print_area.

A more Ruby form of this code looks like this:

class Square
  attr_accessor :side

  def initialize(side)
    @side = side.to_i
  end

  def area
    @side * @side
  end
end

squares = [ ]
squares << Square.new(10)
squares << Square.new(20)

squares.each do |square|
  puts 'Square of side %d has area %d' % [ square.side, square.area ]
end

This consolidates your display logic outside of the model where you should be focused on other things.

3 Comments

Thank you a lot, i can't believe it was that easy.I usually alternate between for and each, but i'll use each for now on. I'll write down your suggestions so i can further improve the way i code.
Would it better to write your area method as side*side employing the wrapper?
Matter of preference. @side * @side is marginally faster, but that's irrelevant for most cases. side * side would work just the same.
3

I believe you want to say:

array.each do |sq| 
  sq.printArea 
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.