DEV Community

Discussion on: 5 Things I Learned From Creating My First Ruby Gem From Scratch

Collapse
 
morinoko profile image
Felice Forby • Edited

Hey Josh,

Thank you so much for your awesome feedback and comments!

1 I was skeptical at first, but planning really helped. I usually get stuck wondering what to do next but the plan solved. I'm sure you can do it in many ways like you said, though, for example with "goals" or interfaces. I think the "user story" method would be excellent too! We used to use user stories at my previous job for every single feature addition, no matter how big or small, and it really forced you to think about things from the user perspective, plus of course keep you on track with your code.

2 I loved the image of you writing your pseudocode for JavaScript in Ruby code, lol. I agree that it becomes less necessary as you get better and better at coding though. If I remember correctly, in the Code Complete book, the author actually advocates for ALWAYS writing pseudocode first before any code because it helps majorly reduce errors. I'm sure that's true, but sometimes it does seem like overkill.

3 I'm trying to be more careful with taking things in small steps (especially as a beginner!). I've been guilty of jumping into things, bashing out a bunch of code, just to learn that I broke everything and not knowing at what point I went wrong. Your gem looks super helpful! I'm going to check that out!

4 True!

Bonus: Yeah... testing I'm sure has it's time and place. But it would have been helpful to have a few simple tests that I could test out my code on instead of having to run the program every single time! heh. I haven't gotten too much into it yet, but I'm sure I'll form more in-depth opinions on testing later ;)


Thanks for checking out my repo too! Actually, I tried to find documentation on what exactly to do with those .gem files once you pushed them, but no luck. Are you supposed to keep them in your own file base? If so, should you delete each .gem version as you make new ones? I removed them from my git repo for now at least.

Collapse
 
joshcheek profile image
Josh Cheek

Thanks for checking out my repo too! Actually, I tried to find documentation on what exactly to do with those .gem files once you pushed them, but no luck. Are you supposed to keep them in your own file base? If so, should you delete each .gem version as you make new ones? I removed them from my git repo for now at least.

My approach is to build them into my project root and add *.gem to my gitignore (eg) so that git won't see it. Sometimes, when I get annoyed by them, I just rm *.gem to clear them out.

I've also seen people create a directory they build it into, eg gems or pkg, and add that directory to the gitignore, but I don't see much value in keeping the old .gem files around.


I looked at it a little bit more, and there's a few issues you're going to wind up hitting. In the gemspec, it defines the bin dir as exe, but the find-recipe executable is in bin. As a consequence, users who install the gem won't be able to run find-recipe (RubyGems won't know to add it to the $PATH).

The require statement in the binary is './lib/find_recipe', the leading dot means "the directory I am currently in", which will work when you're running it from your gem's root directory (b/c from there, lib/find_recipe is the file you want), but it will break when you run it from a different directory (eg people who install the gem are unlikely to be in the gem's source code when they run it). The easy immediate solution here is to use require_relative and go up a dir, but the most correct solution is to add your lib dir to an array stored in the global variable $LOAD_PATH. This variable stores the set of places Ruby will require code from... (Rubygems will add paths to this array, as you require gems). Try running ruby -r pp -e 'pp $LOAD_PATH', to see what that array looks like. After you add your lib dir, you can require everything relative to lib. In this case require 'find_recipe'. Here is where I do that in my gem.

You might find value in a walkthrough I made while teaching a class. It hits on all the most important things while building a gem, including things like the $PATH and $LOAD_PATH, executability, permissions, and so forth. It should touch on all the really nuanced things like that, which took me forever to learn! Seriously, the $LOAD_PATH is simple, but it's implicit, so I was confused by it for years! Right now, it will also be difficult for you to test the gem, b/c it calls gets and puts, which talk directly to the global input and output streams. The third day's material shows how to deal with that for the gem we build, which is similar to yours in many ways :)

Thread Thread
 
joshcheek profile image
Josh Cheek

Actually, looking @ my walkthrough, the stuff that's relevant to you probably begins halfway through the second day, here. If you want to code along with the walkthrough, you can start on the first day, so that you'll have the code, but I don't know that there's anything super new in it (maybe the stuff about how to get the absolute file path). If you don't want to code along with it, the code is here, and the commits follow along with the walkthrough, so you can go back and see what it looked like at that time.

Thread Thread
 
morinoko profile image
Felice Forby

Thanks for explaining the .gem file stuff.

And you hit right on the other thing I was confused about: how to get the 'find-recipe' command to run no matter what directory you're in! I read through your walkthroughs and the $PATH is starting to make a little more sense.

The original $PATH code and gemspec were generated by bundler's gem command, so I had just used it as is. I used your examples and it seems to work now :) thanks again!