Ideal Ruby project structure
Asked Answered
W

4

135

I'm after an overview/clarification of the ideal project structure for a ruby (non-rails/merb/etc) project. I'm guessing it follows

app/
  bin/                  #Files for command-line execution
  lib/
    appname.rb
    appname/            #Classes and so on
  Rakefile              #Running tests
  README
  test,spec,features/   #Whichever means of testing you go for
  appname.gemspec       #If it's a gem

Have I got something wrong? What parts have I missed out?

Workable answered 5/3, 2009 at 10:52 Comment(1)
I would suggest using Yeoman generatorPilaf
M
95

I think that is pretty much spot on. By default, Rubygems will add the lib directory to the loadpath, but you can push any directory you want onto that using the $: variable. i.e.

$:.push File.expand_path(File.dirname(__FILE__) + '/../surfcompstuff')

That means when you have say, surfer.rb in that dir, you can require "surfer" anywhere and the file will be found.

Also, as a convention, classes and singletons get a file and modules get a directory. For instance, if you had the LolCatz module and the LolCatz::Moar class that would look like:

lib/
  appname.rb
  lolcatz/
    moar.rb

That is why there is an lib/appname folder because most libraries are in the appname namespace.

Additionally, if you try running the command newgem --simple [projectname] that'll quickly generate a scaffold for you with just the bare essentials for a Ruby project (and by extension a Ruby Gem). There are other tools which do this, I know, but newgem is pretty common. I usually get rid of the TODO file and all the script stuff.

Macro answered 5/3, 2009 at 11:20 Comment(4)
sweet. I didn't know about newgem. My non-rails projects have often mirrored the Rails structure because I've found it familiar. Thanks for this best-practice tip.Anthodium
Another important file might be "LICENSE"Daube
I don't get the behavior you describe with lib being automatically added to the loadpath. Is it a 1.9 thing? Any special configuration required to get it to happen?Waterborne
You can also use bundle to generate a gem template. newgem hasn't been committed to for 9 months at the time of this comment. The command is bundle gem gem_nameWatchcase
K
12

See the following example from http://guides.rubygems.org/what-is-a-gem/

 % tree freewill
    freewill/
    ├── bin/
    │   └── freewill
    ├── lib/
    │   └── freewill.rb
    ├── test/
    │   └── test_freewill.rb
    ├── README
    ├── Rakefile
    └── freewill.gemspec
Kielty answered 25/7, 2013 at 9:35 Comment(3)
how about test/lib for classes needed for the testsuite only?Lawman
My answer was form 10 years ago! Does anyone even use ruby anymore?Kielty
now is the golden time, a lot of demand but fewer "cool kids" as competitionLawman
A
6

I attempt to mimic the Rails project structure because my team, which usually deals with Rails, will understand the structure better than another configuration. Convention over Configuration - bleeding over from Rails.

Anthodium answered 6/3, 2009 at 5:32 Comment(2)
If some external developer looks at your code, what s/he will see is just your personal convention. I think that for a medium/big project, using a set of conventions meant for a totally different kind of project could even cause more confusion. Is it a rails app, a ruby app? Why is it designed like a rails app? "I'd better get in touch with the developer before I break something...?" That's going to add a bit of overhead right from the beginning..Spyglass
I agree with @jj_. I know this is kinda old, but I think it's important that people understand why there are community conventions. It's so you can pull someone off the street, they could see your project and get cracking. It's so you can look something up and understand it. I feel it's important to use the conventions of the domain. Domain convention over project configuration.Gusset
S
2

If you use bundler, running this command bundle gem app_name will give you the same directory structure.

If you want to use rspec instead of unit tests you can then run this command rspec --init (Just make sure you cd app_name first)

Shaner answered 16/3, 2018 at 11:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.