Is there a shorter way to require a file in the same directory in ruby?

Is there a shorter way to require a file located in the same directory (how the script is executed)?

require File.expand_path(File.dirname(__FILE__) + '/some_other_script') 

I read that require "my_script" and require "./my_script" will load the script twice (the ruby ​​does not recognize that it is actually the same script), and that is why File.expand_path recommended: if it is used every time a script is required, then it will be downloaded only once.

It seems strange to me that a concise language such as Ruby does not seem to have a shorter solution. For example, python just has this:

 import .some_other_module_in_the_same_directory 

I think I could require monkey patch ... but it's just evil !; -)

+50
ruby path require
Apr 25 '09 at 8:43
source share
4 answers

With ruby ​​1.9 you can use require_relative .

+80
Oct 22 '11 at 19:40
source share

Just enter filename .

Yes, it will import it twice if you specify it as filename and ./filename , so don't do this. You do not specify .rb , so do not specify the path. I usually add the bulk of my application logic to a file in lib , and then the script in bin looks something like this:

 #!/usr/bin/env ruby $: << File.join(File.dirname(__FILE__), "/../lib") require 'app.rb' App.new.run(ARGV) 

Another advantage is that it is easier for me to do unit testing if loading the application logic does not start automatically.

+11
Apr 26 '09 at 13:01
source share

The above will work even if you run the script from another directory. However, within the same directory, the shorter forms that you link to are working as expected, and at least for ruby ​​1.9 it will not lead to a double requirement.

testa.rb

 puts "start test A" require 'testb' require './testb' puts "finish test A" 

testb.rb

 puts "start test B" puts "finish test B" 

running 'ruby testa.rb' will result in:

 start test A start test B finish test B finish test A 

However, a longer form will work even from another directory (e.g. ruby ​​somedir / script.rb)

+2
Apr 25 '09 at 12:55
source share

Put this in the standard library directory (somewhere already in the default download path $: :

 # push-loadpath.rb if caller.first $: << File.expand_path(File.dirname(caller.first)) end 

Then it should work

 % ls /path/to/ bin.rb lib1.rb lib2.rb #... % cat /path/to/bin.rb load 'push-loadpath.rb' require 'lib1' require 'lib2' #... 

caller gives you access to the current call table and tells you which file and where, therefore push-loadpath.rb uses this to add a file that push-loadpath.rb this to the download path.

Note that you must load file, not require it, so that the body can be called several times (once for each time you want to change the download path).

Alternatively, you can wrap the body with a method,

 # push-loadpath.rb def push_loadpath $: << File.expand_path(File.dirname(caller.first)) end 

This will allow you to require it and use it as follows:

 % ls /path/to/ bin.rb lib1.rb lib2.rb #... % cat /path/to/bin.rb require 'push-loadpath' push_loadpath require 'lib1' require 'lib2' #... 
+2
Apr 25 '09 at 13:56
source share



All Articles