2013-09-29 4 views
1

У меня есть класс Product, который содержит name, price и count.Вопросы о массивах в рубине

В другом классе Shop (включая класс Product), я инициализирую пустым массивом. Затем добавьте product к этому массиву, используя способ push.

Проблема происходит с методом to_s из в Shop класса:

def to_s 
    string = "Products in the shop:\n" 
    @list.each do |list| 
    #### how can i get access to the attributes of product like @list.name or something like that ? I have tried loads of different methods but i cant get access to my attributes. (the array doesnt recognize the product class) 
    puts @list.name 
    end 

Если я создаю Product без использования Array, я могу получить доступ к атрибутам - Я предполагаю, что проблема возникает из-за Array. ..

+1

Сначала покажите нам класс, который вы создали, затем задайте нам вопрос, указывающий на путаницы, которые у вас возникли. –

+0

Является ли «конец» в вашем кодовом конце «каждым» блоком или концом 'def блок to_s'? –

+0

Кто бы это ни редактировал, возможно, вы изменили вопрос OP. Обратите внимание на мой комментарий выше о несоответствии 'end'. =) –

ответ

3

Итак, в первую очередь, ваши блоки не совпадают.

Вы хотите:

def to_s 
    string = "Products in the shop:\n" 
    @list.each do |item| 
    string << item.name + "\n"  # not @list.name! @list is an Array. item is an element of your list. 
    end 
    string # you could also say: return string 
end 

Вы не хотите использовать puts потому что пришлет его на консоль - когда вы пытаетесь сохранить его в строке под названием string. Вы хотите, чтобы вы тоже вернули это.

Вам не нужно называть ваш параметр блока item. Вы могли бы называть его list, но это было бы странно, потому что у вас есть другая переменная, называемая @list, а параметр block не является списком вообще - всего лишь элемент из массива.

Обратите внимание, что это не самый эффективный способ выполнить это. Предпочтительным способом является следующим образом:

def to_s 
    products_list = @list.map do |item| 
    item.name 
    end 
    "Products in the shop:\n" + products_list.join("\n") 
end 
+0

Вы также можете написать предложенную вами альтернативу: 'def to_s()« Продукты в магазине: \ n "+ @ list.map (&: name) .join (" \ n ") end' –

+0

кому нужна двоеточие после 'def to_s()'? Кроме того, parens не являются обязательными.=) –

+0

Если вы удалите парнеры, вам нужно будет вставить один ';' после 'to_s' и еще до' end'. Оба работают. –

2

Каждый элемент в @list будет уступил each блока в качестве list.

Предполагая, что @list является Перечислимым с объектами Product, вы должны быть в состоянии сделать list.name, чтобы получить атрибут имени внутри блока.

1

Я предпочитаю map и join над each и << (только предпочтение), а фигурные скобки ({}) над do end, потому что я хотел бы подразумевать возвращаемое значение имеет важное значение с помощью брекетов, а do end блока там сбоку эффекты, например

def to_s 
    "Products in the shop:\n" << @list.map{|item| item.name}.join("\n") 
end 

Я также не хотел бы использовать puts потому to_s должна возвращать строку, не выводит строку.

Смежные вопросы