Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialSergio Cruz
15,550 PointsWhy is it that in the in_stock? method the stock_count is defined without an @?
I've been playing around with it and I know it doesn't work if you add the @ sign. So just a bit confused about this. If someone could shed some light as to why this is I'd appreciate it. Thanks!
3 Answers
Erik Nuber
20,629 PointsGiven this code...
def in_stock_report
puts "#{self.to_s} In Stock Report"
reportable = instances.select do |instance|
puts instance.stock_count #added this in and changed to a do/end
puts instance.inspect #also added this
instance.in_stock?
end
reportable.each do |item|
line = []
line.push("Item: #{item.attributes[:name]}")
line.push("Stock: #{item.stock_count}")
if item.attributes.include?(:size)
line.push("Size: #{item.attributes[:size]}")
end
puts line.join("\t")
end
puts "\n"
end
instance is one portion of the instances array. If you log out to screen the instance.stock_count like I did, you will see it is a number. If you inspect it , you will get back the class, location of the item in memory, the @attributes and @stock_count figure.
def stock_count
@stock_count ||= 0
end
def stock_count=(number)
@stock_count = number
end
def in_stock?
stock_count > 0
end
So in calling the in_stock? method, this checks the |instance| stock_count located at instance.stock_count and sends back true or false.
Confusing but hope that helps.
Jesse James
3,020 PointsSergio-
While I don't have an active account anymore so I can't see the particular video/example you're referencing the reason why adding the @ in front of stock_count doesn't work is that because @stock_count and stock_count are different types of variables. variables with @ in front of them are considered instance variables and whatever value they have is available anywhere within that particular instance of the class. Variables without this decoration like stock_count are local in scope and whatever value they are assigned is only available within that method/block.
Examples:
class Foo
@bar = "bar"
def fizz_buzz
buzz = "buzz"
end
def snafu
buzz
end
def fubar
@bar
end
end
In the above example, the method fubar
would work because @bar
is available to any method in this instance of Foo. However, snafu
wouldn't work (and would return an undefined local variable/method error) because the variable buzz
is local to the fizz_buzz
method.
Let me know if that helps, if not I'd be happy to try and explain it another way.
Hamilton Steele
8,717 PointsI think the reason that the stock_count variable in 'in_stock?' doesn't have an @ in front of it is because this...
def stock_count=(number)
@stock_count = number
end
...is used. This defines the method stock_count to either show what's in the instances variable @stock_count or (with the stock_count=(number)) to optionally assign it a number outside of its own class/module body. Thus the above method works exactly like an attr_accessor method you often put at the top of your class definitions. Try putting...
module Inventoryable
attr_accessor :stock_count
...at the top of the Inventoryable module and you'll still get everything working the same. So the reason this method...
def in_stock?
stock_count > 0
end
which just returns a boolean (true or false), doesn't need the @ in front of stock_count is because it is already associated to the @stock_count instance variable by the first method I posted above.
So here's where it gets a little confusing: if you use Eric Nuber's code to actually log out the instance.stock_count number inside of Nuber's instances.select method and make the stock_count local variable inside of the in_stock? method an instance variable like this...
def in_stock?
@stock_count > 0
end
...it actually makes the rest of the code work. Just putsing in the instances.stock_count in Nuber's expanded .select method calls the stock_count method and thus implicitly brings in the @stock_count instance variable instead of just using the original stock_count (sans @) method. Why putsing it in like that does this I have no idea, but if you wanted to use the @stock_count inside of the in_stock? method you would have to write your reportable line like this...
reportable = instances.select { |instance|
instance.stock_count
instance.in_stock?
}
...for it to still have the same function as the original line of code from the lesson.
I still don't think this fully explains the lack of an @ on the stock_count inside of the in_stock? method, and perhaps Nuber's code explains it more eloquently than I, but I think this does give (at least me) some understanding into how the .select enumerable works when used as a class method. Ruby always gets a little tricky to me when it comes to class methods so I wrote this answer to help me out as well and I'm not even sure I got all of it... Oh well. EDIT
Note, if my theory is correct, the only way to replace the stock_count=(number) method is to use the attr_accessor at the top of the Inventoryable module before anything else. Why this is the case, I'm not quite sure. But it will work if you do so.