2016-11-09 3 views
3

Создание квадрата класса, в котором есть конструктор и metiod для вычисления площади квадрата.Ruby array of objects

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

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

Создание 2 объектов и добавление их в массив

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

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

Как я Acces объекты внутри массива? Я получаю сообщение об ошибке: неявное преобразование квадрата в целое число.

+0

Вы также можете нажать два объекта в одной строке: 'array.push Square.new (4), Square.new (10) ' –

ответ

4

Конструкция for почти никогда не используется в коде Ruby. Вместо этого вы бы написать:

array.each do |square| 
    square.printArea 
end 

This перебирает массив и возвращает каждый square объект, который является тем, что делает ваш код, а также. i не является индексом, это элемент в массиве.

В качестве примечания, Ruby настоятельно рекомендует имена и переменные метода иметь форму print_area.

Более рубин форма этого кода выглядит следующим образом:

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 

Это консолидирует ваш дисплей логика за пределами модели где вы должны быть сосредоточены на других вещах.

+0

Большое спасибо, я не могу поверить, что это было так просто . Я обычно чередую между и для каждого, но я буду использовать каждый на данный момент. Я напишу ваши предложения, чтобы я мог улучшить способ кодирования. –

+0

Было бы лучше написать ваш метод 'area' как' side * side', используя обертку? –

+0

Вопрос о предпочтении. '@side * @ side' немного быстрее, но в большинстве случаев это не имеет значения. 'side * side' будет работать одинаково. – tadman

3

Я считаю, что вы хотите сказать:

array.each do |sq| 
    sq.printArea 
end 
5

Другие ответы объяснил, что нужно сделать, чтобы исправить. Я намерен объяснить, ПОЧЕМУ вы получили эту ошибку.

Обратите внимание на код:

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

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

Вы создали пустой массив, а затем вставить две квадратные экземпляры в нем, не так ли?

Тогда, когда вы написали for i in array do, как вы думаете, i будет содержать? Конечно, i будет содержать объекты в array, то есть i будет содержать экземпляры Square !!! Вы это говорите! i in array говорит, что i - это содержание позиций массива, а не его индекс.

Если вы пишете

for i in array do 
    p i.class 
end 

вы увидите что-то вроде

Square 
Square 

Случается, что рубин принимает только целое число в качестве индексов массива. Затем, когда вы упомянули array[i], вы были, по сути, что-то вроде array[Square], и Ruby пытался увидеть эти квадратные объекты целыми числами, чтобы использовать их в качестве индексов массива. И это, конечно, терпело неудачу, потому что есть no implicit conversion of Square into Integer, и это ошибка, которую вы получили.

Я объясню немного больше об этом this article моего блога.