 I'm Maggie. And I'm Nikki. So this came about because Nikki and I, we are both former social workers who found ourselves working together about a year ago at a small software consultancy where we were responsible for maintaining a few different projects. And we were also responsible for billable hours. We were really in a tightly driven, efficient environment. And we saw some of the challenges that came up both in this environment and as a result that we wanted to talk to you guys about. So welcome to, oh, we've lost them. So welcome to Jem's use or misuse and going your own way. I'm Nikki. You can find me on Twitter at Nikki Liz Murray on GitHub at JDAX. My cats are on Twitter, Nikki's cats. I'm a developer with Democrats. I work a lot making fun interactive tools for voters to use. I'm owned and operated entirely by my cats from left to right, Stormageddon, dark lord of all, Tom Waits, Didi, destroyer of all things good and pure. Maggie, you can find all my handles there. Mapstimus, GitHub. And then there's a blog that I used to write on and may someday again. So I'm a software engineer at Labor Voices. Labor Voices provides global brands and their supply chains. What has been missing an early warning system based on direct feedback from workers by repeatedly pulling workers through their mobile phones? We help our customers obtain strong safety standards and decent working conditions, empowering workers through their own voices. I'm bad at elevator speeches, so I took that from our website. But what's really important for you guys to know is that I'm hiring. So if you have any interest in improving global labor conditions and you happen to like rails maybe, feel free to find me or tweet at me. And this is Dolly who you'll see again. So the overview of what we're going over today is the importance of assessment is really key. What is needs assessment? How do you do needs assessment? Important in that is why we use gems. And how and why do we misuse gems? How should we go about assessing gems for fit? And what do we do if we find that there is no gem that fits our needs? Importantly, that means how to do it yourself. So we're starting with the importance of assessment because this is really the thing that if you took nothing else away, we'd love you to take away. So it's remembering to really accurately assess what your problem is and what your needs are before installing a gem into your system. And we have this lovely quote, assessment is an ongoing process which is participatory that seeks to understand the service user and their situation and sets a basis for planning how change or improvement can be achieved. And so we didn't take that from a software development textbook. We took it from a social work textbook. So models of assessment is really common if you're going through social work school, how to do assessment with your users, the users of the service you're providing and how to do assessment in your own team. So the assessment process operates by being purposeful and specific, figuring out what is appropriate for your situations. It needs to be dynamic and responsive. So you need to be flexible in your assessment. It needs to be based on engagement from individuals and inclusive engagement at that. So that means when you're doing the assessment of what you need your app or your gem to do for you, you need to have every stakeholder in the room with you. So that means users, that means design, that means marketing, that means whoever you think is going to have a hand in this project or is going to touch it at one point or another needs to be in the room. Not only that, but it needs to be ethical and skilled. So your solution needs to find a way that achieves your goal ethically for everybody that touches it. It needs to be grounded in legal and policy context too. So if you are doing something with a healthcare company, if you're doing something with a policy company, you need to know the context in which your solution needs to be found. So it doesn't need to be HIPAA compliant. It doesn't need to be compliant with whatever rules a foreign country might have. It needs to also be empowering. So everybody needs to feel empowered to make the assessment, to make the calls. They need to feel that their voices are being heard in the assessment process. It needs to highlight protection and safeguarding. So as you've probably heard in a few other talks, making sure that everybody involved has their privacy protected, has their non-aminity protected. Anything that your users or anybody else involved might find a key thing that they need to hold on to. Make sure that that's protected in the assessment process. It needs to be holistic and comprehensive. So think of every end case, every edge case and think about any other cases that people might be using this service or product in. There needs to have support for decision making. So the people that are making the final decisions need to feel supported in that. So if you're the programmer and you're making the final call on what gem you're using or what gem you're gonna be building, you need to feel empowered that your bosses aren't gonna come back and go, why did you use this? So make sure you have those discussions and that they go both ways. And it also, in the end, needs to lead to future action. So don't have this meeting for weeks on end. Make sure that the meetings that you're doing this assessment in are focused and that they come to a conclusion that ends with a final plan of action. So what's a needs assessment? As you saw from the beginning of our talk, what really matters about this talk is that we wanna avoid using the wrong gems or using gems recklessly. So the first thing you need to do is really know what you need before you use a gem. So what does this look like? So it looks like concretely defining your problem and it means thinking of the problem from as many angles as possible. Asking why it's a problem. Is it a problem for your users? Is it a problem for somebody else on your team? Who is this a problem for and why does this matter? This goes back to getting a lot of opinions on it. Whether it's having everybody in a real room, having everybody in a Slack channel, but just making sure that you really know who the stakeholders are and what they think about this problem. And then considering your users because they're always gonna be your stakeholders. So how will different solutions impact them? How will it change their lives? How will they react to this? And then sometimes we're approaching a problem and we think of it as just one problem but really it's five or six. So it's breaking it down and then approaching it from each problem and deciding which one is the most important and solving that first. So that means writing out different solutions and looking to different people for feedback on those solutions. And once you've determined the best solution it means starting to look for ways to implement it. You could use an existing gem or gems, write your own gem or gems or build in that functionality directly into your project. So I would evaluate each of these and ask yourself which is the best one. So the first question is why do we use gems? This might seem obvious but obviously it's easy so that means you get to go pet your cat more soon, more quickly. So you don't wanna solve a problem that's already been solved. You wanna be as dry as possible or you wanna be not repeating other people's code just in your own way. And then everybody uses them and this leads to a sense of shared responsibility in community so you're not alone in being responsible for maintaining that work. Everybody uses, there's a few gems out there that people might use that has a lot of not necessarily their own documentation but a crap ton of stack overflow questions like device. So this leads to how do we misuse gems? Misuse of gems can sometimes look like 150 gems installed and you have no clue why. For comparison, the average gem file.lock has about 118 with a standard deviation of 58. So on average your project will have 50 to about 175 gems installed and the upper limits of that is a lot of gems and that's a lot of code that you're pulling into a project that you didn't write and that you have no control over. So the pitfalls of gem misuse is unknown dependencies. If you didn't read the dependency list before you ran gem install, you might be sitting there looking at bundler going, why is it installing that? This can also lead to breaks on upgrades. If anybody has ever taken an app through an upgrade process, you know how time consuming that can be. This time can really be cut down by not relying so much on gems. So you upgrade one gem and then suddenly 50 other things don't work. This can also lead you to looking at your gem file and going, why did I install that? And so you remove it and then nothing works again. Also, the gem might not be the best solution to your problem. It might only be a partial solution. So why can this happen? Some of you probably come to projects and been like, what's happening here? I'm staring at the gem file and I don't know how it came to be this way. So you know startup culture and I don't just mean at startups. I mean this idea of we have to get this out the door now, we have to be first. All that really matters is that it works. So you just say, oh, there's a gem for that. Let's go and then you throw it in there and you think you're good to go. There's the idea of group think. So there's sort of some gems that people go, oh, everybody uses this for that solution. So obviously I should use it. There's just sometimes poor planning. You've thought out all the most obvious use cases but you really haven't thought out the more minute ones and your gem might cover those obvious ones but really it's not as relevant to some more edge cases but that actually might be really crucial to what you're trying to do. And then there's this idea of imposter syndrome. I think it's often easy to go, can I really do better than this gem out there that's supposed to be the best? Even though maybe you can do better for your problem. It might not be that you can do better in this global sense but you might know your problem way better than whoever wrote that gem. In addition to the pitfalls of not knowing why your app is doing what it's doing and it's really because of that gem, there's some other risks that you run into when using gems. A lot of people have talked about hacking in the past and how you can hack. There was like a Ruby nation a few years ago where somebody passed out cards that say gem install Ruby nation and then gave a speech about how he could have just taken all of the information on your computer with that because nobody thought anything of it. So any gems that especially aren't on rubygems.org are potential security risks. According to Hikari, 66% of gems that are even on rubygems.org have a one point or another had a version that had a security risk in it. Those might have been really small security risks. They might have been SQL injection risks. So making sure that you're doing the assessment of the gem beforehand to see if you see anything that might stick out to you as a possible security risk. We talked earlier about the average number of gems in a gem file, 118. On that average gem file, about four of them currently have a security risk in them. So maybe you've used sprockets in some of your projects as early as a few weeks ago. It had a known security vulnerability on it. Arbitrary file existence disclosure. Maybe that doesn't concern you. You don't use sprockets or you don't care about those kind of security risks. But you've probably used active record at one point or another. And this summer it had a SQL injection vulnerability. So you don't use rails. You don't care that active record had a security vulnerability in it because you use Lotus or something other that's cool and hip. But you've probably used Bundler. And this summer it arbitrarily installed gems that you didn't want or ask for. There's also memory risk. If any of you have ever bumped your head really hard against where's all of my memory going, why is this happening to me? It's because a lot of gems, common, a few common gems have known memory leaks in some of those versions. So red carpet, Sidekick, the Ruby Racer, all have documented and now fixed memory leaks. But there are still versions out there that might be on your gem files that have these memory leak problems. Currently there are suspected leaks in New Relic RPM and delayed jobs. If you want to make a pull request that fixes these that would be great. So you also run the risk of claustrophobia. You know, you've installed this gem and you realize that as we talked about it solves some but not all of your problems. And you find yourself kind of hedged in by the problems that the original gem author tried to solve. And so what you end up doing is you redesign your feature around this gem rather than redesigning your code to match your feature. You also can wind up with hundreds of lines of codes for only half of a fix in this case. So you have all these lines of codes, you're rewriting your code to keep up with this gem and there's all this code that really is pretty wasteful. And you can figure this out after you get it installed. So you think, okay great, this gem is awesome, it solves most of my problem, but you get it installed and it's set up and then you realize it doesn't even really do the thing you wanted it to do. And it has compatibility issues with other gems in your system. So it's a really fun process from there, right? So that last example happened to me where I was trying to write an API and I decided I would just use a gem for that. And halfway through getting the gem all set up, I'd wasted an entire day trying to get Grape to work with my app and it asked me to turn off strong params and I threw it out and wasted another day seam ripping it. So gem assessment, so what should you look for beforehand? Before you have to go in there with a seam ripper. You wanna look for stuff like how well is it maintained? When was the last commit? Since that last commit, were there any major updates to Ruby that might cause it to not work with Ruby? Are you using the version of Ruby that has since been updated to no longer work with this gem? You also wanna look at how often there is community involvement. So stuff like GitHub watchers or stars, you wanna check the rubygems.org downloads, you wanna see what the community commitment is to this gem and the community support for it and how much community trust has been put there. You also wanna look at the issue trackers. Are there a lot of them in there that have been sitting there for years unaddressed, not even commented on, not even a won't fix on it? You wanna see what kinds of issues they close and what kind of issues they close quickly. If somebody submitted a security vulnerability patch, did it sit there in the PRs for weeks or was it merged in pretty quickly? You also wanna look at what the contribution process is like. What kinds of tests are run before a PR is accepted? Are these automated tests? Are these tests that the gem author is asking you to run yourself? And you wanna look at that test suite itself too. Is it testing for stuff that you would want to see it tested for? Is it testing for edge cases that you strongly think should be tested for? If you have the time, read the source code. If you don't have the time, read the tests. Especially when me and Maggie were doing billable hours, the desire was there to not read the source code because we're billing a lot of money for every minute we spend reading. But it's actually worth it. And if you spend a day reading source code, you're not gonna be spending a week redesigning your entire app. So read the documentation. How well is it documented? Read the source code. Is the source code dry? Does it follow a single responsibility principle? Is it easy to understand what it's doing? Are there really clever tricks that the gem author put in there that you have no clue how they work? And so therefore you trying to write code around that would be difficult? Is it well commented? You wanna look at the tests and read the tests and try and figure out what the gem author was attempting to achieve. And figure out if they were testing for edge cases that you think are important. Were they testing for edge cases that you hadn't even thought of before? You also wanna look at if it has a code of conduct. If you're using the gem, you might need to interact with the gem maintainers or contributors at one point or another. Whether that's submitting a PR or just asking them for clarification of something. Does the code of conduct or lack thereof lead you to believe that that interaction would be a positive one? Does it make you want to work with these people? So you decided that it fits not all of your needs but most of them and you kind of wanna use it. Consider contributing to the gem. You could add the exact functionality that you're looking for and submit it in a pull request. As previously discussed, if those are people that you want to have that interaction with. Unless and until it is merged, you can use a local copy or point your gem file to your branch on GitHub. You could fix the memory leak or security issues you found yourself and hopefully they will respond to that PR quicker than your added functionality one. Does it solve your problems in a way that the users of the project will be happy with? Cause at the end of the day you wanna make sure that your users are happy. Is it an accessible solution? Is the solution that you believe will make you happy to work with it and also the users happy? So you're done assessing and none of the gems out there really fit what you're trying to do. So it's trying to do it yourself but the real question is how? Since we're programmers, I think we all like kind of a method. This is what I came up with just for approaching this problem. I call it, I just say overcome, assess, research, build, maintain. Of course we're gonna do this in the workflow that fits your company and all of that but this is just some ways to think about this. So I just, I put an overcome cause every time I'm approaching a project I have to kind of tell myself like, hey it's okay that I'm really freaked out by what I'm about to approach that my solution might not be perfect but I have to figure out how to, I can come up with something good for the problem at hand and this is where all great things begin under the yoga mat. So we go back to our needs assessment. We're defining that problem concretely again but we're coming back because we didn't have a good solution yet. So we're looking at what the current behavior of our system is, what the behavior we're trying to achieve is and why we want that behavior. We wanna slow down and ask ourselves what are some possible edge cases? What are some things that the gems I already looked at don't address that I need to address now? And what are the risks of building this, the way I wanna build it? What are the security risks? Do I understand how performance is gonna be impacted? Do I understand how my users are gonna be impacted? And then why hasn't somebody else solved this problem? So you've looked at all these gems, you've looked at all this code, why hasn't somebody else figured this out yet? Why haven't they approached it the way you're approaching it? So we're gonna go back to this research. You found some gems before so now you're gonna look back at this and you're gonna read some of their code again. But this time you're not just reading it to assess whether or not it works for you, you're reading it to figure out what they did well that you might wanna build upon and also why it is you originally dismissed the gem as a solution to your problem and what it is you need to change. So you can look at their tests again, think about what they're testing for, what you're gonna wanna test for and then you might wanna look at their dependency list because this gem might not have worked for you but they might have built on a gem that you could use to build out your solution. So it's again figuring out which parts work and which ones don't and again, why they work the way they do. So then you wanna look at what other people have thought about this problem. So did any of the gem authors write about how they approached their problem and their process and why they made their decisions? They could have talked about some other research they did that might be really useful to you. For example, there might be a blog out there where somebody else approached your same problem and documented exactly how they solved it. Maybe they didn't write a gem but maybe they did a tutorial or just kind of a thought process blog on how they solved this same problem. So it's really just learning as much as you can before you even start to approach this. So now you're gonna build. The way you're gonna approach this is the way you'd approach anything else in your app, right? Is you wanna map out your solution. You wanna model every part out and figure out its architecture. You wanna use whatever your best practices are, whether that's TDD or behavior driven development, but you wanna use it, you wanna continue using your best practices as much as you can. And you really wanna document it. I think what's really important here is same as when you're looking at other people's gems, you want somebody else to come back and look at your code and feel really comfortable knowing why you've approached the problem the way that you did. They may not think your solution is right for them but you want them to understand what process you went through. I like the headache test for most of the work I do. I say that if I really get sick of working on something and am I getting a headache day to day working on it, usually something's not going well. So that goes back to, if I have fun while you're working on this, if you're not having fun, why would anybody else have fun with what you end up with? So to start with, consider that you may not need a gem. You may just, you're gonna ask yourself, what's the most basic problem I'm trying to solve? I might just wanna build something into my app. This might be a really quick fix. Maybe I really thought this was huge but sometimes the biggest fixes come from one or two lines of code. So start there because that's gonna be the easiest thing to maintain and the easiest thing to work with later. Again, it's that headache test. Don't make yourself do too much work because if you're miserable, everybody else who comes after you is probably gonna be somewhat miserable as well. So what if it does make sense as a separate gem, right? So then you're gonna wanna think about, how abstract can I make this? How can I make it such that somebody else might be able to use this for their own work? Don't make it too dependent on the code you've already written within your app. Try to pull it out as much as possible. Not everybody can open source, but if you can, that's a great way to get some feedback on it. Maybe other people have really great ideas about what you're working on. If you're open sourcing it, try to add a contributor code of conduct. Maybe somebody else is gonna come in and add something really awesome, some feature that you never even thought of. And publish it. If you think it's a great solution, get the community involved. Speaking of putting it on rubygems.org, if you are publishing your gem, please consider the following. Some of these were previously discussed in Seven Habits of Highly Effective Gems, but we have our own twist on them. How easy would it be for another person to get started on your gem or get it started in their own project? How easy would it be for someone to contribute? If you don't think it's gonna be easy for somebody to contribute to your code base, it's not gonna be easy for yourself to contribute to it three months from now when you have forgotten everything. So is your test suite understandable? More importantly, is it understandable to future you? Are you testing for style conventions? Make this decision now so that you don't have to backwards port that kind of thing into your gem. You wanna think about, is your solution broad enough for other use cases, not just the one that you're solving for? If it's not, specify specifically in your readme what you were trying to solve and document that well. Have you tested it in Rails 2, Rails 3, Ruby 1.87, and also document that so that people know going into it what they are able to use it for and what they might need to look out for in other versions? So you've built your product and now you're maintaining it. You know, there's some questions to start asking yourself here. You know, we're all agile so we're gonna keep working on it. Maintenance is not just a static process, right? We're still working on our feature as we go. So a question to ask yourself is will the next person or future me hired at my company, or I guess me if I'm already hired, so you know, me in three months, hopefully I still work there, be able to jump into your code base? You know, will I be comfortable just getting going? Is this gonna be a huge hassle to get started on again? Have I written some good tests? You know, not just is it there, but is it well tested? Does it test the things I need it to test? If I'm gonna need to add something in six months, am I gonna remember what I worked on six months ago? I think I got my time frames a little confused there, but that's okay. Such that, you know, I'm not gonna break anything important. Have I documented it well? Do I remember what's happening? Maybe ask somebody else to read your documentation and try to work through it. I think that's one of the best ways to know if it's any good, is if somebody else can follow the steps you followed. And then something really important is to be able to ask why did I do it this way? Because the next person who joins, or you in three months, is gonna be asking that. You're gonna be going, why did I do this? So maybe make sure you can really explain that. You know, if you have a teammate and have talked it out with them, if you don't have a teammate, make sure your cat understands really well what's going on. You know, and this is a good time to evaluate how much complexity you've introduced. Is it just way too confusing? Did your solution really simplify things or did it make it much, much worse? You know, you can simplify it now because you have the solution in place, so you can really, this is a great time to clean up your code as much as possible. Whether you've just installed a gem or you've completely written something from scratch. So aside from our assess, assess, assess, and then keep assessing an ongoing assessment, one of the other takeaways that we want you to have from this talk is if you're using a gem, you're not the maintainer. That is more free time for you to work on your own code or more time for you to pet your cat. It's a great thing to not be a gem maintainer. However, if there's something else we want you to take away from this, it's that you are not the maintainer if you didn't write it. So guess what? You have no control over updates or changes or pivots. It could have been your cat or your cat could just be really annoyed at you. You know, you might end up spending two days in upgrades because you didn't do anything on this gem and somebody else just threw in an upgrade that you realize is also security vulnerability, so you really have no choice about whether you go to the next version. So I think we are at the time where we can take questions. Does anybody have any questions about good assessment or good team assessment or gems that you think are really awful? Yeah, absolutely. He asked if there were any specific gems that we thought were subject to frequent misuse. So I'll start with, we first came across the problem as Nikki mentioned because we were working on APIs and we were kind of Googling this and a lot of stuff out there was like, use this gem for an API, this is the gem, and then we'd read the next blog post and it would say use this gem for an API and it'd be like a completely different gem. So Grape was one example of that where everybody's like, use Grape, use Grape. But then I think, you know, Nikki was approaching this problem and she found a third blog. So after putting in a lot of different gems to make my pretty basic crud app into an API and seam ripping all of them out, I was just like, you know what, I'm just going to teach myself how to write an API. And instead of sitting there and turning off strong params, like Grape asked me to do, I was just able to go into the controller and write the code in there for the API. So I think if you are thinking about something like, oh, there should be a gem for this, I don't know how to do this. Like consider just Googling, like how do I build this? So like a lot of people I know use really complex, this came up at Ruby for Good, like how do we make like a CRM in Ruby? And I think like a lot of people at that team tried to start off with like, can we use gems for that? But just kind of like, no, can I take it a step back and think about how I could do this on my own and can I do it simpler? Yeah, and this all came about because like I probably not the only person here who's been at a hackathon, been at a conference where somebody said, have you used this gem? And then you're like, well, no. I'm like, well, everybody uses that gem. And suddenly you feel like you're super behind. And I think that maybe you didn't use that gem because it actually wasn't right for any case you've encountered. So I think it's sort of this idea that we have that we always have to use a gem for, or a specific gem for anything we do. When maybe Active Record is a great gem that it's not right for every app, right? So it's just sort of about like using kind of that, like I think there's an analogy of like using the same knife for every problem I know. I'm not good at analogies. Another thing that I just thought of is that like, everybody says like, you can use devise. It's like the quickest way to get user authentication into your app. Just use devise, just do it. And so then you see these apps that don't need user authentication or user authorization. It's like, why do I need to sign into this? This is like a database of like your favorite movies. Why do I need to sign into this? Well, because you could just put devise in and have user authentication, then you can be getting user data. And it's like, you don't need user data. You don't need to have like user authentication here. You're literally just displaying like static content here. So think about what kind of problem you need and like what solutions like, there's that easy solution of putting devise in, but do you really need it? No. Well, the question was, do you have any tips for scanning for security vulnerabilities? So I, you know, probably if the gem maintainer didn't catch it, you may not catch it. But if you do see something, obviously immediately let it send up a warning signal. I think for like, I don't know if I'm the only one, but sometimes I read gem files and I'm like, oh, they probably knew what they were doing. So if I see something weird, I just won't worry about it, right? Like disabling strong params, for example. But you know, listen to your gut on that. But the other thing is, yeah, we took all of our advisories from RubySec, so that already has some advisories. So maybe start by just looking there and seeing if any gems you're using are already listed there. And I think Hikiri that you mentioned as well has some listings. So, you know, there's some listings out there as well. So like RubySec you can go through and let's see here, what's a good one? Where was that one? Oh, Bundler installs arbitrary gems. Yeah, that was one of our favorites. Yeah. So it says right here, like it was patched in version 1.70 and a description of the problem. And then these are the places that you can go for common vulnerabilities. This is the open source vulnerability database and this is, I don't know what this one is and the wifi is being slow. But it'll take you to places that'll do it and you can check and see here if it's been patched since then. And figure out if you want to maybe use the patched version or if you want to use an earlier version that did not have that vulnerability if it hasn't been patched yet. Yeah, and you guys might want to read the description of this one too because it's a little more scary than just arbitrary gems. I think we had a question back there. Thank you, that's really helpful. So for those who didn't hear, there's some open source places like Code Climate and what was the other one? Gymnasium. That'll run tests on your suite before to see if there's any vulnerabilities that are known in there. That was an example of a possible style choice somebody could make. An extreme style choice. We do not endorse nor we do not endorse any specific styling choices you guys might make. But we give you free reign to go to the extremes with curly braces in either direction. All right, thank you everybody so much for listening.