Search code examples
rubyrubygemsbundlersetup-projectdirectory-structure

When using `bundle gem floob`, why is a directory of the same name as the gem is created?


I am making my first gem. Let's assumed it is called floob. ex: bundle gem floob

Why would bundle gem create two directories of the same name for a gem? ex: /floob/lib/floob/

Do I put the bulk of my code in /lib/floob/ (alongside the version.rb file?)

What is the purpose of the file that is created with the gem name? ex: /floob/lib/floob.rb

The only command run was bundle gem.

I would love a little clarification on what the relationship is between all the floobs~


Solution

  • The reason for this "two-tier" structure is because /floob/lib will ultimately be the folder that is added to the Ruby require load path.

    This way if you put floob.rb into /floob/lib, you can load it with:

    require 'floob' 
    

    This also gives the opportunity to separate subcomponents, like version.rb, under the floob namespace by putting them into /floob/lib/floob. That means you can now do things like:

    require 'floob/version'
    require 'floob/base'
    require 'floob/core'
    etc..
    

    If /floob was directly added to the load path, then it would be difficult to separate code from things like README files, gemspecs, or other assets like images, binary blobs, YAML settings files or bin stubs.

    Now the actual code will live under lib, and everything else can be put nicely into folders directly under /floob, without interfering with the code or load path functionality.

    Also note that in most cases you should not put anything else than floob.rb into /floob/lib, because otherwise you will be polluting the global load path namespace. Instead all the rest of the code should be put into /floob/lib/floob, and then you put require code into floob.rb to load those files, like I described above.

    This way you keep the load path clean, and components nicely separated from each other.