AlexNikolaev94 AlexNikolaev94 - 1 year ago 61
Ruby Question

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.

Answer Source

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'))
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download