1 00:00:00,000 --> 00:00:08,511 (Theme Music) 2 00:00:13,426 --> 00:00:16,543 This talk is about how Bundler works 3 00:00:17,986 --> 00:00:21,129 How does Bundler work? 4 00:00:21,804 --> 00:00:24,780 This is an interesting question. 5 00:00:25,335 --> 00:00:27,576 We'll talk about it for a while. 6 00:00:28,516 --> 00:00:29,691 This talk is a brief history of 7 00:00:31,845 --> 00:00:35,845 dependency management in Ruby, 8 99:59:59,999 --> 99:59:59,999 a discussion of how libraries and 9 99:59:59,999 --> 99:59:59,999 shared code works now and in the past 10 99:59:59,999 --> 99:59:59,999 because how it works now is directly a result 11 99:59:59,999 --> 99:59:59,999 of how it used to work in the past 12 99:59:59,999 --> 99:59:59,999 and trying to fix problems that happened then. 13 99:59:59,999 --> 99:59:59,999 Before we get started, let me introduce myself: 14 99:59:59,999 --> 99:59:59,999 My name is Andre Arko, I'm @indirect on all social media 15 99:59:59,999 --> 99:59:59,999 that's my avatar, maybe you've seen me on 16 99:59:59,999 --> 99:59:59,999 a webpage somewhere. As my day job 17 99:59:59,999 --> 99:59:59,999 I work at Cloud City Development doing 18 99:59:59,999 --> 99:59:59,999 Ruby, Rails, Ember, and web consulting. 19 99:59:59,999 --> 99:59:59,999 We do web and mobile development 20 99:59:59,999 --> 99:59:59,999 and I mostly do architectural consulting 21 99:59:59,999 --> 99:59:59,999 and Senior Developer pairing and training. 22 99:59:59,999 --> 99:59:59,999 Talk to me if you're company is interested. 23 99:59:59,999 --> 99:59:59,999 I also founded Ruby Together, a non-profit, 24 99:59:59,999 --> 99:59:59,999 it's like npm incorporate without the venture capital. 25 99:59:59,999 --> 99:59:59,999 Ruby Together is a trade association that 26 99:59:59,999 --> 99:59:59,999 takes money from companies and people who 27 99:59:59,999 --> 99:59:59,999 use Ruby and Bundler and RubyGems and all 28 99:59:59,999 --> 99:59:59,999 of the public infrastructure that Rubyists use 29 99:59:59,999 --> 99:59:59,999 and pays for developers to work on that 30 99:59:59,999 --> 99:59:59,999 so that RubyGems.org stays up, and so 31 99:59:59,999 --> 99:59:59,999 people can have gems, which is pretty cool. 32 99:59:59,999 --> 99:59:59,999 As part of my work for Ruby Together I work as 33 99:59:59,999 --> 99:59:59,999 lead of the Bundler team. I've been working on 34 99:59:59,999 --> 99:59:59,999 Bundler since before 1.0 came out, and I've 35 99:59:59,999 --> 99:59:59,999 been team lead for the last four years. 36 99:59:59,999 --> 99:59:59,999 Using Ruby code written by other developers, 37 99:59:59,999 --> 99:59:59,999 nowadays this is actually really easy, 38 99:59:59,999 --> 99:59:59,999 you add a line to your Gemfile, 39 99:59:59,999 --> 99:59:59,999 you go to your terminal and run 40 99:59:59,999 --> 99:59:59,999 bundle install, and you start using it. 41 99:59:59,999 --> 99:59:59,999 Pretty cool, that's really easy. 42 99:59:59,999 --> 99:59:59,999 The thing that I've noticed, talking to people 43 99:59:59,999 --> 99:59:59,999 who use Bundler and think it's awesome 44 99:59:59,999 --> 99:59:59,999 is that, it's not actually clear what just happened. 45 99:59:59,999 --> 99:59:59,999 Based on the text printed out by bundle install 46 99:59:59,999 --> 99:59:59,999 it seems like something got downloaded 47 99:59:59,999 --> 99:59:59,999 and something got installed, but it's not clear. 48 99:59:59,999 --> 99:59:59,999 It's not clear what got downloaded or 49 99:59:59,999 --> 99:59:59,999 installed, or where it happened. 50 99:59:59,999 --> 99:59:59,999 What exactly happened there? 51 99:59:59,999 --> 99:59:59,999 Nobody is really sure. 52 99:59:59,999 --> 99:59:59,999 How does just putting a line in your Gemfile 53 99:59:59,999 --> 99:59:59,999 mean you can just start using somebody else's code? 54 99:59:59,999 --> 99:59:59,999 To explain that, we'll need a little bit of history. 55 99:59:59,999 --> 99:59:59,999 We're going to back in a time. 56 99:59:59,999 --> 99:59:59,999 I'm going to give you a tour from the beginning of sharing 57 99:59:59,999 --> 99:59:59,999 code in Ruby up until now. 58 99:59:59,999 --> 99:59:59,999 And hopefully by the end of it you'll understand 59 99:59:59,999 --> 99:59:59,999 why things work the way they do now. 60 99:59:59,999 --> 99:59:59,999 I'm going to start talking about require, 61 99:59:59,999 --> 99:59:59,999 which came with the very first version of Ruby ever, in 1994. 62 99:59:59,999 --> 99:59:59,999 And then talk about setup.rb from 2000, 63 99:59:59,999 --> 99:59:59,999 and then RubyGems from 2003, and Bundler from 2009. 64 99:59:59,999 --> 99:59:59,999 And that's what we're still using today. 65 99:59:59,999 --> 99:59:59,999 The require method has been around since 66 99:59:59,999 --> 99:59:59,999 1994, with the very first version of Ruby. 67 99:59:59,999 --> 99:59:59,999 What I should say is that it's been there 68 99:59:59,999 --> 99:59:59,999 since at least 1997, since that's 69 99:59:59,999 --> 99:59:59,999 the oldest version controlled Ruby we have. 70 99:59:59,999 --> 99:59:59,999 It was probably there before that though. 71 99:59:59,999 --> 99:59:59,999 Require can be broken down into even 72 99:59:59,999 --> 99:59:59,999 smaller concepts. Using code from 73 99:59:59,999 --> 99:59:59,999 a file is basically the same as inserting 74 99:59:59,999 --> 99:59:59,999 that code and having Ruby run it 75 99:59:59,999 --> 99:59:59,999 as if you'd just written it in the file. 76 99:59:59,999 --> 99:59:59,999 It's actually possible to implement it yourself, 77 99:59:59,999 --> 99:59:59,999 with a one-line function. 78 99:59:59,999 --> 99:59:59,999 This function says; I have a file 79 99:59:59,999 --> 99:59:59,999 name and I want to require it, 80 99:59:59,999 --> 99:59:59,999 and you read the file in the memory 81 99:59:59,999 --> 99:59:59,999 into a string and you pass the 82 99:59:59,999 --> 99:59:59,999 string to eval, and Ruby runs it 83 99:59:59,999 --> 99:59:59,999 and it's just like you typed that code yourself. 84 99:59:59,999 --> 99:59:59,999 There are problems with this. 85 99:59:59,999 --> 99:59:59,999 Require doesn't work this way in real life. 86 99:59:59,999 --> 99:59:59,999 I'm sure it's totally fine that this will 87 99:59:59,999 --> 99:59:59,999 run that same piece of code over and over 88 99:59:59,999 --> 99:59:59,999 if you require it over and over, you like 89 99:59:59,999 --> 99:59:59,999 having lots and lots of constants that keep 90 99:59:59,999 --> 99:59:59,999 getting redefined, I'm sure it's totally fine. 91 99:59:59,999 --> 99:59:59,999 Working around that, is pretty straightforward. 92 99:59:59,999 --> 99:59:59,999 Just keep track of what you've required in an Array 93 99:59:59,999 --> 99:59:59,999 and not require something again if it' been required. 94 99:59:59,999 --> 99:59:59,999 As you can see here, 95 99:59:59,999 --> 99:59:59,999 you set up an Array, you check 96 99:59:59,999 --> 99:59:59,999 to see if the Array already contains 97 99:59:59,999 --> 99:59:59,999 the filename that just got passed in, 98 99:59:59,999 --> 99:59:59,999 and if hasn't been required, 99 99:59:59,999 --> 99:59:59,999 do the same thing we did before, 100 99:59:59,999 --> 99:59:59,999 read the file in, pass it to eval, 101 99:59:59,999 --> 99:59:59,999 and then add it to the array, 102 99:59:59,999 --> 99:59:59,999 so it's not required again later. 103 99:59:59,999 --> 99:59:59,999 In fact, this exactly what Ruby does, 104 99:59:59,999 --> 99:59:59,999 but written in C not in Ruby. 105 99:59:59,999 --> 99:59:59,999 There is a LOADED_FEATURES global variable, 106 99:59:59,999 --> 99:59:59,999 and it's an Array, and it contains a list 107 99:59:59,999 --> 99:59:59,999 of all the required files. 108 99:59:59,999 --> 99:59:59,999 If you want to know if you've required something yet, 109 99:59:59,999 --> 99:59:59,999 check the LOADED_FEATURES array. 110 99:59:59,999 --> 99:59:59,999 There is one more problem with this, 111 99:59:59,999 --> 99:59:59,999 it only works when you pass in absolute paths. 112 99:59:59,999 --> 99:59:59,999 I'm sure you don't mind you typing the 113 99:59:59,999 --> 99:59:59,999 full path from wherever you are to 114 99:59:59,999 --> 99:59:59,999 exactly wherever the file you want to require is. 115 99:59:59,999 --> 99:59:59,999 I'm sure that's fine too. 116 99:59:59,999 --> 99:59:59,999 The easiest way to allow requires that 117 99:59:59,999 --> 99:59:59,999 aren't absolute is to just treat 118 99:59:59,999 --> 99:59:59,999 all requires as if they're relative 119 99:59:59,999 --> 99:59:59,999 to the path where you started 120 99:59:59,999 --> 99:59:59,999 the Ruby program. And that's easy, 121 99:59:59,999 --> 99:59:59,999 but that doesn't help a lot if you 122 99:59:59,999 --> 99:59:59,999 want to require Ruby files from different places. 123 99:59:59,999 --> 99:59:59,999 Say you have a folder full of a library 124 99:59:59,999 --> 99:59:59,999 you wrote and folder full of an application you wrote 125 99:59:59,999 --> 99:59:59,999 and you want to use a library from the app, you can't, 126 99:59:59,999 --> 99:59:59,999 because writing relative paths from wherever 127 99:59:59,999 --> 99:59:59,999 you started the Ruby program would be terrible. 128 99:59:59,999 --> 99:59:59,999 Instead we create an Array that holds the 129 99:59:59,999 --> 99:59:59,999 list of paths we want to load we want to load 130 99:59:59,999 --> 99:59:59,999 Ruby files from, in a burst of creativity 131 99:59:59,999 --> 99:59:59,999 I'm just going to call that variable the 132 99:59:59,999 --> 99:59:59,999 LOAD_PATH, and here's an implementation. 133 99:59:59,999 --> 99:59:59,999 If you put something in the LOAD_PATH Array, 134 99:59:59,999 --> 99:59:59,999 you can then pass a relative path to any directory 135 99:59:59,999 --> 99:59:59,999 that's in the LOAD_PATH Array, and 136 99:59:59,999 --> 99:59:59,999 it will look for the file. 137 99:59:59,999 --> 99:59:59,999 If you require "foo", it will look for a file 138 99:59:59,999 --> 99:59:59,999 named "foo" inside any of the LOAD_PATH directories, 139 99:59:59,999 --> 99:59:59,999 and if the first one we find searching 140 99:59:59,999 --> 99:59:59,999 the LOAD_PATH in order from first to last, 141 99:59:59,999 --> 99:59:59,999 we will require that one. 142 99:59:59,999 --> 99:59:59,999 Coincidentally, this is exactly what 143 99:59:59,999 --> 99:59:59,999 Ruby does, there is a global variable 144 99:59:59,999 --> 99:59:59,999 named LOAD_PATH, and if you put 145 99:59:59,999 --> 99:59:59,999 a string that contains a path to a directory 146 99:59:59,999 --> 99:59:59,999 in it, Ruby will look in that directory 147 99:59:59,999 --> 99:59:59,999 whenever you require something for a file 148 99:59:59,999 --> 99:59:59,999 with that name. 149 99:59:59,999 --> 99:59:59,999 You can totally use the LOAD_PATH to require 150 99:59:59,999 --> 99:59:59,999 files from somewhere else while you're working with them. 151 99:59:59,999 --> 99:59:59,999 Of course, the LOADPATH, and LOADED_FEATURES 152 99:59:59,999 --> 99:59:59,999 can both be combined, but that didn't 153 99:59:59,999 --> 99:59:59,999 fit on a single slide, so I'll leave that 154 99:59:59,999 --> 99:59:59,999 as an exercise to the listener. 155 99:59:59,999 --> 99:59:59,999 It's pretty straightforward to be honest. 156 99:59:59,999 --> 99:59:59,999 Load paths are pretty cool. 157 99:59:59,999 --> 99:59:59,999 They allow us to load Ruby directories 158 99:59:59,999 --> 99:59:59,999 even if they're spread across multiple places. 159 99:59:59,999 --> 99:59:59,999 At this point, we could even 160 99:59:59,999 --> 99:59:59,999 have automatically, at the start of every script, 161 99:59:59,999 --> 99:59:59,999 the directory that holds the standard library, 162 99:59:59,999 --> 99:59:59,999 to the load path, and then all of the 163 99:59:59,999 --> 99:59:59,999 files that are pretty of the Ruby standard library, 164 99:59:59,999 --> 99:59:59,999 like Net::HTTP, Set, the cool thing that 165 99:59:59,999 --> 99:59:59,999 come with Ruby, could just be available for 166 99:59:59,999 --> 99:59:59,999 require automatically and you wouldn't have 167 99:59:59,999 --> 99:59:59,999 to worry about putting them in the 168 99:59:59,999 --> 99:59:59,999 load path yourself. That's exactly 169 99:59:59,999 --> 99:59:59,999 what Ruby does, the standard library 170 99:59:59,999 --> 99:59:59,999 starts on the load path when Ruby starts. 171 99:59:59,999 --> 99:59:59,999 It's pretty great. This was cool, and 172 99:59:59,999 --> 99:59:59,999 for several years, this was enough. 173 99:59:59,999 --> 99:59:59,999 People just added things to the load path. 174 99:59:59,999 --> 99:59:59,999 Or wrote scripts that added things to the 175 99:59:59,999 --> 99:59:59,999 load path before requiring things before their 176 99:59:59,999 --> 99:59:59,999 actual script happened. 177 99:59:59,999 --> 99:59:59,999 The thing that got tedius out just having 178 99:59:59,999 --> 99:59:59,999 load paths, is that if you want to get code from 179 99:59:59,999 --> 99:59:59,999 someone else, you have to find that code, 180 99:59:59,999 --> 99:59:59,999 download it, put it somewhere, remember where, 181 99:59:59,999 --> 99:59:59,999 put it in the load path, and then require it. 182 99:59:59,999 --> 99:59:59,999 This was tedious. 183 99:59:59,999 --> 99:59:59,999 Setup.rb happened next. 184 99:59:59,999 --> 99:59:59,999 Around the year 2000 everyone is still 185 99:59:59,999 --> 99:59:59,999 installing share Ruby code by hand. 186 99:59:59,999 --> 99:59:59,999 That wasn't so much fun. 187 99:59:59,999 --> 99:59:59,999 A Japanese Ruby developer, Minero Aoki, 188 99:59:59,999 --> 99:59:59,999 wrote setup.rb, and amazingly, 189 99:59:59,999 --> 99:59:59,999 even though this was created in 2000, 190 99:59:59,999 --> 99:59:59,999 setup.rb is still around on the Internet. 191 99:59:59,999 --> 99:59:59,999 The website for this developer is, 192 99:59:59,999 --> 99:59:59,999 i.loveruby.net, which is pretty cool, 193 99:59:59,999 --> 99:59:59,999 and you can even download setup.rb, but 194 99:59:59,999 --> 99:59:59,999 to be honest, it hasn't been updated since 2005, 195 99:59:59,999 --> 99:59:59,999 so I'm not sure it's super helpful to you. 196 99:59:59,999 --> 99:59:59,999 How did setup.rb work? 197 99:59:59,999 --> 99:59:59,999 At it's core it mimicked the classic 198 99:59:59,999 --> 99:59:59,999 UNIX installation pattern, 199 99:59:59,999 --> 99:59:59,999 downloading a piece of software, 200 99:59:59,999 --> 99:59:59,999 decompressing it, and then running 201 99:59:59,999 --> 99:59:59,999 configure make, and make install, 202 99:59:59,999 --> 99:59:59,999 so setup.rb kind of copied that for Ruby. 203 99:59:59,999 --> 99:59:59,999 You would run ruby setup.rb setup, 204 99:59:59,999 --> 99:59:59,999 ruby setup.rb config, ruby setup.rb install 205 99:59:59,999 --> 99:59:59,999 setup.rb would copy all the Ruby files, 206 99:59:59,999 --> 99:59:59,999 there was a specific directory structure, 207 99:59:59,999 --> 99:59:59,999 kind of like a Gem today, with 208 99:59:59,999 --> 99:59:59,999 library files, and bin files you could run as programs, 209 99:59:59,999 --> 99:59:59,999 and support files, and setup.rb would 210 99:59:59,999 --> 99:59:59,999 copy all of those files into a directory 211 99:59:59,999 --> 99:59:59,999 that was already in the load path called, 212 99:59:59,999 --> 99:59:59,999 site ruby, and that was the ruby files 213 99:59:59,999 --> 99:59:59,999 you had installed that were specific 214 99:59:59,999 --> 99:59:59,999 to your computer. 215 99:59:59,999 --> 99:59:59,999 After setup.rb, using Ruby libraries 216 99:59:59,999 --> 99:59:59,999 was much easier than it had been. 217 99:59:59,999 --> 99:59:59,999 You could find a library online, 218 99:59:59,999 --> 99:59:59,999 download it, you had to untar it by hand, 219 99:59:59,999 --> 99:59:59,999 and run ruby setup.rb all by hand, 220 99:59:59,999 --> 99:59:59,999 but then it was all installed, and no more 221 99:59:59,999 --> 99:59:59,999 manual copying, no more having to 222 99:59:59,999 --> 99:59:59,999 manage all these files. 223 99:59:59,999 --> 99:59:59,999 Everything was in the load path, 224 99:59:59,999 --> 99:59:59,999 you could just require it after setup.rb ran. 225 99:59:59,999 --> 99:59:59,999 After a little while, some of the 226 99:59:59,999 --> 99:59:59,999 shortcomings of this scheme became apparent, too. 227 99:59:59,999 --> 99:59:59,999 There were no versions for any libraries, 228 99:59:59,999 --> 99:59:59,999 and after you run setup.rb there's not even 229 99:59:59,999 --> 99:59:59,999 a way to tell what version you have, unless 230 99:59:59,999 --> 99:59:59,999 you write it down, or the library author 231 99:59:59,999 --> 99:59:59,999 was really nice, and put the version into 232 99:59:59,999 --> 99:59:59,999 the code somehow. There was no way 233 99:59:59,999 --> 99:59:59,999 to uninstall, everything thrown into 234 99:59:59,999 --> 99:59:59,999 the same directory. You'd run setup.rb 235 99:59:59,999 --> 99:59:59,999 for 5 different Ruby libraries and 236 99:59:59,999 --> 99:59:59,999 now all of their files are in one directory. 237 99:59:59,999 --> 99:59:59,999 Good luck figuring out which ones belongs to which. 238 99:59:59,999 --> 99:59:59,999 If you delete the wrong one, too bad. 239 99:59:59,999 --> 99:59:59,999 Upgrading was super fun, if there was 240 99:59:59,999 --> 99:59:59,999 a new version of the library, which 241 99:59:59,999 --> 99:59:59,999 good luck finding that out, you 242 99:59:59,999 --> 99:59:59,999 have to remember the website you got 243 99:59:59,999 --> 99:59:59,999 it from in the first place. 244 99:59:59,999 --> 99:59:59,999 I hope you write all these down. 245 99:59:59,999 --> 99:59:59,999 I hope you've written down every 246 99:59:59,999 --> 99:59:59,999 website you've ever downloaded Ruby from. 247 99:59:59,999 --> 99:59:59,999 You have to go back to that website, 248 99:59:59,999 --> 99:59:59,999 remember which version you have, which 249 99:59:59,999 --> 99:59:59,999 as I said before, there's nothing there unless 250 99:59:59,999 --> 99:59:59,999 you wrote it down. 251 99:59:59,999 --> 99:59:59,999 And then you have to download the 252 99:59:59,999 --> 99:59:59,999 tarball with the new version, and 253 99:59:59,999 --> 99:59:59,999 decompress it, and CD into it and 254 99:59:59,999 --> 99:59:59,999 run ruby setup.rb on it all, and 255 99:59:59,999 --> 99:59:59,999 hope that the new version didn't delete 256 99:59:59,999 --> 99:59:59,999 any files because the old files are still there. 257 99:59:59,999 --> 99:59:59,999 This was tedious, it was really tedious. 258 99:59:59,999 --> 99:59:59,999 People frequently had no idea what 259 99:59:59,999 --> 99:59:59,999 was actually happening with their libraries. 260 99:59:59,999 --> 99:59:59,999 It was not uncommon for people to be like 261 99:59:59,999 --> 99:59:59,999 "Oh this doesn't work, I'll just fix it 262 99:59:59,999 --> 99:59:59,999 in my site ruby directory, ok everything 263 99:59:59,999 --> 99:59:59,999 is great now" 264 99:59:59,999 --> 99:59:59,999 Super awesome. 265 99:59:59,999 --> 99:59:59,999 At some point, some people were like 266 99:59:59,999 --> 99:59:59,999 this is not great. What if you could just 267 99:59:59,999 --> 99:59:59,999 gem install. That would be cool. 268 99:59:59,999 --> 99:59:59,999 And so in 2003, RubyGems came to the rescue. 269 99:59:59,999 --> 99:59:59,999 And fixed all of the problems with setup.rb 270 99:59:59,999 --> 99:59:59,999 that were known. You could check 271 99:59:59,999 --> 99:59:59,999 to see if a library existed by running gem list, 272 99:59:59,999 --> 99:59:59,999 install a gem by gem install, uninstall gems. 273 99:59:59,999 --> 99:59:59,999 RubyGems kept each of these libraries in different directories. 274 99:59:59,999 --> 99:59:59,999 You knew which libraries you had, and how to uninstall 275 99:59:59,999 --> 99:59:59,999 and install new versions, all with one command. 276 99:59:59,999 --> 99:59:59,999 No having to find it on the internet somewhere, 277 99:59:59,999 --> 99:59:59,999 download, and unpack it, setup.rb it. 278 99:59:59,999 --> 99:59:59,999 And RubyGems had another super cool trick 279 99:59:59,999 --> 99:59:59,999 up it's sleeves -- versions. 280 99:59:59,999 --> 99:59:59,999 RubyGems actually kept each version of each 281 99:59:59,999 --> 99:59:59,999 gem in a different place. You could install 282 99:59:59,999 --> 99:59:59,999 multiple versions of the same library. 283 99:59:59,999 --> 99:59:59,999 And they could all be in your Ruby 284 99:59:59,999 --> 99:59:59,999 because they didn't all go into one giant folder, 285 99:59:59,999 --> 99:59:59,999 they went into their own separate folders. 286 99:59:59,999 --> 99:59:59,999 Folders for rails 4.1, 4.2, and 5.0. 287 99:59:59,999 --> 99:59:59,999 To make this work, because require doesn't 288 99:59:59,999 --> 99:59:59,999 support versioning, inherently, 289 99:59:59,999 --> 99:59:59,999 RubyGems added a gem method that 290 99:59:59,999 --> 99:59:59,999 let's you say, I need version 1.0 of rack, 291 99:59:59,999 --> 99:59:59,999 and RubyGems will check to make sure it's 292 99:59:59,999 --> 99:59:59,999 installed, put that directory, just the one 293 99:59:59,999 --> 99:59:59,999 with rack 1.0 into your load path. 294 99:59:59,999 --> 99:59:59,999 So when you run require "rack" you'll 295 99:59:59,999 --> 99:59:59,999 get rack 1.0, it's pretty cool. 296 99:59:59,999 --> 99:59:59,999 Calling the gem method, told RubyGems 297 99:59:59,999 --> 99:59:59,999 you wanted to manipulate the load path to 298 99:59:59,999 --> 99:59:59,999 load exactly the version you knew your 299 99:59:59,999 --> 99:59:59,999 code wanted to talk to. 300 99:59:59,999 --> 99:59:59,999 It was pretty useful. 301 99:59:59,999 --> 99:59:59,999 RubyGems also has a way to support 302 99:59:59,999 --> 99:59:59,999 versioning even in commands that 303 99:59:59,999 --> 99:59:59,999 come with gems. The rack gem 304 99:59:59,999 --> 99:59:59,999 comes with the rackup command, and 305 99:59:59,999 --> 99:59:59,999 if you have multiple versions of rack installed, 306 99:59:59,999 --> 99:59:59,999 the rack command could run any of those versions. 307 99:59:59,999 --> 99:59:59,999 RubyGems defaults to the newest version you have 308 99:59:59,999 --> 99:59:59,999 installed, hoping the newest is the right one. 309 99:59:59,999 --> 99:59:59,999 But if that's not, RubyGems checks the first 310 99:59:59,999 --> 99:59:59,999 argument to the command for something 311 99:59:59,999 --> 99:59:59,999 with underscores on either sides, 312 99:59:59,999 --> 99:59:59,999 it takes that as the version number 313 99:59:59,999 --> 99:59:59,999 that you want to use. 314 99:59:59,999 --> 99:59:59,999 In the above example, we're running 315 99:59:59,999 --> 99:59:59,999 rackup from rack version 1.2.2, and only 1.2.2. 316 99:59:59,999 --> 99:59:59,999 If you don't have that version installed, RubyGems will 317 99:59:59,999 --> 99:59:59,999 make you install that version first. 318 99:59:59,999 --> 99:59:59,999 RubyGems was really, really successful. 319 99:59:59,999 --> 99:59:59,999 Ruby grew in popularity a lot, but RubyGems 320 99:59:59,999 --> 99:59:59,999 made sharing Ruby code grow a lot. 321 99:59:59,999 --> 99:59:59,999 Present day we have 100,000 gems, with 1,000,000 versions. 322 99:59:59,999 --> 99:59:59,999 That's a lot of shared Ruby code. 323 99:59:59,999 --> 99:59:59,999 You probably knew this was coming, 324 99:59:59,999 --> 99:59:59,999 but as cool as RubyGems is, it still had 325 99:59:59,999 --> 99:59:59,999 some problems. If you have multiple 326 99:59:59,999 --> 99:59:59,999 applications that all use RubyGems to load 327 99:59:59,999 --> 99:59:59,999 their dependencies, this can be problematic. 328 99:59:59,999 --> 99:59:59,999 It's hard to coordinate across multiple applications 329 99:59:59,999 --> 99:59:59,999 because, each installation of Ruby itself just has 330 99:59:59,999 --> 99:59:59,999 a set of gems. If you ran gem install, now 331 99:59:59,999 --> 99:59:59,999 there are all these gems. 332 99:59:59,999 --> 99:59:59,999 If one developer runs gem install "foo" and 333 99:59:59,999 --> 99:59:59,999 starts using "foo" in their application, 334 99:59:59,999 --> 99:59:59,999 commits that code and checks it in, 335 99:59:59,999 --> 99:59:59,999 and the next person checks it out 336 99:59:59,999 --> 99:59:59,999 and tries to run the application, 337 99:59:59,999 --> 99:59:59,999 it's going to explode, because it doesn't 338 99:59:59,999 --> 99:59:59,999 know what foo is, you need to fix that. 339 99:59:59,999 --> 99:59:59,999 It led to an area of pure manual dependency management. 340 99:59:59,999 --> 99:59:59,999 Start a new job, hooray! 341 99:59:59,999 --> 99:59:59,999 This literally happened to me in 2008. 342 99:59:59,999 --> 99:59:59,999 New job, welcome to the team, here's 343 99:59:59,999 --> 99:59:59,999 your cool new laptop, we 344 99:59:59,999 --> 99:59:59,999 except you to have the application 345 99:59:59,999 --> 99:59:59,999 running by next week. 346 99:59:59,999 --> 99:59:59,999 It actually took me only 3 and a half days, 347 99:59:59,999 --> 99:59:59,999 working overtime on this. It was amazing. 348 99:59:59,999 --> 99:59:59,999 [Audience Laughs] 349 99:59:59,999 --> 99:59:59,999 To figure out which gems to run gem install, 350 99:59:59,999 --> 99:59:59,999 I looked in the README and there 351 99:59:59,999 --> 99:59:59,999 was a list. 352 99:59:59,999 --> 99:59:59,999 And I installed all of them. 353 99:59:59,999 --> 99:59:59,999 But clearly there was some that people 354 99:59:59,999 --> 99:59:59,999 forgot to put in the README, and 355 99:59:59,999 --> 99:59:59,999 then it kind of worked, but I wasn't 356 99:59:59,999 --> 99:59:59,999 able to get images working. And then 357 99:59:59,999 --> 99:59:59,999 some other developer was like, 358 99:59:59,999 --> 99:59:59,999 you need to install imagemagick, 359 99:59:59,999 --> 99:59:59,999 this was before homebrew. It was terrifying. 360 99:59:59,999 --> 99:59:59,999 To try and fix this problem, 361 99:59:59,999 --> 99:59:59,999 of do we just put the gems in the README? 362 99:59:59,999 --> 99:59:59,999 How do we know if we have 363 99:59:59,999 --> 99:59:59,999 written everything in the README? 364 99:59:59,999 --> 99:59:59,999 "I don't know? Try it?" 365 99:59:59,999 --> 99:59:59,999 Of course, you'd need a new machine 366 99:59:59,999 --> 99:59:59,999 to try it on, because after 3 years 367 99:59:59,999 --> 99:59:59,999 of using Ruby you generally have 368 99:59:59,999 --> 99:59:59,999 installed every gem, and you have 369 99:59:59,999 --> 99:59:59,999 no idea what's important and what's not. 370 99:59:59,999 --> 99:59:59,999 It's terrible. 371 99:59:59,999 --> 99:59:59,999 People started to work on tools to help this problem. 372 99:59:59,999 --> 99:59:59,999 Rails added config.gem, this is Rails 2.3, 2.4 era. 373 99:59:59,999 --> 99:59:59,999 You would put all the gems you need in application.rb 374 99:59:59,999 --> 99:59:59,999 This was super helpful if you needed 375 99:59:59,999 --> 99:59:59,999 to know for sure this was the 376 99:59:59,999 --> 99:59:59,999 master list of all the gems 377 99:59:59,999 --> 99:59:59,999 you needed in your application, but 378 99:59:59,999 --> 99:59:59,999 you could only access that list when 379 99:59:59,999 --> 99:59:59,999 Rails was already loaded. 380 99:59:59,999 --> 99:59:59,999 It was pretty bad. 381 99:59:59,999 --> 99:59:59,999 Because RubyGems automatically uses 382 99:59:59,999 --> 99:59:59,999 the newest version of each gem, just having 383 99:59:59,999 --> 99:59:59,999 an older version installed, didn't mean it 384 99:59:59,999 --> 99:59:59,999 would be used. And if you install 385 99:59:59,999 --> 99:59:59,999 some gem a month after the other person did, 386 99:59:59,999 --> 99:59:59,999 maybe there's a new version? You would 387 99:59:59,999 --> 99:59:59,999 just get the new version automatically. 388 99:59:59,999 --> 99:59:59,999 This is also totally a real-life experience that happened to me in 2009. 389 99:59:59,999 --> 99:59:59,999 Debug a production server that just randomly throws exceptions. 390 99:59:59,999 --> 99:59:59,999 For three days. 391 99:59:59,999 --> 99:59:59,999 The other production servers are fine. 392 99:59:59,999 --> 99:59:59,999 We can't reproduce this problem on a single developer laptop. 393 99:59:59,999 --> 99:59:59,999 What is going on? This is so weird. 394 99:59:59,999 --> 99:59:59,999 After 3 days I finally thought to look at 395 99:59:59,999 --> 99:59:59,999 the output from the gemlist for the entire production 396 99:59:59,999 --> 99:59:59,999 machine and I was like, oh this production 397 99:59:59,999 --> 99:59:59,999 server has gem version 1.1.3 and every 398 99:59:59,999 --> 99:59:59,999 other production server and developer laptop has 1.1.4. 399 99:59:59,999 --> 99:59:59,999 That was the problem. 400 99:59:59,999 --> 99:59:59,999 There was a bug and only that server 401 99:59:59,999 --> 99:59:59,999 had this problem. 402 99:59:59,999 --> 99:59:59,999 And then, like I was saying, about Rails versions, 403 99:59:59,999 --> 99:59:59,999 you could gem install rails, be happy, 404 99:59:59,999 --> 99:59:59,999 make a new app, run your server, 405 99:59:59,999 --> 99:59:59,999 everything is great. And then 406 99:59:59,999 --> 99:59:59,999 you switch to another application 407 99:59:59,999 --> 99:59:59,999 that already existed, didn't get 408 99:59:59,999 --> 99:59:59,999 written to use that version of rails, 409 99:59:59,999 --> 99:59:59,999 got writen to use some older version of rails. 410 99:59:59,999 --> 99:59:59,999 You're like, "Okay, let's go!" 411 99:59:59,999 --> 99:59:59,999 "Boom", because you didn't have 412 99:59:59,999 --> 99:59:59,999 the right version of Rails. 413 99:59:59,999 --> 99:59:59,999 If you put your rails version in the rails config 414 99:59:59,999 --> 99:59:59,999 rails would complain you had the wrong version, 415 99:59:59,999 --> 99:59:59,999 but rails had to be successfully started up to 416 99:59:59,999 --> 99:59:59,999 tell you that you had the wrong version, so 417 99:59:59,999 --> 99:59:59,999 it didn't actually help. 418 99:59:59,999 --> 99:59:59,999 Ultimately, it was a significant part of my job 419 99:59:59,999 --> 99:59:59,999 to figure this shit out by hand, and it sucked. 420 99:59:59,999 --> 99:59:59,999 Depending on what you did on your team, 421 99:59:59,999 --> 99:59:59,999 some people on my team at the time spent 422 99:59:59,999 --> 99:59:59,999 a quarter or a third of their time 423 99:59:59,999 --> 99:59:59,999 doing nothing but figuring out and fixing 424 99:59:59,999 --> 99:59:59,999 dependency management issues. 425 99:59:59,999 --> 99:59:59,999 And I felt really, really bad for them. 426 99:59:59,999 --> 99:59:59,999 Sometimes it was me and I felt really bad for me. 427 99:59:59,999 --> 99:59:59,999 Then there's one more, even after, 428 99:59:59,999 --> 99:59:59,999 you've done all of this by hand management, 429 99:59:59,999 --> 99:59:59,999 there's one more problem that RubyGems has 430 99:59:59,999 --> 99:59:59,999 that is another reason why bundler was created. 431 99:59:59,999 --> 99:59:59,999 Activation Errors, they happen in ruby gems 432 99:59:59,999 --> 99:59:59,999 when you load an application and start by 433 99:59:59,999 --> 99:59:59,999 requiring gems, ruby gems will load the newest 434 99:59:59,999 --> 99:59:59,999 versions of those gems that it can. 435 99:59:59,999 --> 99:59:59,999 Sometimes a gem's dependents need 436 99:59:59,999 --> 99:59:59,999 other gems, that need other gems, 437 99:59:59,999 --> 99:59:59,999 and you'll get the newest version of the 438 99:59:59,999 --> 99:59:59,999 child gem. And later you'll say, I also 439 99:59:59,999 --> 99:59:59,999 need this gem, but that gem won't work with the other. 440 99:59:59,999 --> 99:59:59,999 So how common can this be really? 441 99:59:59,999 --> 99:59:59,999 Unfortunately, it was super common. 442 99:59:59,999 --> 99:59:59,999 Not like happens to you every day common, 443 99:59:59,999 --> 99:59:59,999 but like happens you two or three times a year 444 99:59:59,999 --> 99:59:59,999 and when it does you basically tear 445 99:59:59,999 --> 99:59:59,999 all your hair out, delete your entire 446 99:59:59,999 --> 99:59:59,999 ruby install, uninstall and reinstall all your gems, 447 99:59:59,999 --> 99:59:59,999 because figuring out exactly which combo 448 99:59:59,999 --> 99:59:59,999 of installed gems was causing this 449 99:59:59,999 --> 99:59:59,999 problem was a total nightmare. 450 99:59:59,999 --> 99:59:59,999 This is a real-life activation error. 451 99:59:59,999 --> 99:59:59,999 I salvaged this from a presentation I gave in 2010 452 99:59:59,999 --> 99:59:59,999 about why Bundler exists. 453 99:59:59,999 --> 99:59:59,999 This is a rails app, it's loading, and 454 99:59:59,999 --> 99:59:59,999 rails of course depends on ActionPack, this 455 99:59:59,999 --> 99:59:59,999 was the Rails 2.3 era, ActionPack depends on Rack, 456 99:59:59,999 --> 99:59:59,999 Rack is a gem that helps Rails talk to web servers. 457 99:59:59,999 --> 99:59:59,999 And thin, which is a web server, also depends on rack. 458 99:59:59,999 --> 99:59:59,999 So, rack is how rails talks to thin, how thin 459 99:59:59,999 --> 99:59:59,999 talks to rails, but there's a problem. 460 99:59:59,999 --> 99:59:59,999 thin is perfectly happy to use rack 1.1, which makes some 461 99:59:59,999 --> 99:59:59,999 changes to how rack works. 462 99:59:59,999 --> 99:59:59,999 ActionPack is not happy to use rack 1.1, and 463 99:59:59,999 --> 99:59:59,999 can only use rack 1.0. And so 464 99:59:59,999 --> 99:59:59,999 when you run your server, it loads thin 465 99:59:59,999 --> 99:59:59,999 first because thin is the server. 466 99:59:59,999 --> 99:59:59,999 And thin gets to work trying to load the rails app 467 99:59:59,999 --> 99:59:59,999 and your rails app says "I can't use that rack, sorry" 468 99:59:59,999 --> 99:59:59,999 The reason this happens is runtime resolution. 469 99:59:59,999 --> 99:59:59,999 RubyGems figures out which versions 470 99:59:59,999 --> 99:59:59,999 of which gems of which gems it should load. 471 99:59:59,999 --> 99:59:59,999 After RubyGems is already running. 472 99:59:59,999 --> 99:59:59,999 You say, "Hey I need a thing", and 473 99:59:59,999 --> 99:59:59,999 it's like "Okay, this version might work". 474 99:59:59,999 --> 99:59:59,999 And if later on you say, 475 99:59:59,999 --> 99:59:59,999 "I need a thing that doesn't work with things you've already done" 476 99:59:59,999 --> 99:59:59,999 RubyGems just has to be like, can't fix that. 477 99:59:59,999 --> 99:59:59,999 The fix for this problem is to figure out all the versions 478 99:59:59,999 --> 99:59:59,999 before you run your application. 479 99:59:59,999 --> 99:59:59,999 You have to know the versions you're going 480 99:59:59,999 --> 99:59:59,999 to use are all versions that can work together. 481 99:59:59,999 --> 99:59:59,999 Resolving things at install time, 482 99:59:59,999 --> 99:59:59,999 knowing you're installing versions that work together. 483 99:59:59,999 --> 99:59:59,999 How do we make sure all the versions we're 484 99:59:59,999 --> 99:59:59,999 installing work together? 485 99:59:59,999 --> 99:59:59,999 That's actually where Bundler comes in. 486 99:59:59,999 --> 99:59:59,999 Before Bundler, the process of figuring out 487 99:59:59,999 --> 99:59:59,999 which gems would work together 488 99:59:59,999 --> 99:59:59,999 was done entirely by hand and it 489 99:59:59,999 --> 99:59:59,999 consisted of gem uninstall, 490 99:59:59,999 --> 99:59:59,999 gem install a slighty older version, does rails start up yet? 491 99:59:59,999 --> 99:59:59,999 Repeat the process. 492 99:59:59,999 --> 99:59:59,999 When the exception stopped you knew you'd won. 493 99:59:59,999 --> 99:59:59,999 Unsurprisingly, computers are faster at this than people. 494 99:59:59,999 --> 99:59:59,999 Computers are also good and accurate at trying 495 99:59:59,999 --> 99:59:59,999 many, many, many options until one works. 496 99:59:59,999 --> 99:59:59,999 This is what Bundler does. 497 99:59:59,999 --> 99:59:59,999 Bundler figures out the entire list of every gem 498 99:59:59,999 --> 99:59:59,999 and every version of every gem that 499 99:59:59,999 --> 99:59:59,999 you need, but that also all 500 99:59:59,999 --> 99:59:59,999 work together with one another. 501 99:59:59,999 --> 99:59:59,999 This is called Dependency Graph Resolution, 502 99:59:59,999 --> 99:59:59,999 and there's an entire academic literature about this. 503 99:59:59,999 --> 99:59:59,999 It's kind of well-known hard problem, it's 504 99:59:59,999 --> 99:59:59,999 part of the set of problems called NP complete, 505 99:59:59,999 --> 99:59:59,999 and the totally fantastic thing, and I say 506 99:59:59,999 --> 99:59:59,999 this as a person who has to fix Bundler 507 99:59:59,999 --> 99:59:59,999 when it doesn't work, in theory, you can construct 508 99:59:59,999 --> 99:59:59,999 a set of gems in a gemfile such that 509 99:59:59,999 --> 99:59:59,999 it is not possible to find a set of gems that 510 99:59:59,999 --> 99:59:59,999 work together until after the heat death of the universe. 511 99:59:59,999 --> 99:59:59,999 [Audience Laughs] 512 99:59:59,999 --> 99:59:59,999 Most of the time we don't have that long to wait. 513 99:59:59,999 --> 99:59:59,999 We use a lot of tricks, shortcuts, and heuristics 514 99:59:59,999 --> 99:59:59,999 to figure out which gems to try first and 515 99:59:59,999 --> 99:59:59,999 hopefully finish before you've drunk 516 99:59:59,999 --> 99:59:59,999 that cup of coffee or whatever. 517 99:59:59,999 --> 99:59:59,999 We have a large built-up set of tricks over the years 518 99:59:59,999 --> 99:59:59,999 and most Gemfiles resolve in less than 10 seconds. 519 99:59:59,999 --> 99:59:59,999 Which is pretty cool, considering the upper bound 520 99:59:59,999 --> 99:59:59,999 on that is practically infinity. 521 99:59:59,999 --> 99:59:59,999 After finding versions that work together 522 99:59:59,999 --> 99:59:59,999 because this problem was really hard, 523 99:59:59,999 --> 99:59:59,999 and we don't want to do this over and over. 524 99:59:59,999 --> 99:59:59,999 Bundler writes down the exact versions of every gem 525 99:59:59,999 --> 99:59:59,999 that did all work together, so they can be reused 526 99:59:59,999 --> 99:59:59,999 by other people who are also interested in running 527 99:59:59,999 --> 99:59:59,999 your application. That file is called Gemfile.lock. 528 99:59:59,999 --> 99:59:59,999 Shows which gems to be installed, 529 99:59:59,999 --> 99:59:59,999 the versions to install, and as a bonus 530 99:59:59,999 --> 99:59:59,999 the lock file is what makes it possible 531 99:59:59,999 --> 99:59:59,999 to install the exact same version of every 532 99:59:59,999 --> 99:59:59,999 gem on every machine that's running this application. 533 99:59:59,999 --> 99:59:59,999 That means when you develop on your laptop 534 99:59:59,999 --> 99:59:59,999 you get whatever version of the gem that was 535 99:59:59,999 --> 99:59:59,999 newest when you were developing because run 536 99:59:59,999 --> 99:59:59,999 bundle install and got newest version by default. 537 99:59:59,999 --> 99:59:59,999 Because of the lock file, when you put 538 99:59:59,999 --> 99:59:59,999 that on your production server, you're guaranteed 539 99:59:59,999 --> 99:59:59,999 to have the same versions. And you won't 540 99:59:59,999 --> 99:59:59,999 have to spend 3 days figuring out why 541 99:59:59,999 --> 99:59:59,999 that production server doesn't quite 542 99:59:59,999 --> 99:59:59,999 work all of the time. 543 99:59:59,999 --> 99:59:59,999 It's pretty great. 544 99:59:59,999 --> 99:59:59,999 Fundamentally, the core of bundler consist of two steps. 545 99:59:59,999 --> 99:59:59,999 bundle install, and bundle exec. 546 99:59:59,999 --> 99:59:59,999 The steps for bundle install are simple. 547 99:59:59,999 --> 99:59:59,999 They're totally understandable in plain english 548 99:59:59,999 --> 99:59:59,999 It fits on a single slide, which is great. 549 99:59:59,999 --> 99:59:59,999 I edited this slide for ten minutes deleting words. 550 99:59:59,999 --> 99:59:59,999 So the steps are: 551 99:59:59,999 --> 99:59:59,999 1. Read the Gemfile 552 99:59:59,999 --> 99:59:59,999 2.Ask RubyGems.org for a list of all the gems we need 553 99:59:59,999 --> 99:59:59,999 3. Find versions of those gems both allowed by Gemfile 554 99:59:59,999 --> 99:59:59,999 4. Once found, write all those down in lock and install them all. 555 99:59:59,999 --> 99:59:59,999 And that's how bundle install works. 556 99:59:59,999 --> 99:59:59,999 BundleInstall uses RubyGems under the covers 557 99:59:59,999 --> 99:59:59,999 to the installation, and so every 558 99:59:59,999 --> 99:59:59,999 bundle is it's own little rubygems isolated install. 559 99:59:59,999 --> 99:59:59,999 Every application has it's own rubygems thanks to bundler. 560 99:59:59,999 --> 99:59:59,999 The next step is bundle exec. 561 99:59:59,999 --> 99:59:59,999 This is how we use that applications dedicated ruby gems 562 99:59:59,999 --> 99:59:59,999 instead of the one with whatever in it 563 99:59:59,999 --> 99:59:59,999 because you ran gem install last year. 564 99:59:59,999 --> 99:59:59,999 The way bundle exec works is: 565 99:59:59,999 --> 99:59:59,999 1. Reads the Gemfile, and lock if it's there. 566 99:59:59,999 --> 99:59:59,999 2a. Use locked gems if possible OR 567 99:59:59,999 --> 99:59:59,999 2b. Find versions that work together like install would. 568 99:59:59,999 --> 99:59:59,999 except bundle exec doesn't do any installing. 569 99:59:59,999 --> 99:59:59,999 3. Deletes any existing gems in the LOAD_PATH 570 99:59:59,999 --> 99:59:59,999 4. Adds the exact gem at the exact version at the load path. 571 99:59:59,999 --> 99:59:59,999 That's it. That's all bundle exec does. 572 99:59:59,999 --> 99:59:59,999 Once all the gems work together, and 573 99:59:59,999 --> 99:59:59,999 there exact versions are in the load path 574 99:59:59,999 --> 99:59:59,999 your application is happy. There is no 575 99:59:59,999 --> 99:59:59,999 activation errors, all your requires succeed, I hope. 576 99:59:59,999 --> 99:59:59,999 Everything is pretty great. 577 99:59:59,999 --> 99:59:59,999 As I think I promised in the abstract for this talk, 578 99:59:59,999 --> 99:59:59,999 here's a bundle exec removing pro tip. 579 99:59:59,999 --> 99:59:59,999 I don't really like typing bundle exec, I find it 580 99:59:59,999 --> 99:59:59,999 really annoying, but bundler provides a way 581 99:59:59,999 --> 99:59:59,999 to not have to type it all the time. 582 99:59:59,999 --> 99:59:59,999 And it's to create programs that map to 583 99:59:59,999 --> 99:59:59,999 ruby gems installation that 584 99:59:59,999 --> 99:59:59,999 belongs to that application. 585 99:59:59,999 --> 99:59:59,999 You can use the binstubs command, 586 99:59:59,999 --> 99:59:59,999 bundle binstubs [some gem] 587 99:59:59,999 --> 99:59:59,999 and it will create, in the bin directory, 588 99:59:59,999 --> 99:59:59,999 a program for that gem, that only 589 99:59:59,999 --> 99:59:59,999 runs the exact version that belongs to 590 99:59:59,999 --> 99:59:59,999 that application. So if you have 591 99:59:59,999 --> 99:59:59,999 rspec in your rails app, you can have 592 99:59:59,999 --> 99:59:59,999 bin/rspec that will only load the rspec 593 99:59:59,999 --> 99:59:59,999 for your app. This way you can have 594 99:59:59,999 --> 99:59:59,999 bin/rspec refer to rspec 3, and this application 595 99:59:59,999 --> 99:59:59,999 can have rspec 2. Rails has started to do this. 596 99:59:59,999 --> 99:59:59,999 Rails 4 ships with bin/rails bin/rake that are scoped 597 99:59:59,999 --> 99:59:59,999 so when you run bin/rails, you get the exact 598 99:59:59,999 --> 99:59:59,999 rails version for this application and not another one. 599 99:59:59,999 --> 99:59:59,999 When you run bin/rake you get the exact version of rake. 600 99:59:59,999 --> 99:59:59,999 Pretty cool, no more bundle exec. 601 99:59:59,999 --> 99:59:59,999 If everyone did this, you can check in these binstubs 602 99:59:59,999 --> 99:59:59,999 so you can take bin/rspec, but it in git, 603 99:59:59,999 --> 99:59:59,999 and it'll be mapped to that application forever, 604 99:59:59,999 --> 99:59:59,999 so no one would have bundle exec 605 99:59:59,999 --> 99:59:59,999 ever again if everyone did this. 606 99:59:59,999 --> 99:59:59,999 Now we bundle install, all our gems 607 99:59:59,999 --> 99:59:59,999 show up. We have versions 608 99:59:59,999 --> 99:59:59,999 dedicated for individual applications. 609 99:59:59,999 --> 99:59:59,999 But, as you probably sensed a problem 610 99:59:59,999 --> 99:59:59,999 going through history, that wasn't actually 611 99:59:59,999 --> 99:59:59,999 the end. There are still problems 612 99:59:59,999 --> 99:59:59,999 that show up after bundler came out. 613 99:59:59,999 --> 99:59:59,999 The biggest problem that was left was 614 99:59:59,999 --> 99:59:59,999 running bundle install, took forever. 615 99:59:59,999 --> 99:59:59,999 If you lived a long time from the United States 616 99:59:59,999 --> 99:59:59,999 it took a really long time. 617 99:59:59,999 --> 99:59:59,999 I talked to some developers in South Africa 618 99:59:59,999 --> 99:59:59,999 when I went there to give a talk 619 99:59:59,999 --> 99:59:59,999 and they told me about how running 620 99:59:59,999 --> 99:59:59,999 bundle install means they literally get 621 99:59:59,999 --> 99:59:59,999 up to start making a cup of coffee 622 99:59:59,999 --> 99:59:59,999 that they can finish before bundle install does. 623 99:59:59,999 --> 99:59:59,999 To try and speed things up, bundler 1.1 624 99:59:59,999 --> 99:59:59,999 created a completely different 625 99:59:59,999 --> 99:59:59,999 way to get information from rubygems about gems. 626 99:59:59,999 --> 99:59:59,999 And that sped things up by 50%, a big win. 627 99:59:59,999 --> 99:59:59,999 We keep working on this, bundler 1.9 just 628 99:59:59,999 --> 99:59:59,999 came out this month. There's a bunch more 629 99:59:59,999 --> 99:59:59,999 improvements we're working on. 630 99:59:59,999 --> 99:59:59,999 If you're interested in following along with that, 631 99:59:59,999 --> 99:59:59,999 the bundler websites has news annoucements 632 99:59:59,999 --> 99:59:59,999 at bundler.io, and twitter we're also @bundlerio. 633 99:59:59,999 --> 99:59:59,999 Having said all of this, if you use Bundler, 634 99:59:59,999 --> 99:59:59,999 I would totally love to have your help working on it. 635 99:59:59,999 --> 99:59:59,999 It's an open source project. 636 99:59:59,999 --> 99:59:59,999 We've dedicated a lot of time to making it easy 637 99:59:59,999 --> 99:59:59,999 for people who don't know how to do open source 638 99:59:59,999 --> 99:59:59,999 to help with Bundler, and to start working on Bundler, 639 99:59:59,999 --> 99:59:59,999 and to get into open source that way. 640 99:59:59,999 --> 99:59:59,999 It's a project at Github.com/bundler/bundler. 641 99:59:59,999 --> 99:59:59,999 If you're interested but don't know where to start 642 99:59:59,999 --> 99:59:59,999 email the bundler team at team@bundler.io 643 99:59:59,999 --> 99:59:59,999 and we'll get you set up. 644 99:59:59,999 --> 99:59:59,999 On the other hand, if you 645 99:59:59,999 --> 99:59:59,999 have a job that means you have money, 646 99:59:59,999 --> 99:59:59,999 but not time, join Ruby Together, and give 647 99:59:59,999 --> 99:59:59,999 us money, and we'll work on Bundler, and it'll be 648 99:59:59,999 --> 99:59:59,999 better. As RubyTogether grows, we will also be 649 99:59:59,999 --> 99:59:59,999 tackling bigger community issues. 650 99:59:59,999 --> 99:59:59,999 We want to add easy to use gem mirrors so you 651 99:59:59,999 --> 99:59:59,999 don't have to go all the way to rubygems.org 652 99:59:59,999 --> 99:59:59,999 for your office or data center, we want to 653 99:59:59,999 --> 99:59:59,999 add better public benchmarks. There's a project 654 99:59:59,999 --> 99:59:59,999 calling ruby-bench that's starting to do that, 655 99:59:59,999 --> 99:59:59,999 and we'd really like to expand it. 656 99:59:59,999 --> 99:59:59,999 There's a bunch of other things 657 99:59:59,999 --> 99:59:59,999 that RubyTogether is working on that are cool 658 99:59:59,999 --> 99:59:59,999 If you want Bundler or RubyTogether stickers 659 99:59:59,999 --> 99:59:59,999 I have a giant pile, so find me later. 660 99:59:59,999 --> 99:59:59,999 That's it. 661 99:59:59,999 --> 99:59:59,999 [Audience Applause]