DEV Community

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

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!