[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Library path relative to current .rb file

zoranlazarevic

11/24/2003 9:01:00 AM

One of the most irritating (missing) features of Ruby is inability to
'require' files in the same directory or subdirectories as the
executing source file. In other programming languages (Java, C, C++)
that is commonly used. Note that this is different from the current
woriking directory.

I do not want to add the directory of the currenty executing file to
the library path because that would apply to all the other files,
including standard library (e.g. I usually have 'utils.rb' in every
project, and that would make a confusion if I tried to use two
projects).

$LOAD_PATH << File.dirname($0) # VERY BAD - does not work for
libs
$LOAD_PATH << File.dirname(__FILE__) # Also VERY BAD - huge
LOAD_PATH

The solution is to prepend current file's directory before every
'require', which is very ugly.

require File.join(File.dirname(__FILE__), 'utils' ) # UGLY

My question is:
- Why aren't required files looked up in subdirectories relative to
the current file?
- Is there an easy way to simulate that in Ruby?
- Can it be easily fixed in Ruby interpreter source code?

Thanks,

--Laza
11 Answers

Gavin Sinclair

11/24/2003 12:44:00 PM

0

On Monday, November 24, 2003, 8:02:12 PM, Zoran wrote:

> One of the most irritating (missing) features of Ruby is inability to
> 'require' files in the same directory or subdirectories as the
> executing source file. In other programming languages (Java, C, C++)
> that is commonly used. Note that this is different from the current
> woriking directory.

Agreed.

> [...]

> The solution is to prepend current file's directory before every
> 'require', which is very ugly.

> require File.join(File.dirname(__FILE__), 'utils' ) # UGLY

It's a lot less ugly if you separate the ugly stuff into a variable
first.

require 'pathname' # 1.8

this_dir = Pathname.new(File.dirname(__FILE__))

require this_dir + "utils.rb"


> My question is:
> - Why aren't required files looked up in subdirectories relative to
> the current file?

Well, they dhould use $LOAD_PATH, shouldn't they? Perhaps you mean
another syntax.

> - Is there an easy way to simulate that in Ruby?

No.

> - Can it be easily fixed in Ruby interpreter source code?

Probably. Adding syntax is easy of you know what you're doing (I
don't), but it's controversial at this stage of Ruby's life.

Search for an RCR (www.rubygarden.org) on it; create a new one if
there is none.

Personally, although I have occasionally wanted what you want, I don't
think I've (in recent times) ever actually used the __FILE__ trick for
'require'. It's more a case of taking a look at how files/directories
are laid out.

I'll have plenty of specific advice if you detail what you're trying
to do :)

Cheers,
Gavin



Andrew Walrond

11/24/2003 9:10:00 PM

0


The full solution is worse. To handle the case of the script being executed
via symlinks or relative paths, you need to do something like this:

require 'ftools'
dir = File.expand_path(__FILE__)
while File.symlink?(dir); dir = File.readlink(dir); end
SCRIPT_DIR = File.dirname(dir)

require SCRIPT_DIR+'/my_script.rb'
...


Gavin Sinclair

11/25/2003 9:22:00 AM

0

On Tuesday, November 25, 2003, 8:09:36 AM, Andrew wrote:


> The full solution is worse. To handle the case of the script being executed
> via symlinks or relative paths, you need to do something like this:

> require 'ftools'
> dir = File.expand_path(__FILE__)
> while File.symlink?(dir); dir = File.readlink(dir); end
> SCRIPT_DIR = File.dirname(dir)

> require SCRIPT_DIR+'/my_script.rb'
> ...


require 'pathname'
dir = Pathname.new(File.expand_path(__FILE__)).realpath

Gavin


Andrew Walrond

11/25/2003 7:00:00 PM

0

On Tuesday 25 Nov 2003 9:21 am, Gavin Sinclair wrote:
>
> require 'pathname'
> dir = Pathname.new(File.expand_path(__FILE__)).realpath
>
> Gavin

I love this language :)



zoranlazarevic

11/25/2003 8:40:00 PM

0

Gavin Sinclair <gsinclair@soyabean.com.au> wrote in message news:<16710416244.
> require 'pathname'
> dir = Pathname.new(File.expand_path(__FILE__)).realpath

We probably need function 'require_local' because this is often used.
Or maybe an extra argument to require ( require
'myfile',:relative=>true )

require 'require_local'
require_local 'path_relative to this file'

....

require 'pathname'
def require_local filename
dir = Pathname.new(File.expand_path(__FILE__)).realpath
require File.join(dir,filename)
end


--Laza

Gavin Sinclair

11/25/2003 8:53:00 PM

0

On Wednesday, November 26, 2003, 5:59:45 AM, Andrew wrote:

> On Tuesday 25 Nov 2003 9:21 am, Gavin Sinclair wrote:
>>
>> require 'pathname'
>> dir = Pathname.new(File.expand_path(__FILE__)).realpath
>>
>> Gavin

> I love this language :)

I love that (little-known) library! :)



Andrew Walrond

11/25/2003 10:44:00 PM

0

On Tuesday 25 Nov 2003 8:53 pm, Gavin Sinclair wrote:
> On Wednesday, November 26, 2003, 5:59:45 AM, Andrew wrote:
> > On Tuesday 25 Nov 2003 9:21 am, Gavin Sinclair wrote:
> >> require 'pathname'
> >> dir = Pathname.new(File.expand_path(__FILE__)).realpath

Even better,

dir = Pathname.new(__FILE__).expand_path.realpath


Andrew Walrond

11/25/2003 11:13:00 PM

0

On Tuesday 25 Nov 2003 10:43 pm, Andrew Walrond wrote:
> On Tuesday 25 Nov 2003 8:53 pm, Gavin Sinclair wrote:
> > On Wednesday, November 26, 2003, 5:59:45 AM, Andrew wrote:
> > > On Tuesday 25 Nov 2003 9:21 am, Gavin Sinclair wrote:
> > >> require 'pathname'
> > >> dir = Pathname.new(File.expand_path(__FILE__)).realpath
>
> Even better,
>
> dir = Pathname.new(__FILE__).expand_path.realpath

Actually, this appears to be broken when I try to use it. Example:

root@bob root # ls -l /sbin/rubyx
lrwxrwxrwx 1 root root 23 Nov 24 20:41 /sbin/rubyx -> /pkg/rubyx.1/sbin/rubyx
root@bob root # irb
irb(main):001:0> require 'pathname'
=> true
irb(main):002:0> Pathname.new('/sbin/rubyx')
=> #<Pathname:/sbin/rubyx>
irb(main):003:0> Pathname.new('/sbin/rubyx').realpath
Errno::ENOENT: No such file or directory - /sbin/pkg
from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:144:in `lstat'
from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:144:in `realpath_rec'
from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:125:in `scan'
from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:125:in `realpath_rec'
from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:149:in `realpath_rec'
from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:125:in `scan'
from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:125:in `realpath_rec'
from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:113:in `realpath'
from (irb):3
from :0
irb(main):004:0>



Tanaka Akira

11/25/2003 11:30:00 PM

0

In article <200311252313.21059.andrew@walrond.org>,
Andrew Walrond <andrew@walrond.org> writes:

> Actually, this appears to be broken when I try to use it. Example:
>
> root@bob root # ls -l /sbin/rubyx
> lrwxrwxrwx 1 root root 23 Nov 24 20:41 /sbin/rubyx -> /pkg/rubyx.1/sbin/rubyx
> root@bob root # irb
> irb(main):001:0> require 'pathname'
> => true
> irb(main):002:0> Pathname.new('/sbin/rubyx')
> => #<Pathname:/sbin/rubyx>
> irb(main):003:0> Pathname.new('/sbin/rubyx').realpath
> Errno::ENOENT: No such file or directory - /sbin/pkg
> from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:144:in `lstat'
> from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:144:in `realpath_rec'
> from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:125:in `scan'
> from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:125:in `realpath_rec'
> from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:149:in `realpath_rec'
> from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:125:in `scan'
> from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:125:in `realpath_rec'
> from /pkg/ruby.1/lib/ruby/1.8/pathname.rb:113:in `realpath'
> from (irb):3
> from :0
> irb(main):004:0>

It is already fixed in latest CVS version.
--
Tanaka Akira


Andrew Walrond

11/25/2003 11:33:00 PM

0

On Tuesday 25 Nov 2003 11:29 pm, Tanaka Akira wrote:
>
> It is already fixed in latest CVS version.

Excellent - thanks!