174

174 Rubygems with Eric Hodel


03:06 – Eric Hodel Introduction

04:22 – Start of RubyGems

06:21 – Core Functionality

09:37- Solving Developer Problems with RubyGems

10:33 – Eric’s History with Open Source

11:53 – Changes to RubyGems 13:25 – Merging with Bundler

16:55 – Hidden Features in RubyGems

20:15 – Package Structures 21:42 -Gem Signing – Security Tools

26:33 – Future Features of RubyGems

29:56 – Building and Deployment of RubyGems

34:10 – Plugins

36:24 – James’ RubyGems Request RPA – Ruby Package Archive

43:20 – “Gem Prelude”

  • Deployment

45:31 – Dealing with Open Source Community

50:11 – Good/Bad Parts of RubyGems Coding

51:46 – Lessons Learned 54:16 – Favorite Gem Commands

56:24 – Eric’s Upcoming Conferences

Book Club

Refactoring: Ruby Edition: Ruby Edition (Addison-Wesley Professional Ruby Series) by Jay Fields, Shane Harvie, Martin Fowler, and Kent Beck

Refactoring in Ruby by William C. Wake and Kevin Rutherford

Next Week

HeatSeek with William Jeffries

This episode is sponsored by

comments powered by Disqus

TRANSCRIPT

AVDI:  Charles, would you tell James that I’m not speaking to him?

[Laughter]

DAVID:  Charles, would you tell James that I don’t know who slashed the tires on his chair?

[Laughter]

JAMES:  Awesome.

CHUCK:  Why am I always in the middle of these things?

[Laughter]

DAVID:  Because you’re too slow to get on the edge of them.

[Laughter]

DAVID:  [Inaudible] everybody else.

[Laughter]

CHUCK:  Saron, will you tell James everything everybody else said?

[Laughter]

ERIC:  I’m glad I’m being left out of this.

[This episode is sponsored by Rackspace. Are you looking for a place to host your latest creation? Want terrific support, high performance all backed by the largest open source cloud? What if you could try it for free? Try out Rackspace at RubyRogues.com/Rackspace and get a $300 credit over six months. That’s $50 per month at RubyRogues.com/Rackspace.]

[This episode is sponsored by Codeship.io. Don’t you wish you could simply deploy your code every time your tests pass? Wouldn’t it be nice if it were tied into a nice continuous integration system? That’s Codeship. They run your code. If all your tests pass, they deploy your code automatically. For fuss-free continuous delivery, check them out at Codeship.io, continuous delivery made simple.]

[This episode is sponsored by Hired.com. Every week on Hired, they run an auction where over a thousand tech companies in San Francisco, New York, and L.A. bid on Ruby developers, providing them with salary and equity upfront. The average Ruby developer gets an average of 5 to 15 introductory offers and an average salary offer of $130,000 a year. Users can either accept an offer and go right into interviewing with the company or deny them without any continuing obligations. It’s totally free for users. And when you’re hired, they also give you a $2,000 signing bonus as a thank you for using them. But if you use the Ruby Rogues link, you’ll get a $4,000 bonus instead. Finally, if you’re not looking for a job and know someone who is, you can refer them to Hired and get a $1,337 bonus if they accept a job. Go sign up at Hired.com/RubyRoguesPodcast.]

[Snap is a hosted CI and continuous delivery that is simple and intuitive. Snap’s deployment pipelines deliver fast feedback and can push healthy builds to multiple environments automatically or on demand. Snap integrates deeply with GitHub and has great support for different languages, data stores, and testing frameworks. Snap deploys your application to cloud services like Heroku, Digital Ocean, AWS, and many more. Try Snap for free. Sign up at SnapCI.com/RubyRogues.]

CHUCK:  Hey everybody and welcome to episode 174 of the Ruby Rogues Podcast. This week on our panel, we have James Edward Gray.

JAMES:  Hello everyone.

CHUCK:  David Brady.

DAVID:  If you can hear me… okay.

CHUCK:  Saron Yitbarek.

SARON:  Hey from New York.

CHUCK:  Avdi Grimm.

AVDI:  Hello from Pennsylvania.

CHUCK: I’m Charles Max Wood from DevChat.TV. And this week, we have a special guest, Eric Hodel.

ERIC:  Hello. Hello from Seattle.

CHUCK:  So Eric, you’ve been around for a little while. I have to point out that I’ve been preparing for this episode. I’ve been using RubyGems all week.

[Laughter]

ERIC:  How can you not?

CHUCK:  That’s a good question.

ERIC:  [Chuckles]

JAMES:  You know, that’s actually kind of funny because we talk about that now, how can you not. But I actually remember a time when we used to like when a library was all one file or a folder that you could really easily grab so you could just throw it in a vendor directory and require it directly or something. That actually used to be common in Ruby land.

ERIC:  Yeah, I remember.

DAVID:  Is it not still good practice to not have your libraries do require ‘rubygems’? That better be because they’re there automatically now, right?

ERIC:  Yeah. There’s no need anymore. It just happens.

AVDI:  Well, except for backward compatibility, really old Ruby versions.

CHUCK:  Yeah.

DAVID:  Yeah, Ruby version 1.old.

ERIC:  Yeah.

CHUCK:  [Laughs]

JAMES:  But even then, it was considered bad practice to directly require RubyGems.

ERIC:  I think so, at least inside of the library.

AVDI:  Inside the library, yeah. I mean, in your application…

DAVID:  Yeah, yeah.

JAMES:  Right.

AVDI:  If you expected it to run on 1.8 you needed to require it at some point.

ERIC:  Yup.

CHUCK:  Yup. So, I’m curious. I haven’t been around pre-RubyGems. So, how did we get RubyGems?

ERIC:  Well, let’s see. Was it 2004 RubyConf that Chad and Rich and Jim wrote it during, or at least the first draft of it, during the conference? I think that’s around the right timeframe. And then it grew from there. And then let’s see. So, they got it up to a 0.7 or a 0.8 or thereabouts. And then I wanted to write a tool that would tell you if all the tests were passing on your gem when you installed it. So, you install it and you’d run this command and then it would run the tests and then upload those somewhere. So, when I started to do this, I was like, “Well, I should just figure out how to run it on all the gems.” And then there was no real API inside RubyGems to do all that. You’d have to shell out. So, I was like, “Well, I’ll fix that first.” Then I never got around to writing that thing that I was originally writing. So, I guess this has been a multiyear yak shave.

CHUCK:  Very nice.

JAMES:  That’s awesome. Eric’s still working on RubyGems to this day.

ERIC:  Yup.

CHUCK:  So, one thing I can say that will date me a little bit is I do remember working off of, or having it pull stuff off of RubyForge.

ERIC:  Yeah, that was, let’s see, Tom Copeland ran that on the RubyForge site. It had the script to build all the old indexes that took forever to download.

DAVID:  I actually remember writing a gem called kitchen-sink and having to fill out the paperwork on RubyForge to get them to please include my library.

CHUCK:  [Laughs]

ERIC:  [Laughs]

DAVID:  And it took them five days. You could tell it was one guy that was buried, handling everything. And five days later, “Yeah, we’ll approve this.”

ERIC:  Yeah, that was probably Tom Copeland who was an unsung hero for many, many years.

JAMES:  Yeah. RubyForge was just recently shut all the way down, right?

ERIC:  Yup.

CHUCK:  Yeah, that’s since we have RubyGems.org now, which I forget what the project was actually called.

JAMES:  Gemcutter.

AVDI:  Gemcutter.

ERIC:  Yup.

CHUCK:  That’s right.

AVDI:  Okay, so RubyGems. Even I realized I was a little bit hazy on what exactly it did until recently, because I did some Ruby Tapas Episodes on loading code, the various ways of loading code, recently. And I realized I didn’t remember which things just Ruby handles, and which things RubyGems is responsible for, and what it added to the mix when it came around. So, could you just talk a little bit about what its core functionality is?

ERIC:  There’s two pieces. There’s the piece that installs the gems, and that’s the big piece. And then the smaller piece is loading code. So, figuring out which file to load, which gem that lives in, and then adding that gems paths to the load path so that when Ruby’s require runs, it’ll find the library that you wanted to load. So, that’s the very basic view of it.

AVDI:  So, for the installing part, it’s the combination of downloading and then it’s unpacking and sticking the code somewhere, right?

ERIC:  Right.

AVDI:  What did that replace? What came before that?

ERIC:  So, before that there were I think the most used tool was setup.rb. And setup.rb would put the code to where RubyGems lives now if you update RubyGems. So, there’s one that ships inside Ruby. And if you update it, it goes in the user library dir. And inside of the Ruby install directory. And so, it used to be that all the code lived there. If you installed, I don’t even remember the stuff that’s still around from back then, when you use setup.rb, what you got to install to that same directory.

AVDI:  Any Ruby library you installed, it would actually wind up in your Ruby install directory?

ERIC:  Yup.

AVDI:  In site local?

ERIC:  Yeah, yeah, in the site local directory.

AVDI:  And RubyGems changed all that.

ERIC:  Yes.

JAMES:  We should probably say that setup.rb, it was an interesting thing. It was just literally what it sounds like. A file setup.rb that was a giant chunk of code that you dropped in a directory, the directory of your project, I won’t call it gem yet, and it made all these assumptions like binaries were in bin and your main code was in lib, et cetera, et cetera. And then it gave almost a make-like interface I would say, for a typical project for doing things like installing and stuff like that. It was a very strange thing. It’s cool.

AVDI:  And if you got a new version of the library and ran setup.rb, well it would just be overlaying whatever was already installed there, right?

JAMES:  Yeah, I think so.

ERIC:  Oh yeah. There may have been a way to uninstall stuff. But I don’t remember. It’s been [inaudible].

AVDI:  And you probably had best do it before you installed a new version.

JAMES:  Yeah [chuckles].

[Chuckles]

AVDI:  So, that was a big deal was that…

JAMES:  Yeah, I don’t think there was any super clever diffing going on there or anything. [Inaudible]

AVDI:  So RubyGems, it introduced the idea of having a separate directory for each version of a gem as well, or a library.

ERIC:  Right.

AVDI:  Right.

ERIC:  Right. So, you could have multiple versions installed at the same time.

SARON:  So, what would you say is the biggest problem that RubyGems solved for a developer?

ERIC:  It made it easy to install and uninstall libraries and also to find libraries that you may not have known about that you were looking for, because there was now an index that you could at least search for the names. Or if you were like, “Oh, I want something that does XML,” then you could try and find an XML gem more easily than you could with, maybe your package was on RIA, maybe it was on RubyForge, maybe you’d never listed it anywhere except by sending it to the Ruby-Talk mailing list. So, now you had a more central place to go and find gems as well.

JAMES:  That’s a good point. And I didn’t really consider the discoverability aspect of it. It is a powerful thing to be able to search for a specific thing like you say. That’s nice.

ERIC:  I think we could still use some work on the search. But it was certainly better than it was before.

SARON:  So, I wanted to talk a little bit about your role maintaining code. I know you’ve been doing this for about, six years I think is what I saw. And it started as a hobby and now it’s a fulltime job. How did you initially get started on working on open source?

ERIC:  So, I think the first thing, big thing, that I contributed to was the Mozilla project back before Firefox was Firefox and there was a separate browser or any of that stuff. So, I was just hanging around, saw it on probably Slashdot or something. It was like, “Oh, I’ll go and check this out. I can probably figure out or report a bug or something at least.” And so, I ended up, I think I have some code still in the browser that does part of the page info dialog. It was just like, “Oh yeah, I can probably do something like that.” So, I went over and wrote it and it ended up getting accepted.

And then for, since I had that experience, when I started doing more Ruby stuff, the community was so welcoming to that kind of, that approach. And I just kept going.

SARON:  Nice. So, it sounds like the community definitely made it easy for you to make those contributions as well.

ERIC:  Yup. Yup, I think that’s one of the reasons I like Ruby is that the community is nice generally. They’re people that I can respect and that I hope have respect for me too.

CHUCK:  So, I’m curious. How has RubyGems changed over the years?

ERIC:  I think the biggest changes have been in how the index format is stored, because the very first index was not scalable to the number of gems we have now. It was a single file YAML index. And so, I…

JAMES:  [Laughs]

ERIC:  With all of the information for all of the gems in it, so by the time that we…

JAMES:  [Inaudible] should be fine.

ERIC:  Yeah, I think by the time that we switched away from that one, it was around 120 megabytes.

[Chuckles]

CHUCK:  Wow.

JAMES:  That’s awesome. Anytime you had to communicate with the RubyGems server you just sent 120 megabytes back and forth?

ERIC:  Well, before it got that big there was an incremental update or add-in so I could go and be, “Well, I’m a thousand behind so I’ll maybe fetch the big one. Or if I’m less than that, then I’ll go and fetch all the individual gems.”

JAMES:  Gotcha.

ERIC:  But it turned out, that didn’t scale either. So, we moved onto a more condensed index format where you’d only fetch the specifications you needed. And then now that’s been partially replaced by Bundler’s dependency API, so you only fetch the gems you need. You say, “I need a version of Rails. Just give me all the versions of Rails.” And you can give it a couple of different gems and it’ll give you all of them at once. So, it’s more of, compared to a flat file, it’s more intelligent. Andre Arko is working on a new index format that will replace the current index format and the Bundler API with the new thing.

CHUCK:  So, I remember talking to Andre. It sounds like Bundler and RubyGems are merging, or RubyGems is going to take over some of the responsibilities that Bundler has.

ERIC:  Yeah, that’s a very long-term goal. So, I recently left AT&T and got a grant from Ruby Central to do some work on the shortest possible term goal for that, which is having the RubyGems resolver behave the same way as the Bundler resolver. And so, I’ve been working on getting some of the specs from Bundler to run on top of the RubyGems codebase by writing evil shims. And then when enough of the specs run then we can consider running, having Bundler use the RubyGems resolver rather than each of us having our own do the same thing. But if somebody updates on one side, then the other one is behind.

AVDI:  Talk a little bit about what that adds to RubyGems.

ERIC:  So, the resolver or the…

AVDI:  The resolver, yeah.

ERIC:  Yeah, okay. So, in the olden days, RubyGems would use a topological sort. And that was about the only intelligence it had for figuring out which gems would work with which other gems. But it wasn’t smart enough to go and figure out how to backtrack in case your dependency set got large enough that it was like, “Oh, well gem C over here is not compatible with gem Y over there,” because once Rails came around and everybody was writing more libraries and using more libraries, just trying to use all the latest versions, you’d have an incompatible set. And so, Bundler added a resolver that would be able to go and backtrack to be able to solve which dependencies or which gems would all work together. So, that was the main reason that Bundler was written.

And then, let’s see. I believe it was around last year, Evan Phoenix wrote a resolver for RubyGems that works the same way. So now, both RubyGems and Bundler have roughly the same features as far as being able to figure out, “Oh, well you’re going to use this lower version of this other gem so that your entire set works.” And so, now that’s been shipping in RubyGems for the last two minor versions I think. But we’re, the RubyGems version is not quite, or doesn’t quite match all the features that Bundler has. And then there are still a few bugs I’ve been finding as I’ve been working on it and people have started using it.

JAMES:  Interesting. What was the initial motivation to duplicate that functionality?

ERIC:  Bundler uses a lot of RubyGems functionality. And it doesn’t seem to make sense that that should live only in Bundler, not in RubyGems, because RubyGems should be able to install the same, a set of gems that works all the time. And there’s no reason that that should be a feature it doesn’t have.

JAMES:  So, long, long term like you said, is the idea that Bundler would be retired in favor of that functionality just being a natural part of what RubyGems does?

ERIC:  That’s not something that we’ve discussed yet as far as myself with Andre and Terrence who maintain Bundler, because Bundler has its own set of commands. And so, it may be in the far, far future that there’s Bundler as a thin shell over the RubyGems functionality, or it may be that it still has its own value add stuff that goes in Bundler and only makes sense in Bundler. But what that’s going to look like is not something that any of us can predict yet just because there’s so much to do before we even get to being able to discuss that.

CHUCK:  So, the discussion that we’re having here makes me wonder a little bit. Are there features in RubyGems that most people just don’t know about or don’t use? Most people use it as the way to get new libraries into your application. Is there more to it than that?

JAMES:  Yes.

ERIC:  Yeah.

JAMES:  [Laughs]

ERIC:  But I think the rest of the features are pretty obscure, like there’s a feature for going and checking to make sure that all your gems are okay. And I don’t think anybody runs that ever because I think the last bug report I saw on it was years ago. There’s a bunch of other commands that nobody typically runs other than install and list and search. And they’re the commands you would expect in a package manager but the ones that you don’t need to use often unless you’ve done something weird to your RubyGems library that you probably weren’t supposed to do in the first place.

JAMES:  What about gem server? Is that still there? It used to be a big deal.

ERIC:  Yeah, it’s still there. See, I’ve actually done some work on that, ish. So, it used to be that when you installed gems it would build both RDoc and RI at the same time. And now it only builds the RI. And the server uses the servlet that ships in RDoc to go and display HTML just off of the RI data files. So, you don’t have to generate two sets of documentation, just one now. That is if you still have that enabled.

JAMES:  Yeah, that was a common use for it way back when. People would run gem server and then hit the local URL, and you could have all the documentation of all the gems that were installed on your system. So, you could go look at documentation, say when you didn’t have internet connection or something like that, real conveniently.

ERIC:  I’m probably one of the few people that use it frequently. But there I would get the occasional bug report about it. Yeah, and it’s super handy if I’ve got slow internet. If I’m in a café or something, I’d be like, “Oh, how does such and such work?” I’ll just go and pull up my local server and go looking through the documentation to go and see what I’m missing or look up some method arguments or something like that.

JAMES:  The server actually in functionality though basically does become a full gem server that then you could install gems from. Is that right?

ERIC:  Yeah, that’s right.

CHUCK:  That’s pretty cool.

JAMES:  You don’t see that used too much. One use I can think of, I believe Sidekiq, the Rails background job system, the author does a Sidekiq Pro which is mainly about some other features and support and stuff. And I believe he does a private gem server. So then, if you sign up you get an authentication in his private gem server. And that’s how you install Sidekiq Pro, which is interesting.

ERIC:  And I think there’s also, there’s a bunch of companies that run their own gem server because they build a gem and then they want to use it only internally. And I think Geminabox is the popular tool for that, which I believe is a packaged version of the gemcutter project that might have some extra features on top of what RubyGems.org has. But you can go and have accounts and push gems to it. And it works with gem push and gem owner and all those commands for managing the gems you’ve released.

CHUCK:  So, I’m curious, talking about the structure of gems. How are they packaged up? Are they tar files? If I remember right. And you have a gemspec and things like that. Why are those structured the way that they are?

ERIC:  Actually, the original gems were self-installable. So, at the very front was a Ruby script that had enough smarts to go and talk to RubyGems to install the rest of the file. And then there was a YAML gemspec. And then there was base64encoded file chunks for the rest of the, for all the files that were in your gem. And then there is no compression there. And I’m not sure why those changed before I started.

And then after that, it was switched to the tar format. But it’s kind of backwards where there’s a tar on the outside with gzipped or tar gzipped files inside. So, there’s one for the specification and then there’s one for all the file contents. And then if there’s a signed gem, you can have extra signatures. And then I think recently I added checksums so that the gem can at least have an integrity check so that you can tell if anything got corrupted when it was downloaded or transferred or moved around.

And so, what I’d really like it to be is that it’s a tar.gz with a tar file inside so that the compression runs over the whole thing. But it’s really difficult to change those.

AVDI:  Where are we at with gem signing?

ERIC:  I’m not a cryptologist or a cryptographer or whatever that is. And so, I’ll try to delegate this as best I can. The last best project was an implementation of, I think it’s the update framework which Python uses to sign its gems. And I think that that was mostly finished. But I’m not sure where the authors that were working on that have wondered off to. So, I should probably go try to track them down and see if that can get farther along. But right now, there’s built in is the OpenSSL x509-based signing system which has a number of problems to it, both technically and socially. And then there was also a PGP-based solution that has basically the same problems as the built-in one, just PGP-flavored instead of x509-flavored.

DAVID:  So basically, you can build a really good lock but the problem is still the hinges?

ERIC:  Yeah. And there’s with PGP solution and the x509 solution, the major problem is that what happens when the key expires. Now you can’t install the gem anymore because the key is invalid.

DAVID:  Right.

ERIC:  And you’re like, “Well, do I still trust this even though the key is expired? I guess so.”

DAVID:  Right. But if a key has been compromised conversely, don’t you have to expire… I mean expiring the key is the only way to get people to stop installing the gem that’s compromised, right?

ERIC:  Yeah. And there’s just not enough infrastructure around this.

DAVID:  Yeah.

ERIC:  Yeah, that’s part of it, is there’s not enough infrastructure around it. And also the tools are not as easy to use. The security tools are not as easy to use as they should be.

DAVID:  Yeah.

ERIC:  Or could be. And the idea of the update framework is that you sign the metadata and you make it all transparent. So, you have secure channels for uploading by HTTPS and HTTPS for download. And then so long as you know the update, the metadata about the gem and its checksums and those things, is secure, then you can verify that the bytes that you got are the right ones.

DAVID:  Yeah.

ERIC:  And so there’s, people who know about cryptography tell me this is good so I trust them.

DAVID:  Yeah. At the end of the day, there is a lock. We look at a lock and we think the purpose of this tool is to keep bad people out, or keep the wrong people out. But if you think about what a lock does, day in and day out, for 99.99999% of locks out there, it’s let the right people in easily. And it’s a double-edged sword, right? If you make the lock too easy to get through, then the bad guys can just breeze through it. If you make the lock too hard to use, then the people who have to use it every single day hate it. And yeah, you run into that same kind of problem.

ERIC:  Yeah. The people who wrote the PGP one were all, “Yeah, this is great. This is great. It’s the best.” And then they go and read it and I compare it to what RubyGems has built in. I’m like, “Well, it’s really exactly the same.” It’s just a different flavor.

DAVID:  Yeah.

ERIC:  And that’s not what I want to present to users as, “Hey, this is great,” as something that they don’t have to worry about. It’s like…

DAVID:  Yeah.

ERIC:  You’ve got great secure gems, downloads and uploads, and you’re done. And right now, that answer is HTTPS downloads.

DAVID:  Yeah.

ERIC:  And so, the only problem is, are you using HTTPS or not?

DAVID:  That one leads to securing the endpoints, right? As long as I trust that nobody has infected your repo and that I am still talking to the correct repo, and that sort of thing, so [inaudible] so long as I believe that the connection between here and there is stable, then I sort of trust HTTPS. The NSA probably has a hack into it. And so, bad guys may. But the kind of bad guys that can crack HTTPS…

JAMES:  No, no. They’re [inaudible].

CHUCK:  [Laughs]

DAVID:  Well, they’re the kind of… I lumped the NSA into the same group. It’s bad guys that are so high above my pay grade that I’m beneath their notice.

[Laughter]

DAVID:  Which is essentially secure, right? And yeah, the question then becomes, did what I download match what the author actually put up? And at the end of the day, that’s still just another onion because what if the author’s infected with a virus and uploads something, right? Security’s fun. I know. I’m in the same boat as you, Eric. I’m not a cryptanalyst. But I’ve read ‘Applied Cryptography’ which is like an inch-a-half thick book by Bruce Schneier whose job it is to convince you to stop trying to do cryptanalyst things because you’re not a cryptanalyst. And it’s a great book. Everybody should read it before they accidentally try to secure their system with duct tape and happy thoughts.

ERIC:  Yup.

JAMES:  What kind of features other than moving parts of Bundler that made sense in RubyGems into RubyGems can we expect probably in RubyGems’ future?

ERIC:  Let’s see. I wonder what’s on my plate. As far as user-visible features, I don’t have a lot of things that I would be like, “It would be totally awesome if RubyGems had this.” Besides pulling over features from Bundler, there’s been work ongoing for duplicating gemfile support. And so, that’s pretty much there. Every release I have somebody who says, “Oh, this part doesn’t work.” I’m like, “I didn’t even know that was a thing.” And so, it’s pretty easy for me to go and implement that and add that. But as far as what my wishes and goals for RubyGems are, I want it to not break when I would do releases. And I’ve had a pretty good track record at that, I think.

SARON:  How do you end up prioritizing features in general? Do you just have your own personal wish list or do you ask the community what they need? How do you know what to focus on next?

ERIC:  I use GitHub issues for this. I have three categories of feature request. So, I have the ones that I’m going to put in the next feature release. I have ones that are marked future that I think are, I don’t have time for in the next release timeframe, whatever that might be. And then I have ‘unfulfilled promises and broken dreams’. I actually have these, if you go and look at the GitHub issues, you’ll see these three milestones that are pretty much the only three that I have.

And so, anything that I think is too difficult or too outlandish goes in ‘unfulfilled promises and broken dreams’. And I tell them, “Hey yeah, this sounds nice. But it sounds way too hard for me to do. So, I will totally help you write this, but I’m not interested in having it as a feature.” And then maybe after they’ve sat there for two years, then I’ll go and close those out. But it’s very much self-service in terms of, “Hey, I want this thing.” Well, I’ll totally consider that feature and if it sounds like something that would fit in RubyGems I’ll help get it added to RubyGems.

And if it’s something that can be answered by a plugin, then I’ll say, “Well, you should write a plugin for this. And then, you’ve got these hooks,” or, “You should write a plugin for this but I need to write a hook for you.” And then, if I go and have people add it as a plugin, then I don’t have to maintain it. I only have to maintain the hook, which is a lot less code than a feature that adds 20 methods that somebody’s going to use and then ask me, “Hey, how does this work? Why doesn’t it work this way?” And I’ll be like, “I have no idea.” And now I have extra time spent maintaining that instead of something that, some bug that I added that’s in some core functionality that five or ten people have said, “Oh yeah, this is totally a major issue for me. Can you fix this right away?”

So, I feel that I can give my users better service if I push back on some things and say, “Well, I’d rather have you maintain this because you’re the one who’s super interested in it.” And when that’s not in RubyGems, it’s much easier for me to have happen. And then if it ends up getting super popular, then maybe it can be reincorporated into RubyGems. But maybe not.

SARON:  Is the third category really called ‘unfulfilled promises and broken dreams’?

ERIC:  Yes.

SARON:  That’s amazing. I also…

[Laughter]

DAVID:  Awesome. [Inaudible] support.

SARON:  I have a similar list but just not in code.

JAMES:  That’s amazing.

DAVID:  Eric, I have a nerdy DevOps question for you. And we can skip over it if you don’t think it’s relevant. But I’ve always wondered how RubyGems is built and deployed. I know I can type gem search and it will go search something somewhere. And it’s a lot faster than it used to be and that’s great. And like you said, there used to be this 120 meg index file. And if I’m not mistaken, the gem client back in 2009, you had to download that client and search it on your own computer, which made it sound like RubyGems basically FTP. Can you describe what is going on in RubyGems now? What is the monster? It’s a service now, but what’s in it? Does it have elastic search? Is it on multiple servers? Does it have a good hard drive? What’s going on with it?

ERIC:  So, I only know an overview as far as the RubyGems.org half. So, we’ll start with your search question. So, your search works basically the same way that it always has. It goes in, goes and downloads the index, downloads a new copy of the index, looks through. It scans through it for a regular expression or a literal string and gives you gems that match.

DAVID:  Okay.

ERIC:  So, that’s been basically the same as it always was.

DAVID:  Now, that’s not really slow on my computer. It doesn’t feel like I’m downloading 120 megs every time.

ERIC:  Yeah, because as the indexes have evolved, we’ve gotten better at writing the indexes so that you don’t have to download so much stuff.

DAVID:  Okay.

ERIC:  Now, I think the, let’s see, how big is the index? So, you just download the latest specs which has the name of all the gems in the index. Then that’s 2 megabytes right now.

DAVID:  Okay.

ERIC:  And so, yeah, so a 2 megabyte file is a lot smaller and…

DAVID:  Did the old file have the info block for each gem?

ERIC:  Yeah.

DAVID:  Oh, wow.

ERIC:  Yeah, it had all of the info. I think it even had all the files in [inaudible].

JAMES:  Please hold while we download your database.

ERIC: Yeah.

DAVID:  Yeah.

CHUCK:  [Laughs]

ERIC:  Yeah, so RubyGems.org the service is run on AWS. It’s funded by Ruby Central. So, attending RailsConf or RubyConf, your ticket price goes to supporting RubyGems the service. And it runs on AWS. I think they’re on multiple servers now. The gems are stored in S3. And there is a mirroring infrastructure with mirrors in various cities that I have no idea which ones they are.

DAVID:  Multiple colos though, because you hear about GitHub going down. But you don’t hear about RubyGems going down.

ERIC:  It does on occasion. I believe there was some maintenance work done on it in the last two months. And so, it was down for a little bit while they went and switched from one server set to the others. So, I believe the people that work on that are, I don’t think I’m going to get them all, but they’re Sam Kottler, there’s David Radcliffe. Nick Quaranto still works on it somewhat and Evan Phoenix. And I think there are one or two other people that work on the server side. And it’s very nice, because it means that there’s less for me to worry about. So, I can just work on the client part and I can trust that the RubyGems.org’s infrastructure is in excellent hands with people who have the time and energy to work on that.

DAVID:  Yeah. And these guys are the real heroes of RubyGems, right? Because all around the world, developers open up, we open up our machines, we go to a terminal, and we type gem install rails and it just works.

ERIC:  Yup.

DAVID:  Because the servers are there and everything runs. That’s awesome.

ERIC:  Yeah. Yeah, I should also mention Andre Arko and Terence Lee, because they maintain the third piece, which is the Bundler dependency API, which lives on Heroku. And I think there might be one or two other people that work on that.

DAVID:  Yeah.

ERIC:  And so yeah, so that’s, now RubyGems uses that same API that Bundler does to speed up gem install.

JAMES:  It’s cool how the collaboration of these projects, Bundler coming up and getting popular to solve a particular problem has then in turn made RubyGems better.

ERIC:  Yup.

CHUCK:  So, I want to talk a minute about the plugins. What kinds of hooks and what kinds of plugins are we talking about here?

ERIC:  So, there are hooks for the life cycle of a gem. So, pre and post-install for a gem, pre and post-uninstall for a gem, and then there’s a hook around installing a set of gems. Those are the basic six. Or actually, I think there’s only five. There’s only one that fires after, like if you do gem install rails and Rails installs Active Support and Active Record and so on, and so on. Then there’s one that fires at the very end of that. So, that last one, RDoc uses that to go and build the documentation. And there are also some extra hooks in there for automatically figuring out which documentation to build. So, instead of typing no-rdoc, no-ri, you could write your own documentation generator. And I think for some reason, YARD still doesn’t use it, even though that’s why I wrote it. And I think that’s…

CHUCK:  [Chuckles]

ERIC:  I think Loren was the one who was like, “Yeah, I totally need this hook,” so I went and wrote it. And then I don’t think he’s ever switched over to it. And then the ones that fire around installing each individual gem can be used for various different types of statistics. And then I’m trying to think of one that somebody has used. But an example’s not coming to me.

And then there’s also, you can add your own commands. So, there was a gem open command that would open the directory of the gem in your editor so you could look around. Now, that originally started, I think there were two different command plugins for that. And now, they’ve been integrated into RubyGems itself. So, I think that was the last command that was added, because there were a lot of people that used it.

JAMES:  Are RubyGems’ own command written as plugins?

ERIC:  There’s a list of them. So, it’s basically the same infrastructure with a call to go and have that registered. It’s built into RubyGems itself rather than being a search and discover kind of thing. So, if you write your own plugin, there’s a special file you add, rubygems_plugin, that goes and fires the hook to add the command. But if you…RubyGems just doesn’t use that discovery mechanism. It just says, “Well, this is a list. Here it is.”

JAMES:  That’s cool. So, can I talk about the future I want out of RubyGems [chuckles] someday?

ERIC:  Sure.

JAMES:  I’ve always wanted, we were talking about this in the preshow, but there was in ancient history times there was, Eric game me the name the RPA, the Ruby Package Archive or something like that. And it was like a curated set of things you can install, like RubyGems, packages I guess they were called. And like I guess sort of Debian does or things like that. Not that I want that. But I’m surprised that there’s never been, I actually thought it would come about when we got gemcutter. I guess it did exist in the RubyForge era.

But I would love to be able to see, “What is the canonical XML gem for Ruby in some way?” And I don’t even know 100% what that means. Does that mean that everybody installs this one? It has these ratings or stuff like that. One I’m thinking of kind of exists in Ruby Toolbox. I’ll put a link to that in the show notes. And it’s with [inaudible] use. But I think it would be kind of neat to have that integrated into RubyGems someday and could really make something like search powerful, if you could be like, “Well, I need to find this thing.” And you got the things most people use or something like that as top choices. It seems like that could be cool.

DAVID:  Like a Yelp for RubyGems?

JAMES:  Yeah, something like that.

DAVID:  I almost think it’d be cool it was, Eric you can feel free to stop writing in the hopeless dreams category because it’s just me daydreaming. I’m assuming that you wrote down what James said, but you can assume that you don’t have to write this down.

JAMES:  I’m assuming he was sitting over there thinking, “I’m not giving you comments, ever.”

DAVID:  Yeah.

CHUCK:  [Laughs]

DAVID:  Actually, I wouldn’t be surprised if he’s sitting there thinking, we should ask him what he’s thinking because he is a guest on the show. But it’s actually more fun to guess. He’s probably sitting there thinking, “Already in there, dudes.”

ERIC:  [Laughs]

CHUCK:  [Laughs]

DAVID:  Do you have a note for add a review system?

ERIC:  So, I think that would live one the RubyGems.org side, which I’ve already disclaimed responsibility for. So, I’m not a gatekeeper for this feature at all at any way.

DAVID:  Wait a minute. So, if you’re not part of RubyGems, what do you do here, Eric?

CHUCK:  [Chuckles]

ERIC:  So, I maintain the client. And then the server is up to other people.

DAVID:  Mm, okay.

ERIC:  Yeah, so I think this is a great idea. But first, the ratings have to exist on RubyGems.org before I could go and download them and say, “Oh, you want XML? You should use Nokogiri,” and edit, Nokogiri’s the canonical XML library. I hope everybody knows that.

DAVID:  Yeah. And you’re right that this would be totally on RubyGems.org, because it’d almost be like Amazon reviews, right? You’d want to go to the website, check on the gems, okay. And if it would be anything like Amazon, I would actually find negative reviews more helpful because the positive reviews are all going to be, “This is great. Use this gem.” And that’s like a, “Sucks/Rules”. You might as well just put a votee on it and just 1500 plus ones, that’s all you need.

JAMES:  Just to be clear, there’s more value than just straight up reviews. For example, Ruby Toolbox which I mentioned earlier has categories.

DAVID:  Yeah.

JAMES:  So, if you want a templating engine, you can check a templating category. I hope that exists. I didn’t actually check. But it would have ERB and Erubis and Haml and all of those things in it. So, being able to search by category, I think might help, especially when Eric mentioned earlier the discoverability of RubyGems which is awesome. But if I do gem search xml, I don’t hit Nokogiri unless it pulls the description or something, right?

DAVID:  Mm, okay.

ERIC:  Right.

DAVID:  See, I was thinking the advantage of a negative review is somebody would be like, you’re looking at Nokogiri and it’ll say on there, “Don’t use this if you’re using the OpenJDK 7. Make sure you’re using the Oracle JDK.” I don’t know if that’s an actual restriction on here. I don’t think it is. But that kind of thing, where somebody will post a negative review and you’re like, “I’m already using the thing that you said doesn’t work, or the thing that you said I have to use.” So, this was a totally helpful negative review because I’m doing it weird and here’s this negative review that says, “Unless you’re doing it weird in exactly this way, don’t use this.” And those reviews end up being the most helpful. So, you can go in and say, “Oh yeah. That negative review was actually really helpful.”

ERIC:  Yeah, and I think the Apple App Store has reviews per version.

DAVID:  Yeah.

ERIC:  So that, if there was some nasty bug in a version, then the author doesn’t get penalized for it.

DAVID:  Mmhmm.

CHUCK:  Yeah, I believe that’s the case.

JAMES:  Anyway, that’s just my pie in the sky, I would love to see.

DAVID:  Yeah.

JAMES:  Somehow integrated into the system someday, because I think it would be cool.

ERIC:  Yeah. Well, fortunately, it’s open source. So, somebody can totally get right on writing that.

DAVID:  So, who main-…

JAMES:  Be right back.

DAVID:  Yeah. Who maintains RubyGems.org?

ERIC:  I think the primary committers now are, there’s Sam Kottler, sferik, I think David Radcliffe. And I can totally merge pull requests over there, because I’m an admin on the RubyGems.org. But it’s not something I have much familiarity with.

DAVID:  Yeah.

ERIC:  So, other than knowing how Rails apps work, I’m like, “Yeah, this looks like good code for a Rails app.” But I’m not sure what their vision or any of that stuff is. So, I tend to stay out of their hair.

CHUCK:  So, does that mean you guys only talk about the boundary between the two projects? Or do you ever actually sit down and say, “We’d really like to add this to the overall ecosystem so that means you guys will probably have to build this part and I’ll build this into the client and there here we go”?

ERIC:  I think the next major work on that is Andre’s work. And he’s been developing both halves, the client side and the server side, at the same time. So, there’s not been anything that I’ve needed for the server to support. And sometime, there was a feature request. Somebody said, “Hey, you should be able to go and add a repository URL to your gem. And then when you upload that to RubyGems, that automatically fills in that field in the notes, in the links section of your gem.” And I’m like, “Yeah, well sure. But you can use the metadata inside the gem to go and hold that link. And then RubyGems.org can go and pull that out when you do the update, or when you do the push the gem up.” And so, some of that’s just been like, “Oh yeah, you should go talk to these other people and use this metadata key. And you’re good to go.”

JAMES:  Pretty awesome. So, now that RubyGems is a part of Ruby itself, comes with Ruby, how has that changed things? Maybe talk about gem prelude or something. That was a big concern back in the 1.9 era.

ERIC:  Well, I think the biggest change is that it’s a lot more stressful for me because if I had a bug…

DAVID:  [Chuckles] Sorry.

ERIC:  [Chuckles] If I had a bug and it’s a big bug, that’s going to just ruin a Ruby release.

JAMES:  That’s awesome.

ERIC:  So, that part can be quite stressful. But…

JAMES:  I now have this image of Eric sitting there typing, just sweating bullets.

ERIC:  That’s how I feel right around when it’s release time. It’s like, “Okay. If I make this change, what could possibly break? And do I have tests around it?” And if I don’t, let’s go back and build those back in. So, personally that’s been the biggest thing.

DAVID:  Do you ever listen to the guys talking about continuous deployment and just get angry? Do you grind your teeth?

ERIC:  The more frequently I deploy, the better I feel, because in the meantime…

DAVID:  Awesome.

ERIC:  You’re like, in the meantime between Ruby releases, and I have all this time for people to find bugs, as it gets closer to the wire is when I start to get nervous like, “Oh yeah, there’s this big bug that you added,” and I’m like, “Crap. What is this?” Hopefully I’ll fix it right and there won’t be another one.

DAVID:  Yeah.

ERIC:  As far as the internals, there’s been some feedback from Ruby in order to make the startup of RubyGems a little faster. So, RubyGems uses autoload to only load just the very basic parts it needs in order to go. And when you require something that’s not in your default load path that it can go find gems, and part of that’s part of the prelude. And now prelude is a lot smaller than it used to be. And it’s a lot less intrusive so that you don’t get in these… there were some weird places that the code would be in when we were still figuring out how to make it work right. So, now we’ve smoothed those out. So, it’s easier on me. But as far as what users would see, it’s been pretty much the same experience.

DAVID:  Mmhmm.

SARON:  So, when I hear you talk about the stress of deploying and releasing and hoping there isn’t a bug and hoping you don’t break a lot of stuff, it reminds me of Seth Vargo who wrote a blog post a couple of weeks ago. He’s a release engineer at Chef who actually decided to take a leave of absence from maintaining that open source project because it was just so stressful and he was receiving a lot negative feedback and he got a few death threats. And it made me wonder, for people who do a lot of open source work and are responsible for such popular, well-known projects, how stressful is dealing with just the feelings of the community and making them happy? How’s that been like for you?

ERIC:  I think over the last couple of years, it’s been pretty good. I’ve done a pretty good job of not doing anything hurriedly I guess. And in the past it’s been more difficult, just because RubyGems is old code. And there are a lot of nooks and crannies and half-APIs that people use. And some of those I want to get rid of, just because it’s like I don’t want to maintain two ways of doing the same thing because we now discovered a better way or doing it and it’s much simpler and the API is better. And so, sometimes people have been using those old APIs and then trying to remove them has caused lots of people to get upset. And so, I’ve learned a lot about how to manage those kinds of transitions better.

And so, lately when I’ve made small changes that are backwards incompatible, it’s been, “Oh yeah, this thing is broken.” But it’s been much, I think because I’ve handled the transitions and knowledge about the API transitions better, that I’ve not gotten as much negative feedback as I have in the past. It still gets stressful and you’re like, “Okay. This is a new major feature release and there are ten new features. And two of them are really big and I know that there’s going to be bugs.” The supporting gemfiles has been a lot of bugs in that. But overall, people have been like, “Yeah, I tried this and it didn’t work. And here’s my gemfile and here’s the error.” And so, when I get feedback like that where it’s just like, “Yeah, here’s everything you need to fix it, I hope,” that’s been a lot more pleasant for me than it has like, “Oh, it’s all broken and you’re a terrible person.”

SARON:  Yeah, definitely. So, when you say that you handle the transitions better, what do you mean?

ERIC:  So, there was a large debacle around the RubyGems 1.4 time I think, where we’re like, “We want to get rid of these APIs.” And nobody used them, so we’re going to make them start warning. But unfortunately, lots of people used them. So, lots of people got lots of warnings. And lots of people are unhappy, which was not a great time.

JAMES:  So, I actually remember this era. And so, if I can add my outside memory of it, I think the problem was that anytime you would install a gem, there would be this stream of deprecation warnings. But the problem was that I as a user was not the person who could fix those. It was the person maintaining that whatever, right?

ERIC:  Something like that, yeah.

JAMES:  Yeah. So yeah, it was a, and I had a lot of sympathy for it because I know that RubyGems is the ultimate expression of whatever you put in there is forever. How horrible is that? But yeah, it was hard because you would get this stream of stuff that created this anxiety in you whenever you used gems. And it was like, “But this isn’t for me,” kind of thing.

ERIC:  Yup, yeah. So, there’s been some strategies that I’ve added like don’t give the user a problem that they can’t easily fix. And when you do, when you make changes like there was a rather large change I made recently to where the extensions get installed. So now, instead of installing them in the same directory as the libraries, they get installed in a separate directory so that if you share a gem repository with different architectures like OS X, maybe you have a shared network drive and you deploy gems there, then you can share that between say Linux and OS X or something.

So, there were some difficulties around that. But I think I did a much better job with both the messaging and the, “Oh, if you have this problem run this command and it’ll get fixed right away.” So, those kinds of strategies have been helpful to reduce user outrage when they’re like, “What is this and what is happening and why am I having all these problems?”

CHUCK:  So, I’m curious, just a couple of question about your experience working on the codebase. Every codebase that I’ve worked on has these. They have the part of the code that I really like working on and the part of the code that I never want to touch again. Can you talk about what those are in RubyGems for you?

ERIC:  So, Evan wrote a new resolver, which is super nice and easy to work on. The problem is that it’s spread out across, I think there are probably 30 different classes in there. And making fixes on that can be kind of maddening because, “Oh yeah, the fix is super easy and straightforward but I just have to touch eight files.” And it’s all adding two lines to each file, maybe. But even still, it’s just like, “Oh, I can totally know how to fix this, but is it the right way because I have to touch all these things? Is there a way that I can do it or change the code so that I don’t have to touch all those things?” So, that’s a big modern annoyance.

And there is some code that I just have never touched because it’s always worked. But sometimes I got and look at it. Now, because I never look at it, it’s like, “Oh yeah, maybe the bug is over here.” So, I go look at this thing and I’d be like, “What is this? I have no idea,” just because it’s been working for so long and the bug is not actually in there because it’s I guess perfect. But as far as the major pain points, I think that I’ve eliminated all the ones that are like, “I totally never want to look at that code. It is horrible.” I think there’s some of that in some of my other code. Like in RDoc, there are some places where I’ve been working on this code for years and I still have no idea how it fits together.

CHUCK:  What have you learned working on RubyGems, I guess code-wise? Are there some lessons or takeaways that you want to share?

ERIC:  So, I’ve been working on this one project for so long that tests are incredibly, incredibly, incredibly valuable, because I will not remember a feature that I worked on and why it’s supposed to behave the way it does two weeks from now, let alone two years. And having a test that is going to fail when I try and change that in a way that breaks some expectation is immensely invaluable. Because then I can go, why is this test failing? And then I can go and read it and I can go and be, is that a valid behavior still? Because now that I know here, now that I’ve been reminded of it, is it still a valid behavior and do I need to change this test because it doesn’t make sense anymore? Or do I need to change the new bug or the new feature I’m adding? So, that’s been super useful.

The other thing that I’ve started more recently is being much more verbose in my commits and making much smaller commits. Sometimes, I’ll go back through history when I find one of these tests failing and be like, “Okay well, why does this line behave the way it does?” And if it’s one line in a 200-line commit that has a two-sentence commit message, there’s no way I’m going to be able to tell what I was thinking back then when I changed that line, or whether it was important. But when I make a 10 to 20-line commit and I write a paragraph about it, when I come back and look at that I can be, “This is exactly what I was thinking when I wrote this.” So, I have a much better idea of what my ideas were when I wrote that and why that line might be important.

JAMES:  You’ve learned to be nice to yourself.

ERIC:  Yes.

[Laughter]

JAMES:  That’s awesome. It’s a thing we could all get better at, right?

ERIC:  Yeah, leave myself breadcrumbs.

JAMES:  That’s very cool.

ERIC:  I find I do lots of reading of the code’s history. And when there are more commits in the history, more different commits per line in the history, then it becomes a much easier read than it’s like, “Oh there was this change that touched all of the lines in it. And now, oh I have to go and figure out how to jump past that to go and figure out where this line went.” That’s super annoying as far as backtracking what you did and why you did it. When I have those nice, small commits, I’m like, “I know what I did,” right away. It doesn’t take me an extra 10 or 15 minutes to go and track back and figure out what commit is relevant and then hope that it has a relevant message, even.

CHUCK:  Alright. Do we have any other questions or things to talk about with RubyGems? Is there anything we didn’t ask because we just didn’t think of it, Eric?

JAMES:  What’s your favorite gem command?

ERIC:  What’s my favorite gem command? Gem uninstall.

[Laughter]

JAMES:  Why is that your favorite?

ERIC:  Because one of the things I like to do is delete code. And there’s no better way to delete code than en masse. I don’t need this whole thing. Go away.

JAMES:  Yeah, that’s a good point. We should mention gem pristine. There’s a lot of problems I get into over the years that gem pristine can get me out of. You want to tell what that does?

ERIC:  Sure. So, it basically reinstalls the gem. Now it uses, it has a C extension and it records all the arguments for your C extension so that it can replay those and install it exactly as it was before. If you go in, sometimes you might have a bug. And instead of checking it out, I’ll just go and edit the gem itself and poke around in it. And so, if you’ve got all those things in there, you’re like, “Oh, well I need to go and restore the original,” you can just run gem pristine and give it that gem. It’ll reinstall it and take out any of the edits you made. That’s the basics of it.

JAMES:  Super handy command, especially if you upgrade your OS or something and then your C libraries are built wrong for whatever reason or whatever.

ERIC:  Yeah.

JAMES:  I’ve found it can get me out of problems like that.

ERIC:  Yup, upgrade some library the gem depends on, pristine will recompile it against that one.

JAMES:  Well, I think we should thank Eric for all of his crazy work. I can’t imagine. When I make a bug it’s usually just my boss yelling at me.

[Laughter]

JAMES:  I can’t imagine how many people yell at Eric, including me.

DAVID:  Yeah. Thank you for making all of Ruby work, please. Thank you.

ERIC:  You’re welcome. And I think I’ve been rather fortunate that even when people yell at me, they’re usually like, “Yeah, this thing didn’t work and here’s the error I got.” So usually, that’s about as far as the yelling gets, rather than, “You’re a terrible person and you should feel bad.”

JAMES:  [Chuckles] You should not feel bad. You should feel good. You’ve done an awesome job keeping it going.

CHUCK:  Alright. Well, before we get to the picks there’s one other question I want to ask and that is, it seems like if we wind up at the same conference you and I, I really enjoy winding up going to lunch with you and just chatting. What conferences are you going to be at here in the next little while?

ERIC:  So, the next two I have scheduled are RubyKaigi which is next week. And then RubyConf. I don’t have any other plans for other conferences in the near future. But I typically go to Ruby on Ales and Cascadia, which are relatively in my neighborhood.

CHUCK:  Awesome. Alright, should we do some picks?

JAMES:  Let’s do it.

CHUCK:  Alright. James, do you want to do some picks?

JAMES:  Sure. So first, some fun blog posts I’ve found recently. Sandi Metz has a good one about the shape of code and object-oriented programming and keeping related code together, and all kinds of things like that. Really good read. I recommend checking that out.

And then Piotr Solnica had a post about mocking and Ruby that I thought was really good and to the point, and warned of some dangers there and some assumptions. I found that really helpful. So, two good blog posts.

And then for fun stuff, Lego has been putting out some cool Lego sets recently, just from their ideas site where people submit ideas and they eventually pick them up. Two that are kind of awesome. Recently, there’s a research institute one. This one has three female scientists doing various things. Astronomer, paleontologist, I forget what the other one is. And it’s a cool little set. It’s been crazy popular and has totally sold out online. But just wait. They’ll print more. And you don’t have to pay crazy prices for it. That’s a cool set.

They also made a cool Exo Suit set with an old-timey astronaut minifigure that’s also a woman. And it’s like the astronaut minifigures I played with when I was a kid. So, some neat nostalgia there. Plus, exoskeleton has got a little robot turtle. I mean, come on. It screams cool. So, cool Lego sets to check out, maybe share with your kids.

And then finally my last pick, this is my last episode as a regular on the Rogues. I’ve done it for a long time. And I just need a break and will burn out. But I’ve had a great time, learned so much, and I have to pick all of my fellow Rogues because they are the coolest people on earth.

DAVID:  Cool.

JAMES:  So, that’s it for me.

SARON:  Aww.

CHUCK:  Thanks, James.

SARON:  Thanks, James. [Chuckles]

CHUCK:  I was going to pick James.

DAVID:  I’m honored.

CHUCK:  And then I was going to cry.

SARON:  You can still do that.

CHUCK:  Okay. Saron, what are your picks?

SARON:  Sure, I got a few. So, the first one is a blog post called ‘7 Techniques to Design Killer Graphics for Your Blog Posts’. And usually, I really hate list-ical things. But I really like this one, not so much for blog posts, but just for websites in general. I feel like a lot of people may not be very design-y and may not like that stuff. But you still need design elements to make your website look decent. And this gives some really, really good ideas of quick ways to make things digitally that enhances your website with very little effort. So, if you are not too invested in design but you kind of care, this is a good place to get some ideas.

The second one just because I mentioned it in the actual show part of this, the Seth Vargo blog post about how he’s leaving, I’m going on a sabbatical. He’s a release engineer for Chef. I thought that’d be an interesting read and I’ll include that.

And the final one in honor of James’ last episode as a regular is that I wrote a blog post. And it’s called ‘The Truth about the Rogues’. And it’s essentially the expose.

DAVID:  Oh, no.

SARON:  I know, I know. This is going to be fun for me.

JAMES:  Wow.

DAVID:  So, this is my last episode too, as a regular.

[Laughter]

SARON:  It might be. We’ll see what the listeners say. But yeah, I wanted to share a little bit about my experience as a guest panelist, especially because James was the one who initially invited me. So yeah, I just wanted to share that. That’s what I got.

CHUCK:  Awesome. Avdi, what are your picks?

AVDI:  Let’s see. Well, I’m going to pick in honor of James as well. I was poking through the history and realized that there’s a terrible omission. As far as I can tell, James’ blog is not listed in our history of picks.

JAMES:  That’s because it was down for most of the time.

AVDI:  Well, yeah so for most of the run. For most of the run, it was down. But he did bring it back with a vengeance recently. And he’s been posting a lot of fantastic stuff, which makes me very happy because long before there were Rogues and I ever dreamed of being a Rogue, I used to read his blog and really enjoy it. So, I’ve been particularly [inaudible] the post on Rust. There’s also Ruby stuff. There’s also the entire run of Rubies in the Rough, which was James’ extended essay series that he was doing as a subscription service but now it’s all there. Lots of really deep, good stuff there. So, totally go check out and bookmark and add to your reader James’ blog if you haven’t already because it’s wonderful, deep, technical stuff.

My ongoing campaign to deal with some of the RSI issues I’ve been having, I did pick up an ergonomic keyboard. I got Microsoft’s latest entry into that market. For a long time it was the Microsoft Ergonomic 4000 or whatever it was, but they’ve actually got a relatively new thing called the Sculpt Ergonomic Keyboard. And it’s pretty nice. It doesn’t suck. It has this really, really nice memory foam-y wrist rest. It’s got the shape that keeps your wrists in more of a neutral position. And it uses modern style island keys like the minimal form factor slim you’re probably used to seeing on laptops these days. And I’ve become a real fan of those. So, it was nice to see an ergonomic keyboard that actually incorporated those. I know all of the clicky-clacky keyboard people are cringing in disgust right now. [Chuckles] Dave.

DAVID:  [Laughs]

AVDI:  [Laughs]

DAVID:  It’s so cute. Carry on.

[Laughter]

AVDI:  It’s not the greatest thing ever. The end key is a little wonky and they’re probably not the most comfortable keys I’ve ever done. But it’s pretty decent. And you can get it for a relatively decent price compared to some of the really advanced ergonomic stuff, which I still may check out eventually. So, that’s been serving me pretty well.

Something that actually occurred to me while we were recording the episode, this wasn’t going to be a pick, but I got an email while we were recording that was actually a follow-up from the UPS Store on an issue I had with them in one of their stores recently. And the follow-up that they sent me is actually one of the nicest customer service emails I’ve ever received. So, the UPS Store deserves a pick just for having really great customer service.

And finally, one not business-y, not technical pick. I’ve been really enjoying the band Austra recently. So, I’ll include a link to that. And that’s it for me.

CHUCK:  Alright. I’m going to pick James then I’m going to go cry myself to sleep. Honestly, it’s been such a pleasure to get to know James over the last few years. I know we had talked and met at conferences before, but I’ve learned a lot from him. And I just personally want to say thanks, James, for all of the great stuff that you’ve done. I kind of am getting into my picks, but I think I skipped Dave. So, I’m going to ask him for his picks in a minute.

I’m going to pick a couple of podcasts that I’ve been listening to lately that I really enjoy. One of them is GeekBeat.tv. And they’re just videos. They cover all kinds of tech stuff. And I really enjoy the review and stuff that they do of tech stuff. So, that’s one.

Another one is the ‘Planet Money Podcast’. I’m pretty sure I’ve picked it on the show before.

And finally, the last pick is CES. I just was informed that I’m going to be at CES, or that I have a ticket to CES anyway this January in Las Vegas. So, if you’re in the Las Vegas area or if you are going to be at CES let me know and we can go and look at all of the cool tech together. And those are my picks. Now Dave, did I really skip you?

DAVID:  You did, but that’s okay. I just had one quick pick at the start of picks because I figured James was going to dump his entire picks folder, but he did that last week. So, my first pick is obviously James.

And the pick that I’ve got is I was googling. Well, I should back up. James and I have both told the story of the first time I met James which was I was a little overenthusiastic as a fan of Ruby Quiz. And I think the first thing I said to him was in way too loud a voice, “You totally destroyed my Ruby Quiz submission.” And I meant it as the lead-in to saying, “Thank you,” and for James being the person to actually get me to think in Ruby when I’m programming in Ruby, to stop thinking in C++ when I’m programming in Ruby. And that was a Ruby Quiz submission about solving Sudoku boards. And that’s still on the RubyQuiz.com site.

But I had a recent run in with Ruby Quiz last month. I was trying to remember, trying to figure out how to render a structure that basically it was tree structure. And I needed to display it on the screen. And I’m like, “I know I have to use recursion to do this. This is like displaying a tree or rendering a graph. I bet there’s been, somebody has to have solved this problem.” And I went out and googled for the problem that I was having and I found a Ruby Quiz on it. And I found my own solution to that Ruby Quiz problem on the site. So, I basically trolled myself from seven years ago.

JAMES:  [Chuckles]

DAVID:  And it just made me very, very happy. It made me smile. So yeah, James I’m super bummed. I’m going to be really sorry for myself. I’m really happy for you and excited to see what fun things you’re going to go do. But I’m super bummed for myself. Okay, so now I’ve got something on my eye, but you can’t hear that on the podcast.

My one pick for the show that I had planned anyway, there is a game coming out of Canada on Kickstarter by an individual developer called Noct. And I don’t really know how to describe it other than to say, go look at the link. It’s a top-down shooter with zombies and monsters. But everything is done through thermal imaging. And so, when you leave the room everything outside the room vanishes. So, what your thermal camera can’t see, you can’t see. And I backed it for one frame of animation. When you get killed, the screen just goes black. The thermal vision camera that you’re getting just ends. There’s no, “You have died.” There’s no, “Game over.” It’s just [pbbt], you’re dead.

And the experience of watching that is so visceral, because you see the monster slap an arm at your guy and then the screen just goes black. And it was so terrifying that I went out and backed the guy, backed the guy’s game, just on the strength of that one frame of video and the visceral experience that it cost me. So, definitely check out Noct. I’ll put a link to the Kickstarter. I’m hoping that they get funded. The music for it is haunting and beautiful. They’re doing a lot of things really right in the development of that game. So, that’s my one big pick.

And then Avdi mentioned keyboards. Yeah, I want to be a keyboard hipster and put down any keyboard that isn’t perfect. But honestly, I’ve become a jaded old cynical ergonomic hermit. And there is no such thing as a good keyboard. And so, yeah I’m not going to give Avdi any crap about the keys on his keyboard. There’s a keyboard that I currently like. And it’s not the build your own lightsaber one anymore.

I switched back to a Razer BlackWidow. They have started making the Stealth again, which is the clicky-clacky keys but without the clicky-clack. So, it still feels like you’re typing on something fairly solid and the key action feels really good. And I will say this to anybody that does not have an expensive clicky-clacky keyboard, don’t get one unless you really need one, because once you’ve typed on one you can’t go back. It’s like all of a sudden you’re like, “Oh, this is what the hipsters were all about, or on about.” And before you go, your keyboard is fine. There’s nothing wrong with it. And then you get $150 keyboard with super nice key switches in it and you’re like, “Oh, I can’t ever go back. I just can’t do it.”

AVDI:  So, what color [inaudible] switches are in that one?

DAVID:  This is me officially turning in my keyboard hipster card. I don’t know.

AVDI:  [Gasps]

[Laughter]

AVDI:  Gosh.

DAVID:  Okay. Obviously it’s a Cherry MX switch because, obvious. But I think they’re browns. They’re the ones that have the full tactile, no I’m sorry they’re clears. They’ve got the full tactile, you can feel the clickety-clack as it goes in and out. But there is no click-bang from, the blues are the most common. The blues are the ones that go clackity-clackity-clackity-clackity. Actually, it might be a custom key switch made by Razer. But the BlackWidow Stealth has quiet keys that feel really good to type on. So, those are my picks.

CHUCK:  Awesome. Eric, what are your picks?

ERIC:  So, while we’re talking about keyboards, I’ve built my own keyboard. One of my friends and Seattle.rb members, I guess former Seattle.rb member, Phil Hagelberg designed his own keyboard called the Atreus. And I bought a kit off of him and soldered it all up myself. And what I like about it is that it’s small. So, it’s got only 42 keys on it. So, you have to do some hand shenanigans to type numbers or punctuation or those kinds of things.

But it’s small enough that I can carry it with me wherever I go, small enough and light enough, which makes a big difference if I’m not typing in my comfortable typing space. So, if I’m typing at a table I can go and put the keyboard in my lap and have my laptop up on the table, which is much more comfortable for me. And it was also really fun to go and put it together myself. He also sells it, but I imagine that since he hand-assembles and solders it, that the lead time on that if you were to order a built one would be a lot longer. And it’s also got a really nice wood case and everything. And no letters on it. So, it looks quite intimidating. But it feels really nice.

And then, let’s see. I also, I think RubyKaigi is my favorite Ruby conference to go to. Sure, it’s in Japan which is a long ways to go for a conference. But it also has this amazing technical feel that I think only RubyConf in the states comes close to.

And then finally, I’ve been volunteering as a TA at Ada Developers Academy. And I can’t recommend that experience enough. I think it’s helped me a lot in thinking about what does it mean to be a programmer and how do I do what I do and why do I do it. because the students will ask all kinds of questions about programming that I hadn’t thought to ask and were second nature until I actually thought, well how do I do this and what do I think about when I do it so that I can explain it to you in a way that will help you in your programming career and help you with learning programming. And so, that kind of experience has just been amazing.

CHUCK:  Awesome. Well, thanks again for all of your hard work on RubyGems. It makes such a big difference to us.

DAVID:  Yes.

CHUCK:  Out in the community, in our everyday work. And a lot of times, we just don’t think about how much work must go into making this work.

AVDI:  Yeah, thank you so much.

JAMES:  Yeah. It’s awesome. Thanks.

ERIC:  You’re welcome.

CHUCK:  Alright. We got a reminder real quickly for our book club book, ‘Refactoring: Ruby Edition’. So, go check it out. And we’ll catch you all next week.

[A special thanks to Honeybadger.io for sponsoring Ruby Rogues. They do exception monitoring, uptime, and performance metrics and are an active part of the Ruby community.]

[Working and learning from designers at Amazon and Quora, developers at SoundCloud and Heroku, and entrepreneurs like Patrick Ambron from BrandYourself, you can level up your design, dev, and promotion skills at Level Up Con taking place October 8th and 9th in downtown Saratoga Springs, New York. Only two hours by train from New York City, this is the perfect place to enjoy early fall and Oktoberfest while you mingle with industry pioneers in a resort town in upstate New York. Get your ticket today at LevelUpCon.com. Space is extremely limited for this premium conference experience. Don’t delay. Check out LevelUpCon.com now.]

[This episode is sponsored by MadGlory. You’ve been building software for a long time and sometimes it’s get a little overwhelming. Work piles up, hiring sucks, and it’s hard to get projects out the door. Check out MadGlory. They’re a small shop with experience shipping big products. They’re smart, dedicated, will augment your team and work as hard as you do. Find them online at MadGlory.com or on Twitter at MadGlory.]

[Hosting and bandwidth provided by the Blue Box Group. Check them out at Blubox.net.]

[Bandwidth for this segment is provided by CacheFly, the world’s fastest CDN. Deliver your content fast with CacheFly. Visit CacheFly.com to learn more.]

[Would you like to join a conversation with the Rogues and their guests? Want to support the show? We have a forum that allows you to join the conversation and support the show at the same time. You can sign up at RubyRogues.com/Parley.]

x