Require and relative paths

(francisrammeloo@hotmail.com) #1

Hi all,

Suppose I have following code:

require "./Classes/Printer" # My personal printer class

Now if I want to run my program Ruby needs to find the Printer.rb file
in the Classes directory. But if the script was run like this:

cd ~
ruby ~/rubydev/projects/texteditor/main.rb

Then the current path will be ~ and Ruby won't find
../Classes/Printer.rb
How do I solve this problem?

Greetings,
Francis

(Robert) #2

francisrammeloo@hotmail.com wrote:

Hi all,

Suppose I have following code:

require "./Classes/Printer" # My personal printer class

Now if I want to run my program Ruby needs to find the Printer.rb file
in the Classes directory. But if the script was run like this:

cd ~
ruby ~/rubydev/projects/texteditor/main.rb

Then the current path will be ~ and Ruby won't find
./Classes/Printer.rb
How do I solve this problem?

Did you try removing "./"? Other than that, if directory "Classes" is
always relative to the script, you can use "require
File.join(File.basename($0), "Classes", "Printer")". Btw, I think you
don't need the extension, Ruby will figure automatically.

Kind regards

    robert

(Jim Menard) #3

francisrammeloo@hotmail.com wrote:

Hi all,

Suppose I have following code:

require "./Classes/Printer" # My personal printer class

Now if I want to run my program Ruby needs to find the Printer.rb file
in the Classes directory. But if the script was run like this:

cd ~
ruby ~/rubydev/projects/texteditor/main.rb

Then the current path will be ~ and Ruby won't find
../Classes/Printer.rb
How do I solve this problem?

require File.join(File.dirname(__FILE__), 'Classes', 'Printer')

Jim

···

--
Jim Menard, jimm@io.com, http://www.io.com/~jimm
"I am sure that like Java, [C#] will be a 'no pointer' language, where the
most common runtime error will be a 'NULL pointer exception'."
    -- Jerry Kott, in comp.lang.smalltalk

(Erik Veenstra) #4

require "./Classes/Printer" # My personal printer class

Now if I want to run my program Ruby needs to find the
Printer.rb file in the Classes directory. But if the script
was run like this:

$ cd ~
$ ruby ~/rubydev/projects/texteditor/main.rb

Then the current path will be ~ and Ruby won't find
./Classes/Printer.rb

How do I solve this problem?

$: << File.dirname(File.expand_path(__FILE__))
require "Classes/Printer"

Skip the "./" part. "." is already added to $:

gegroet,
Erik V. - http://www.erikveen.dds.nl/

(francisrammeloo@hotmail.com) #5

I tried to remove the "./" but that doesn't work.

Using the File.basename($0) trick gives following result:
   LoadError: No such file to load -- irb/Classes/BobParser

Perhaps I should mention that I use following emacs command: C-c C-l
and that I'm pretty new to emacs : )

(mathew) #6

Jim Menard wrote:

require File.join(File.dirname(__FILE__), 'Classes', 'Printer')

I'm inclined to prefer doing

$: << File.dirname(__FILE__)

then using the normal require syntax, just for the sake of clarity.

mathew

···

--
<URL:http://www.pobox.com/~meta/>
          WE HAVE TACOS

(francisrammeloo@hotmail.com) #7

Thank you very much.

This works, but not completely...
Suppose I have this code:

   $: << File.dirname(File.expand_path(__FILE__))
   require "Classes/Window"
   require "../Modules/InstanceCounter"

Now ruby finds "Classes/Window", but it doesn't find
"../Modules/InstanceCounter".

Is this normal?
Is there a solution?

Many thanks in advance for all helpful hints.

Best regards,
Francis

(Robert) #8

francisrammeloo@hotmail.com wrote:

I tried to remove the "./" but that doesn't work.

Using the File.basename($0) trick gives following result:
   LoadError: No such file to load -- irb/Classes/BobParser

Of course this won't work if you try it from irb. Did you try it in your
script?

Perhaps I should mention that I use following emacs command: C-c C-l
and that I'm pretty new to emacs : )

Regards

    robert

(francisrammeloo@hotmail.com) #9

require File.join(File.dirname(__FILE__), 'Classes', 'Printer') works
thanks!

I'll try Erik's trick tomorrow. His' would be even nicer.

Best regards,
Francis

(francisrammeloo@hotmail.com) #10

I found a solution, but I think it's a bit clumpsy:

   $: << File.dirname(File.expand_path(__FILE__))
   $: << File.dirname(File.expand_path(__FILE__)).sub(/(.*)\/\w+/,
'\1') <-- added
   require "Classes/Window"
   require "Modules/InstanceCounter" <-- no "../" needed anymore

Best regards,
Francis

(Erik Veenstra) #11

I found a solution, but I think it's a bit clumpsy:

$: << File.dirname(File.expand_path(__FILE__))
$: << File.dirname(File.expand_path(__FILE__)).sub(/(.*)\/\w+/, '\1')
require "Classes/Window"
require "Modules/InstanceCounter" <-- no "../" needed anymore

I couldn't do it clumpsier...:slight_smile:

This is what I would do:

f1 = File.expand_path(__FILE__)
d1 = File.dirname(f1)
d2 = File.dirname(d1)
$: << d1
$: << d2
require "Classes/Window"
require "Modules/InstanceCounter"

If you want to add more directories, upto the root, use this:

entry = File.expand_path(__FILE__)
while (not $:.include?(entry = File.dirname(entry)))
   $: << entry
end
require "Classes/Window"
require "Modules/InstanceCounter"

(Just kidding...)

Just don't use "./" or "../" or any other "relative" references
to a file in a require statement. Trying setting up $:
correctly instead and feed require the name of the library
instead of filenames.

gegroet,
Erik V. - http://www.erikveen.dds.nl/

(francisrammeloo@hotmail.com) #12

Thanks, that looks a lot better than my "solution"..

vriendelijke groeten,
Francis