Require, from within lib, files located under the local path

Hi.

Here's an issue I've not been able to solve for some time now.

Let's say I designed a tiny library, following a standard structure:

$ tree
.

-- LICENSE
-- README.md
-- Rakefile
-- VERSION
-- lib
  >-- mylib
  > `-- core.rb
  `-- metamorphosis.rb
-- metamorphosis.gemspec

`-- test

Using Jeweler to build and install the gem (successfully), it goes into
(for instance): home/YOU/.rvm/gems/ruby-1.9.1-p378/gems/mylib-0.1.0/

The purpose of mylib involves allowing the user who will eventually
perform a require 'mylib', to create, along the file.rb performing the
require, a folder (let's call it mylib_stuff). So the user sets up the
following structure:

$ tree
.

-- main.rb

`-- mylib_stuff
    >-- a_piece_of stuff.rb
    >-- ...
    `-- another_piece_of_stuff.rb

The core.rb file needs to use what's inside mylib_stuff/*. Using the
standard technique: require File.expand_path("../../mylib_stuff",
__FILE__), you end up with the following error: no such file to load --
/home/YOU/.rvm/gems/ruby-1.9.1-p378/gems/mylib-0.1.0/mylib_stuff/[foobar]

That's because __FILE__ is core.rb. So what I'd like to do is passing
require a path which would be aware of the location the gem mylib is
used from, so it'll access this particular path. Another script using
mylib would trigger different require statements in core.rb, involving
it's very own mylib_stuff local directory.

Thank you!

···

--
Posted via http://www.ruby-forum.com/\.

s/along the file.rb/along the main.rb/

···

--
Posted via http://www.ruby-forum.com/.

Ok so here's what I eventually did:

require 'pathname' # I love it :slight_smile:
module MyLib
def self.extended base #:nodoc:
    # the receiver is the extended module or class
    @receiver = base

    # paths of the receiver file and receiver stuff
    @base_path = Pathname.new(File.expand_path($0)).dirname
    @stuff_path = @base_path + "mylib_stuff"

    # ... do whatever with base and the paths
  end

  # ...
end

I don't know if this practice of relying on $0 is solid, though.
Any hint?

···

--
Posted via http://www.ruby-forum.com/.

Jean-denis Vauguet wrote:

I don't know if this practice of relying on $0 is solid, though.

It's very risky:
* on many platforms it's truncated
* the script which the user started running isn't necessarily the file
which is requiring your code

I suggest you look at Kernel#caller instead.

Unfortunately it just gives you strings which you have to parse
yourself, and you'll probably need to grep out all the rubygems-related
paths.

For an example, look in the sinatra gem (lib/sinatra/base.rb,
specifically methods caller_locations and caller_files). Sinatra uses
this to locate the application source code, for reading inline
templates.

···

--
Posted via http://www.ruby-forum.com/\.

Brian Candler wrote:

I suggest you look at Kernel#caller instead.

Unfortunately it just gives you strings which you have to parse
yourself, and you'll probably need to grep out all the rubygems-related
paths.

For an example, look in the sinatra gem (lib/sinatra/base.rb,
specifically methods caller_locations and caller_files). Sinatra uses
this to locate the application source code, for reading inline
templates.

Thank you so much :slight_smile:

···

--
Posted via http://www.ruby-forum.com/\.