Если вы не явно return
что-то из метода (или next
что-то из блока), тогда последнее вычисленное выражение становится возвращаемым значением метода(блок, лямбда, тело определения модуля, тело определения класса).
Поскольку вы не явно return
из AddItem
, последнее вычисленное выражение будет возвращаемымстоимость. Последнее выражение, которое оценивается, это:
@item.each do |x|
if x[:name] == item
x
end
end
Другими словами, возвращаемое значение AddItem
будет возвращаемым значением @item.each
. Согласно документации Array#each
, возвращаемое значение - это просто Array
, к которому был вызван each
. (Обратите внимание, что это на самом деле не относится к Array#each
, это общий контракт из each
, так что это верно для всех реализаций each
.)
Это имеет смысл: цель each
- выполнить побочный эффект для каждого элемента коллекции. На самом деле не имеет полезного возвращаемого значения. Итак, два разумных возвращаемых значения будут nil
и self
, и разработчики библиотеки выбрали self
. (Предположительно, чтобы учесть цепочку методов, я не знаю.)
Следующая проблема в том, что ваш блок на самом деле ничего не делает. Помните, что цель each
- выполнить побочный эффект для каждого элемента, но у вашего блока нет побочных эффектов! Если вы хотите сделать что-нибудь полезное, вам потребуется побочный эффект (например, изменение привязки внешней переменной):
def AddItem(item)
return_value = nil
@item.each do |el|
return_value = el if el[:name] == item
end
return_value
end
В качестве альтернативы, вы можете return
найти найденный элемент напрямую:
def AddItem(item)
@item.each do |el|
return el if el[:name] == item
end
end
Но на самом деле вам нужно найти первый соответствующий элемент:
def AddItem(item)
@item.find {|el| el[:name] == item }
end
Обратите внимание, что в вашем коде много запутанных вещей:
- У вас есть два метода с именами
CheckSomething
, но оба метода делают совершенно разные вещи. - Кроме того, ни один из двух методов на самом деле не проверяет что-то, один метод что-то печатает, а другой что-то находит.
- Ваш метод
AddItem
делает то же самое, что и CheckPrice
, но он назван совершенно по-другому. Кроме того, это делает вещи совершенно по-другому. (Вот почему это не работает.) - Опять же, имя:
AddItem
фактически ничего не добавляет. - Кроме того, что это
i = 0
делает в AddItem
? - Класс называется
Action
, что является очень общим именем и мало что говорит о том, что он делает. - Кажется, он не выполняет большую часть действия,хотя.
- Когда вы создаете экземпляр
Action
, вы назначаете его переменной с именем customer
. Однако, похоже, что он не делает много «привычных» вещей. - В конце концов, вы кладете клиента в корзину. Представьте себе, это был настоящий супермаркет. Так ли это в реальном мире?
И последнее замечание: стандартный стиль кодирования сообщества Ruby состоит в использовании snake_case
для методов, локальных переменных, переменных экземпляра, переменных класса и глобальныхпеременные. PascalCase
для констант, которые указывают на классы или модули, SCREAMING_SNAKE_CASE
для других констант. Мы не используем camelCase
.