229

I see this all the time in Ruby:

require File.dirname(__FILE__) + "/../../config/environment"  

What does __FILE__ mean?

dreftymac
  • 31,404
  • 26
  • 119
  • 182
Josh Moore
  • 13,338
  • 15
  • 58
  • 74
  • To help tie together references, also see https://www.ruby-forum.com/topic/143383 and http://stackoverflow.com/questions/4325759/is-require-file-expand-path-file-the-best-practice?lq=1 – the Tin Man Feb 26 '14 at 17:04

4 Answers4

156

It is a reference to the current file name. In the file foo.rb, __FILE__ would be interpreted as "foo.rb".

Edit: Ruby 1.9.2 and 1.9.3 appear to behave a little differently from what Luke Bayes said in his comment. With these files:

# test.rb
puts __FILE__
require './dir2/test.rb'
# dir2/test.rb
puts __FILE__

Running ruby test.rb will output

test.rb
/full/path/to/dir2/test.rb
Community
  • 1
  • 1
Geoff
  • 3,749
  • 2
  • 28
  • 24
  • 90
    This answer is not accurate. __FILE__ is the "relative" path to the file from the current execution directory - not absolute. You must use File.expand_path(__FILE__) to get the absolute path – Luke Bayes Sep 09 '09 at 21:29
  • 8
    Double underscores were automatically removed within the comment above. – Luke Bayes Sep 09 '09 at 21:30
  • 1
    is this still true in ruby 1.9.2? – Zasz Sep 03 '11 at 15:58
  • 5
    @Zasz It works kinda different in 1.9.2. The file initially loaded has a relative \_\_FILE\_\_, but other included/required files have absolute paths. – Geoff Jan 04 '12 at 22:43
  • 11
    @LukeBayes You can preserve underscores and other special characters in Stack Overflow comments by surrounding the literal text with backticks. Write `\`__FILE__\`` to get `__FILE__`. – Rory O'Kane Jul 25 '12 at 20:52
  • 1
    @RoryO'Kane Before someone misreads this and tries to enter this into a ruby script, do not write `\`__FILE__\`` in ruby, unless you want the world to maybe explode. – Ben Aubin Oct 17 '16 at 15:50
  • I've found [references](https://ruby-doc.org/core-3.1.1/doc/keywords_rdoc.html) to the [docs](https://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-__FILE__), but they're not too specific. – x-yuri Dec 21 '22 at 22:31
  • `__FILE__` is relative only for the first (main) file. Because in this case `load_file()` is called [directly](https://github.com/ruby/ruby/blob/v3_1_3/ruby.c#L2127) and passed `$0`. When requiring files `require_internal()` [uses `search_required()`](https://github.com/ruby/ruby/blob/v3_1_3/load.c#L1117-L1120) to find the file and passes to `load_file()` the [resulting absolute path](https://github.com/ruby/ruby/blob/v3_1_3/load.c#L1136). The behavior is handy to make `$0 == __FILE__` kind of checks (self-executing files). – x-yuri Dec 22 '22 at 10:57
63

The value of __FILE__ is a relative path that is created and stored (but never updated) when your file is loaded. This means that if you have any calls to Dir.chdir anywhere else in your application, this path will expand incorrectly.

puts __FILE__
Dir.chdir '../../'
puts __FILE__

One workaround to this problem is to store the expanded value of __FILE__ outside of any application code. As long as your require statements are at the top of your definitions (or at least before any calls to Dir.chdir), this value will continue to be useful after changing directories.

$MY_FILE_PATH = File.expand_path(File.dirname(__FILE__))

# open class and do some stuff that changes directory

puts $MY_FILE_PATH
cutalion
  • 4,334
  • 1
  • 38
  • 47
Luke Bayes
  • 3,234
  • 2
  • 25
  • 20
  • 1
    ```This means that if you have any calls to Dir.chdir anywhere else in your application, this path will expand incorrectly.``` The path expanded correctly under my test. My ruby version is 2.3.7, maybe the newer ruby version fixed this issue. – Alec.Zhou Mar 25 '19 at 15:53
28

__FILE__ is the filename with extension of the file containing the code being executed.

In foo.rb, __FILE__ would be "foo.rb".

If foo.rb were in the dir /home/josh then File.dirname(__FILE__) would return /home/josh.

Ethan
  • 57,819
  • 63
  • 187
  • 237
18

In Ruby, the Windows version anyways, I just checked and __FILE__ does not contain the full path to the file. Instead it contains the path to the file relative to where it's being executed from.

In PHP __FILE__ is the full path (which in my opinion is preferable). This is why, in order to make your paths portable in Ruby, you really need to use this:

File.expand_path(File.dirname(__FILE__) + "relative/path/to/file")

I should note that in Ruby 1.9.1 __FILE__ contains the full path to the file, the above description was for when I used Ruby 1.8.7.

In order to be compatible with both Ruby 1.8.7 and 1.9.1 (not sure about 1.9) you should require files by using the construct I showed above.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Matt Wolfe
  • 8,924
  • 8
  • 60
  • 77
  • 1
    You need to prepend a slash to your relative path: `File.expand_path(File.dirname(__FILE__) + "/relative/path/to/file")` – Felix Rabe Feb 13 '13 at 21:51
  • 4
    You should never hard-code the directory separator. Use File.join instead: `File.expand_path( File.join( File.dirname(__FILE__), "relative", "path", "to", "file") )` – Andrew Hodgkinson Dec 18 '14 at 21:35
  • Andrew, can you helpe-me please? I am writing to a file using the following: path = YAML::load_file(File.open(File.join(File.dirname(__FILE__) + "/massa/users.yml"))) path[:cad_user][:user] = input_email_create.value File.open(File.join(File.dirname(__FILE__) + '/massa/users.yml'), 'w') {|f| f.write path.to_yaml } but I get the message: No such file or directory @ rb_sysopen – Tadeu Nov 29 '21 at 16:27
  • Not sure how it behaved back then, but these days `__FILE__ == $0` for the first (main) file, and an absolute path for the rest. This is handy for `__FILE__ == $0` kind of checks (self-executing files). More about it in my [other comment](https://stackoverflow.com/questions/224379/what-does-file-mean-in-ruby#comment132157943_224383). – x-yuri Dec 22 '22 at 11:02