RubyConf 2015

Cómo funciona Bundler en las aplicaciones Ruby

Andre Arko  · 

Presentación

Vídeo

Transcripción

Extracto de la transcripción automática del vídeo realizada por YouTube.

- Hi, everyone. So, this talk is called How does Bundler work, anyway? and it basically came from realizing as I talked to people that a lot of people are like "Oh, I know how Bundler works. You copy and paste this line from RubyGems or ReadMe and then you run bundle install, that's how Bundler works.

So it turns out that if what you care about is like, what's happening when those things happen, you actually have to understand what the problem is that Bundler solves, and to understand the problem that Bundler solves, you have to understand the problem that created the problem that Bundler solves, and then you have to understand what created that problem, and then what created that problem, so this is going to be a brief history of dependency management in Ruby, hopefully brief, but before I tell you about how dependencies have worked forever, let me quickly tell you who I am.

My name is André Arko, on the internet I'm pretty much always indirect, that's my current avatar on all the internet things, you may have seen my picture on a website or something. I work for Cloud City Development, mostly joining teams who could use someone who has seen how that decision can go wrong and can warn you to avoid it.

Also, pairing with people who are like, junior and midlevel and talking about how Ruby works. If your team could use one of those people, maybe talk to me later. I co-authored the third edition of The Ruby Way. It- the first edition of The Ruby Way was totally my favorite Ruby book ever in like, 2001 and I basically learned Ruby from it, and so The Ruby Way third edition is updated for Ruby 2.

2 and 2. 3, and I'm sure it'll last at least a good six to nine months before it just turns into something you use to prop up your monitor. The other thing that I do is called Ruby Together, it's a nonprofit. It's kind of like NPM except we don't have any venture capitalists and basically, we take money from companies and people who use Ruby and we pay developers to work on projects that everyone who uses Ruby needs to have work.

So we have some- some companies have just agreed with us that this is a good idea, including Stripe and New Relic and Basecamp and what Ruby Together does is it pays for work on things like RubyGems, and the RubyGems. org server that everyone gets gems from, and Bundler.

So I've been the team lead for Bundler for about four years, and that's why I'm talking to you about Bundler today. So, let's share some Ruby code. How hard is it to use code written by someone else? Well, it's actually pretty easy, you just put this thing in your Gemfile, and then you run Bundle install, and then you run bundle exec, and ta-da! So, that was so easy, but what actually just happened when you did that? Well, it's complicated.

Something got installed, something got downloaded, what got downloaded, where did it go, how did you get to it later, I don't even know. So, history time. Let me take you on a little dependency history tour, but, by the time we finish, you'll at least know, you know, not just how it works, but why it works the way that it does today, and as you could maybe predict from anything that involves computers, the answer is legacy reasons.

So, starting, here's a little preview of what I'm gonna talk about. I'm gonna talk about require, which is how Ruby lets you load code from files, then we'll get setup. rb which was the first way that you could install code into Ruby so that you could require it without telling Ruby where it was, and then we'll look at RubyGems which was the first way to easily download someone else's code, and then we'll look at Bundler, which lets you have multiple gems that all work at the same time.

So, require. The require method has been around since at least 1997, which is the oldest Ruby code that is actually in version control. I went back and checked. Presumably, require did not exist at some point, but Matz wasn't using version control yet, so I don't know when that happened.

Even though require is that old, it can still be broken down into some pretty small concepts. So, using code from another file, in Ruby, at least, is basically the same as copying and pasting the contents of that file in place of the line that says require.

That's pretty straightforward. So, you can actually implement the require function yourself, naively, with just, like, one line of code. You say I have the path to a file, I would like to read that file, I would like Ruby to eval that file as if it was code.

Done. I've implemented require. Pretty sweet. So, as I said, a little naive. You'll probably notice some problems with that naive implementation, so if you code require more than once, your code will run multiple times, this is usually bad, especially if your code, say, creates a class, because or defines a constant, or, you know, whatever.

So, it's actually not that hard to implement a system that checks to see if you've already required something. I even got it to fit on a slide. Global variables are usually pretty evil, in this case, it's probably the only way to track things that you've required that make sense, so let's call that global variable loaded features, for no reason in particular, and then you can see that you basically just say "Hey, did I already do that? That file name? Well, if I didn't, go, if I did, hey, we're done already, sweet.

" Turns out Ruby provides a global variable named loaded features that contains a list of all the files that you've required, good work. So, then the next problem that you may have already noticed just from looking at this code is that you have to pass absolute paths.

If you say require rails, it will say "There's not a file named rails. " So, that's probably okay if you know where every single file on your entire machine is, but I'm assuming that you don't want to have to know that all the time, so the easiest way to allow requires that aren't absolute is to just treat every file name as if it's relative to the directory that the program was started from.

That's really easy, but unfortunately it doesn't work well if you want to require Ruby files from multiple directories, so let's implement something that lets us require from more than one directory. I guess, theoretically that would probably look something like a global variable that's an array that contains a list of directories, and then you would loop over the list of directories, seeing if the file that's being required is present in any of those directories, I even got that code to fit on a slide.

So we'll call that global variable load path for no particular reason, and then we'll say "Hey, let's just find the first entry and load path that actually contains the file that we're requiring. And then we'll do the normal eval thing. " So, it turns out Ruby provides a global variable named load path, and when you call require, iterates over the load path, looking for the file that you just tried to require in each of the directories contained in the load path.

Now you know how require works. In real Ruby, unlike my slides, both the loaded features feature and the load path feature are combined into a single method. I couldn't get that to fit on a slide, but you're- feel free to do it yourself, if you would like.

[ ... ]

Nota: se han omitido las otras 3.585 palabras de la transcripción completa para cumplir con las normas de «uso razonable» de YouTube.