If you do not explicitly return something from a method (or next something from a block), then the last expression evaluated becomes the return value of the method (block, lambda, module definition body, class definition body).
Since you don't explicitly return from AddItem, the last expression that is evaluated will be the return value. The last expression that is evaluated, is:
@item.each do |x|
if x[:name] == item
x
end
end
In other words, the return value of AddItem will be the return value of @item.each. According to the documentation of Array#each, the return value is simply the Array that each was called on. (Note that this is actually not specific to Array#each, it is the general contract of each, so this is true for all implementations of each.)
This makes sense: the purpose of each is to execute a side-effect for each element of the collection. It doesn't really have a useful return value. So, the two sensible return values would be nil and self, and the library designers chose self. (Presumably, to allow for method chaining, I don't know.)
The next problem is that your block doesn't actually do anything. Remember, the purpose of each is to execute a side-effect for every element, but your block doesn't have any side-effects! If you wanted to do anything useful, you would need a side-effect (such as modifying an outer variable binding):
def AddItem(item)
return_value = nil
@item.each do |el|
return_value = el if el[:name] == item
end
return_value
end
Alternatively, you could return the found item directly:
def AddItem(item)
@item.each do |el|
return el if el[:name] == item
end
end
But really, what you want to do is find the first matching item:
def AddItem(item)
@item.find {|el| el[:name] == item }
end
Note that there a lot of confusing things about your code:
- You have two methods that are both named
CheckSomething, but the two methods do completely different things.
- Also, neither of the two methods actually checks something, one method prints something and the other finds something.
- Your method
AddItem does exactly the same thing as CheckPrice, but it is named completely different. Also, it does things in a completely different way. (Which is why it doesn't work.)
- Again, naming:
AddItem doesn't actually add anything.
- Also, what is that
i = 0 doing in AddItem?
- The class is named
Action, which is a very generic name and doesn't tell much about what it's doing.
- It doesn't seem to do much of an action, though.
- When you instantiate
Action, you assign it to a variable named customer. However, it doesn't appear that it doesn't do much "customery" things either.
- In the end, you put the customer into a basket. Just imagine, this were a real-world supermarket. Is that how it works in the real world?
And one last remark: the standard Ruby Community Coding Style is to use snake_case for methods, local variables, instance variables, class variables, and global variables. PascalCase is for constants that point to classes or modules, SCREAMING_SNAKE_CASE for other constants. We don't use camelCase.