Search code examples
rubyrubygemsrubymine

What is the best practice to read a file (under lib) while developing a gem?


I experienced some pain when deal with the "path" in developing a gem. Here is the folder structure

production codes:

lib/gem_name/foo/templates/some_template.erb
lib/gem_name/foo/bar.rb

test codes:

test/gem_name/foo/bar_test.rb

In bar.rb, I read the template by:

File.read("templates/some_template.erb") => Errno::ENOENT: No such file or directory

when I run the unit test in bar_test.rb in RubyMine, it gives me the error:

Errno::ENOENT: No such file or directory - D:/.../test/gem_name/foo/templates/some_template.erb

Obviously the test in the path is wrong.

My question are,

  1. How to deal with this issues?
  2. What is the best practice to handle such path problem while developing a gem?

Edit:
Since __FILE__ only returns the path of the file it is written, currently I define fname (see @ckruse's answer) like functions in every file I need it. It works but it is not elegant. Perhaps someone will have a better solution than mine on this. If so, please let me know.:)


Solution

  • You can always refer to the directory of the current file by File.dirname(__FILE__) and then use relative pathes, e.g.:

    fname = File.dirname(__FILE__) + "/templates/some_template.rb"
    File.read(fname)
    

    Edit: To shortcut this just write a method:

    def fname(file)
      File.dirname(__FILE__) + "/../til/../project/../root/../" + file
    end
    

    Edit 3: You also could use caller to always refer to the directory of the calling file:

    def fname(file)
      path, _ = caller.first.split(':', 2)
      File.dirname(path) + "/" + file
    end