This is the old RCRchive. It's available only for reading and reference. To submit RCRs for Ruby 1.9/2.0, and to participate in discussions about them, please visit the new RCRchive.
ruby picture

RCR 309: __DIR__

Submitted by transami (Sat Jul 30 18:54:29 UTC 2005)

Abstract

Very simple. We have __FILE__, I sometimes need File.dirname(__FILE__). It would be nice if __DIR__ were equal to that. I have tried to use __DIR__ = File.dirname(__FILE__). But Ruby won't recognize it as a constant. Even so it would be nice if it were built in.

Problem

At the very least:

  irb(main):001:0> __DIR__ = File.dirname(__FILE__)
  => "."
  irb(main):002:0> def x
  irb(main):003:1>   p __DIR__
  irb(main):004:1> end
  => nil
  irb(main):005:0> x
  NameError: undefined local variable or method `__DIR__' for main:Object
        from (irb):3:in `x'
        from (irb):5

But again built-in would be even better.

Proposal

Add __DIR__ as a built in constant.

Analysis

__DIR__ is useful info and the enduser can't get a similar constant to __FILE__ (w/o a hack at least).

Implementation

__DIR__ = File.dirname(__FILE__)
ruby picture
Comments Current voting
Hi --

You could define it as a method:

  module Kernel
    def __DIR__
      File.dirname(__FILE__)
    end
  end 

David Black


Ah, Kernel method. Of course. Thanks. Had constant stuck in my mind for some reason.

T.


I should point out for those who don;t see it right off, that this is still a viable addition despite it being definable as a kernel method. Notice that the kernel method will always return the directory location of the file it is defined in, not the one you call it from. So it doesn't really work.


module Kernel
  def __DIR__
    (/^(.+)?:\d+/ =~ caller[0]) ? File.dirname($1) : nil
  end
end


Hey, thanks! That went right into Facets. If you would like I can credit you in the source code, whomever you are?

T. (Trans)


IMO this method should continue to work even if the user changes the current directory; I don't believe the above implementations do. You can use File.expand_path to expand the path relative to a given directory, namely the current working directory at the time the file was loaded. I haven't tried it, but my first pass would be to modify the above code to:

  module Kernel
    BASE_DIR = Dir.getwd
    def __DIR__
      (/^(.+)?:\d+/ =~ caller[0]) ? File.expand_path(File.dirname($1), BASE_DIR) : nil
    end
  end

though this is still not perfect if a library changes the current working directory when it is required (which is a bad thing to do IMO, but nevertheless possible).

I believe that a perfect solution in pure ruby would be too complex to be worthwhile. I would rather see this implemented in C.

-- Paul Brannan


Strongly opposed1
Opposed1
Neutral1
In favor3
Strongly advocate4
ruby picture
ruby picture

Powered by Ruby on Rails.