Extend and Include4:14 with Jason Seifer
In this video, we learn a little trick with extending and including something at the same time.
module Inventoryable def self.included(klass) klass.extend(ClassMethods) end module ClassMethods def create(attributes) object = new(attributes) instances.push(object) return object end def instances @instances ||=  end end def stock_count @stock_count ||= 0 end def stock_count=(number) @stock_count = number end def in_stock? stock_count > 0 end end class Shirt include Inventoryable attr_accessor :attributes def initialize(attributes) @attributes = attributes end end
When we last left off, 0:00 we had just added the stock_count methods to our inventoriable class. 0:01 Now what we're gonna do is take the same pattern that we used in the tracking 0:07 module to do this create and return instances. 0:11 So, we're gonna do this in a tricky little way. 0:17 We're gonna do it inside of another module, inside of Inventoryable. 0:20 We're gonna call this ClassMethods 0:24 because these are going to go on the class of what we want inventoried. 0:28 So let's go ahead and write our create method. 0:34 And that's going to take an attributes hash. 0:40 And this is gonna be very very similar to what we did here. 0:45 We're gonna initialize an object, push it to instances and return the object. 0:48 And the only difference between this and 1:06 the create method in the tracking module is that we're 1:09 taking an attributes hash instead of a single item, which was a string. 1:12 So now we'll be able to say, shirt.create. 1:18 But we still need to write the instances method. 1:22 Very very easy, we just say, instances conditionally equals a new array. 1:26 And now we can push on to that. 1:32 So, we've got this class methods module. 1:36 And what we need to do 1:41 is extend our shirt class with it in order to get that to work. 1:43 We can say extend Inventoryable::ClassMethods, 1:49 and now we'll get the create method as well. 1:55 So we can say the same thing here, Shirt.create, 2:02 Shirt.create, and this shouldn't affect our code at all, and it should work. 2:06 Let's go ahead and run it and see what happens. 2:13 Okay, it looks like we got what we were expecting. 2:17 We still have these specific shirts in stock. 2:19 New. 2:23 Take all of these out here, and let's go ahead and 2:24 just take a look at Shirt.instances. 2:28 Just to make sure everything is in there. 2:34 So I'm gonna clear my screen and run that again. 2:36 And we can see we have these two instances of the shirt 2:41 class just like we expected to by having this create method. 2:46 So this is kind of cumbersome to keep doing each time. 2:53 Extend and include. 2:57 And, there's a pattern that a lot of Ruby programmers use when we do something 2:59 like this. 3:03 Now, remember this included method that we had access to before? 3:05 Where we sent in the class that's been included? 3:10 We could take advantage of that inside of our Inventoryable module as well. 3:14 So when we say that this module has been included into this class, 3:20 we can get really tricky and just tell the class to extend itself 3:27 with the class methods that are inside of this module. 3:33 Now, if we take this out, everything should still work. 3:39 I clear my screen and run this again. 3:44 We still get these shirts and the create method works fine, 3:48 even though we're only specifically including one module. 3:52 So when we include it, the class gets sent in, which in this case is the shirt class. 3:57 So by calling shirt.extend ClassMethods, it's the same thing 4:02 as if we extended it with the Inventoryable class methods ourselves. 4:08
You need to sign up for Treehouse in order to download course files.Sign up