0

I'm playing around with a combination of Thin, Sinatra and Bundler. I'm trying to understand how I get Thin to include the path to my source code in the load path? I have looked for introductory tutorials to this setup, but none of them seem to answer my question.

Mucking around with the rackup file or Thin config file feels wrong. Assume I have a directory structure with something like:

bin/my-application-entry.rb # The entry point to my sinatra application
lib/myapp/mylibs.rb
thin/config.ru # rackup config
thin/dev.yaml  # thin config
Gemfile        # for my dependencies

The contents of the rackup file is essentially

require 'sinatra'
# I'd like to require 'my-application-entry' around here somewhere (I think?)
run Sinatra.application

I invoke the application with

thin -C thin/dev.yaml -R thin/config.ru start

I noticed that thin takes a command-line argument to require a specific library, but surely there is a better place where you can define all the load paths?

So my question is really, how do I tell thin/rack/bundler which directories to include? (such as bin/ and lib/)

Edit: For clarity, I'd really like to know how this is generally done with Thin specifically. I am reluctant to modify $: in my main application, but if I am forced to use $:, where is the best place (in a Thin/Rack/Sinatra context) to do so?

jabalsad
  • 2,351
  • 6
  • 23
  • 28

2 Answers2

0

$: is a global variable describing the load path, represented as an array. You can add ".", then if you care, eliminate duplicates, as follows:

$:.unshift(".").uniq!

Or you can push it to the end of the list:

$:.push(".").uniq!

It's often omitted by default because it's a potential security hazard.

djconnel
  • 441
  • 2
  • 4
  • 2
    I am aware of the technical details of adding the necessary directories to your load path, thanks :-) My question was more aimed from a design perspective: where is the right place to do this? Generally, I feel uncomfortable mucking with `$:` in source code unless there is no better way. For example, in the applications I write the load path is setup before the ruby process gets executed and then passed in via `ruby -I`. I'm not saying this is the right approach, but in this instance it's cleaner than messing with $: since it provides clear separation of the environment from the application. – jabalsad Jun 22 '12 at 12:08
0

I'm wondering the same thing. I'll tell you what I'm doing and try to justify it. Perhaps in the process of writing this, I'll have figured something out.

I have decided, for now, to add to $LOAD_PATH in config.ru, because I'm using config.ru as the entry point of my application. I can get away with this because I intend to leave this file in the root of the project. I don't like making that assumption, but it seems pretty safe for now. Of course, I'll leave a comment saying "Ew. Assumes that this file is the only entry point of the application and that it will always be in the root of the project."

I chose this because I want to add to $LOAD_PATH as high up in the call stack as possible (Dependency Inversion Principle), but doing so in the commands that run the app (Procfile running thin in production; command line running shotgun in development) duplicates the directories that I want to add to the load path. Do I classify this duplication as essential (worth removing) or coincidental (worth duplicating)? For now, it looks like an essential aspect of the app, at least as I've decided to organise it, because the app integrates the various services into a single request/response/routing engine. Also, config.ru describes the app, so it makes sense to treat it as the app.

If the situation changes and I notice that I want a different $LOAD_PATH in development than in production, then I'll move the directories up the call stack into the command that runs config.ru.

I feel comfortable with this choice, not because I consider it "the right choice", but because I think I know how and why I'd change my mind. Good enough for me.

I hope this helps.

J. B. Rainsberger
  • 1,193
  • 9
  • 23