AlexNikolaev94
AlexNikolaev94

Reputation: 1209

Opening relative paths from gem

I'm writing a simple gem that can load from and save data to text files and zip archives. So, it has four methods: load_from_file, load_from_zip, save_to_file and save_to_zip respectfully. The problem is that I can't figure out how to specify relative paths for loading and saving for these methods. Here they go:

def load_from_file(filename)
  File.open(filename) do |f|
    f.each { |line| add(line) } # `add` is my another class method
  end
end

def load_from_zip(filename)
  Zip::File.open("#{filename}.zip") do |zipfile|
    zipfile.each { |entry| read_zipped_file(zipfile, entry) } # my private method
  end
end

def save_to_file(filename)
  File.write("#{filename}.txt", data)
end

def save_to_zip(filename)
  Zip::File.open("#{filename}.zip", Zip::File::CREATE) do |zipfile|
    zipfile.get_output_stream('output.txt') { |f| f.print data }
  end
end

private

def read_zipped_file(zipfile, entry)
  zipfile.read(entry).lines.each { |line| add(line) }
end

So what I want basically is to allow this gem to load and save files by relative paths whereever it is used in system, e.g. I have an app located in /home/user/my_app with two files - app.rb and data.txt, and I could be able to read the file from this directory without specifying absolute path.

Example:

# app.rb
require 'my_gem'

my_gem = MyGem.new
my_gem.load_from_file('data.txt')

(Sorry for bad English)

UPD: This is not Rails gem and I'm not using Rails. All this is only pure Ruby.

Upvotes: 1

Views: 1017

Answers (1)

Eric Duminil
Eric Duminil

Reputation: 54223

Short answer

If I understand it correctly, you don't need to change anything.

Inside app.rb and your gem, relative paths will be understood relatively to Dir.pwd.

If you run ruby app.rb from inside /home/user/my_app :

  • Dir.pwd will be /home/user/my_app
  • both app.rb and my_gem will look for 'data.txt' inside /home/user/my_app.

Useful methods, just in case

Dir.chdir

If for some reason Dir.pwd isn't the desired folder, you could change directory :

Dir.chdir('/home/user/my_app') do
  # relative paths will be based from /home/user/my_app
  # call your gem from here
end

Get the directory of current file :

__dir__ will help you get the directory :

Returns the canonicalized absolute path of the directory of the file from which this method is called.

Get the current file :

__FILE__ will return the current file. (Note : uppercase.)

Concatenate file paths :

If you need to concatenate file paths, use File.expand_path or File.join. Please don't concatenate strings.

If you don't trust that the relative path will be correctly resolved, you could send an absolute path to your method :

my_gem.load_from_file(File.expand_path('data.txt'))

Upvotes: 2

Related Questions