 I was here two years ago for my first or actually my first talk ever. I was very sure that I was about to have a heart attack, so luckily I didn't, and I'm here today, I made it. So thanks for all for coming. And in all seriousness, I'm gonna talk about dependency management in Ruby. And yeah, and the things that I like about it and how I think we can evolve. So let's get started. So there's two things that you should know about me. The first thing is that I have a cat. His name is Dennis. I had some paranoid thoughts that maybe he was trying to kill me and I took a quiz online and I was right. He is, yeah, so this is him, there's that. And then I also work at a company called Heroku. I work on developer experience there. I've been there a little bit over a month and I've only broken one thing, so things are going pretty well. And so yeah, so I'm gonna talk about dependency management with Ruby. Initially when I proposed the talk, I was a little bit ambitious for 10 minutes, so I had to shorten the name to fit with the shorter talk. So it's just locking it down with Ruby or as I would like to say, it's things I appreciate in regards to Ruby package management and dependency locking. So the reason that I actually started thinking about this as you guys heard before, I actually write a lot of Ember and a lot of JavaScript and so there's an ongoing dispute, conversation about the two conflicting ways to lock your dependencies in a JavaScript application. So there's NPM and there's Yarn and then Bauer is just kind of watching from the sidelines. And so there is a lot of conversation around how to do this because there's two different ways to lock dependencies and it can be confusing even as if you're experienced with a project or if you don't know JavaScript at all, then just forget about it, it's really confusing. And so since I've started working in JavaScript applications, so first of all, when I talk about locking, just to give a general definition, I'm talking about locking an entire dependency tree for an application or taking a dependency that is within the application level and then locking that tree for that specific dependency. And so I've done it four ways in JavaScript which is for a couple years is like a lot. And so the first one that I've done and it works okay is use pessimistic locking. And so you take the version of your package JSON which is the equivalent of a gem file and you strip out the syntax so that it gives it a range and so this would be greater than four, three, whatever, it doesn't matter. And so you take out the syntax and then you just give it a specific version so that when you install your packages, it resolves to that specific version. So I've used that. There's a shrink wrap, I won't get into what that is but it wasn't good. And then Yarn came out in about a year and a half, what year is it? Yeah, a year and a half ago and then six months later, NPM came out with their own lock file and so right now that's the conversation between the two to be determined how that ends. And so now I'm gonna go back and talk a little bit, a brief history about how Ruby came to be and how the dependency ecosystem kind of evolved. So originally we have Ruby, it came out in 1995, I'll call that year zero. And then we have Ruby Gems which was introduced in 2004, nine AR after Ruby. And then I'm lumping together Ruby Gems org and the Ruby Gems tool into one unit because it's just easier to talk about it that way but there are two pieces to that. And then five years later, 14 AR came Bundler and Bundler was the tool to, oh and so Ruby Gems is for managing, so for hosting, for packaging your Ruby libraries to make available for other developers for the Ruby ecosystem and then also for hosting Ruby Gems. And then Bundler came around and this was for dependency management after Rails came out and so different applications needed a more robust version locking system. So let's talk about the good parts. So first of all, so this is all my opinion. This is based off of working a lot with another language and kind of identifying the different pieces that I think Ruby has done really well and hoping that maybe it will come to JavaScript one day, they're getting there. And so first of all, I think that the way to install gems and then also make them available at that application level is really straightforward and easy. You could see here that you can do all of this stuff and so you can install the command line tool which is just Rails and then initiate a Rails application with or without running bundle and then you can add a gem, a library to your application and then you could just even within the scope of an application using bundle exec, you're able to run whatever version you need to. So if you have different applications running on the same operating system, you don't have to worry about the version because if you use bundle exec, it's just scope to the right version and it just works. And so another thing that's really great is the way that Bundler resolves dependency conflicts and so I think this is really taken for granted a little bit, it's overlooked how this works because it's really cool. And so this is taken from the Bundler website which I think is pretty true, Bundler is an exit from dependency hell. And so just to give an overview, the way that this works is that we have the gem file and so I have these two dependencies and I just learned during this talk that I18n is internationalization because there's 18 letters between I and n and internationalization, fun fact. And so this has a dependency on concurrent Ruby but for some reason in this application I don't want concurrent Ruby greater than 1.0. I want 0.8.0 because that's just the, however I built it, that's how I want it to work. And so let's see, so when I run bundle install on this, it will generate this gem file lock and then, so what's happened here is that Bundler knows at the application level that I have, that I only want 0.8.0 in concurrent Ruby but then it looks back, I think I have a snapshot. Okay, yeah, and so you can see here that even though I haven't specified a dependency version, it still goes to internationalization and it goes backwards until it finds a version of concurrent Ruby that does not conflict with the application level. So it resolves those version conflicts for you and then you have a running application and so it works pretty well. And then the next thing that I think that RubyGems and Bundler do really well is that, well this is specific to RubyGems, is that it's really easy to package and develop and make available your Ruby library, isn't it? So it's just, all you have to do is put together a folder, you have a gem spec, all of the tools are there so that it creates a packaged file. You can push it up to RubyGems which is available on AWS and it's stored in S3 and then it's readily available within, I think there's like a caching layer or whatever but it's readily available for other people, to other developers, either to install it for their global applications or install it for their command line or add it to their applications. Thought there was, yeah, that's it. And so, I think this is my last point but so the last thing that's really cool about Ruby is that all of these two tools, the Bundler and RubyGems, are also both written in Ruby and so if you've ever tried to debug a tool that you're not familiar with the language, that it's, I mean, besides the fact that you can like learn or whatever, it's a pain. So it's really awesome because if you're finding out, you're like, why isn't this working? You can just step through your tools because they're all built in Ruby and it's really easy to read. So for instance, we have gem install, colorize, I think that's a gem name, I might have made that up but so when you have the gem executable, it takes two arguments, which is install and colorize and so it just runs this command and so you can see here that it's actually just creating an instance of gemrunner and then it's running it on that instance. So just using a gemrunner object. So this is, there's a lot that goes in between this but so let's see. So there's a lot that goes in between this but I'll just call it here. It creates a command object and then it just runs the command object with our configuration args and our build args and here's an execute step here. You could see at the top the install command and then it has install gems code or I'm sorry, install gems method, it has an exit code and then you could see from the beginning we saw that it's just running a process until the process is executed and then so hopefully it's successful. Bundle install, I just wanted to call out some of the cool stuff. So bundle install is just a larger Ruby method and so at the top here you could see, I don't know why that's there, but whatever. So you can see here that gem file is just a block and so it passes it into this method and iterates over it when it's installing your gems and then it runs installer on, runs a class method on that. So in conclusion, I think that all of these tools work really well but as you can see there's other libraries or there's other communities that are pretty aligned with what Ruby's doing and that we can really work from or learn from. So there's always points of iteration and yeah, I think we should be looking at those but all in all it's pretty good. I think that's it, thank you.