What Does _File_ Mean in Ruby

What does __FILE__ mean in Ruby?

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

Why is __FILE__ uppercase and __dir__ lowercase?

I think that is because __FILE__ is a parse-time constant whereas __dir__ is a function and returns File.dirname(File.realpath(__FILE__))

For more details, see This discussion

What is '$:.unshift File.dirname(__FILE__)' doing?

It's adding the current file's directory to the load path. $: represents the load path (which is an array) and unshift prepends to the beginning of the array.

The reason it's there (and at the top) is so that all those requires needn't worry about the path.

Is require File.expand_path(..., __FILE__) the best practice?

In Ruby 1.9.2 + require_relative is probably the more correct way to do it.

require was changed to not include your '.' directory for security reasons. require_relative was added to provide a local-file solution for modules relative to your calling script's path.

You can search here on StackOverflow, particularly in "What is require_relative in Ruby?", and the internets and find usage tricks and the why-for messages explaining how it came about.

What Does require File.expand_path('../../config/environment', __FILE__) do Exactly?

__FILE__ is the relative path to the file from current directory. File.expand_path will get you absolute path of file, so above in your question require the environment.rb file.
$: contains the array of required path, so $:.push append the your given path into list of required path, so that you can require that file in your app. Rails push various file while booting process.

What's the equivalent of python's __file__ in ruby?

There's nothing exactly equivalent.

All files that have been required are listed in $LOADED_FEATURES in the order they were required. So, if you want to know where a file came from directly after it was required, you simply need to look at the end:

$LOADED_FEATURES.last if require 'yaml'
# => 'C:/Program Files/Ruby/lib/ruby/1.9.1/yaml.rb'

However, unless you record every call to require it's going to be hard to figure out which entry corresponds to which call. Also, if a file is already in $LOADED_FEATURES, it will not get loaded again:

require 'yaml'
# => true
# true means: the file was loaded

$LOADED_FEATURES.last
# => 'C:/Program Files/Ruby/lib/ruby/1.9.1/yaml.rb'

require 'json'
$LOADED_FEATURES.last
# => 'C:/Program Files/Ruby/lib/ruby/1.9.1/json.rb'

require 'yaml'
# => false
# false means: the file wasn't loaded again, because it has already been loaded

$LOADED_FEATURES.last
# => 'C:/Program Files/Ruby/lib/ruby/1.9.1/json.rb'
# Last loaded feature is still JSON, because YAML wasn't actually loaded twice

Also, many libraries aren't contained in a single file. So, the required files might themselves contain calls to require. In my case, for example, require 'yaml' not only loads yaml.rb but a whole bunch of files (15 to be exact):

  1. C:/Program Files/Ruby/lib/ruby/1.9.1/i386-mingw32/stringio.so
  2. C:/Program Files/Ruby/lib/ruby/1.9.1/i386-mingw32/syck.so
  3. C:/Program Files/Ruby/lib/ruby/1.9.1/syck/error.rb
  4. C:/Program Files/Ruby/lib/ruby/1.9.1/syck/basenode.rb
  5. C:/Program Files/Ruby/lib/ruby/1.9.1/syck/syck.rb
  6. C:/Program Files/Ruby/lib/ruby/1.9.1/syck/tag.rb
  7. C:/Program Files/Ruby/lib/ruby/1.9.1/syck/stream.rb
  8. C:/Program Files/Ruby/lib/ruby/1.9.1/syck/constants.rb
  9. C:/Program Files/Ruby/lib/ruby/1.9.1/date/format.rb
  10. C:/Program Files/Ruby/lib/ruby/1.9.1/date.rb
  11. C:/Program Files/Ruby/lib/ruby/1.9.1/syck/rubytypes.rb
  12. C:/Program Files/Ruby/lib/ruby/1.9.1/syck/types.rb
  13. C:/Program Files/Ruby/lib/ruby/1.9.1/yaml/syck.rb
  14. C:/Program Files/Ruby/lib/ruby/1.9.1/syck.rb
  15. C:/Program Files/Ruby/lib/ruby/1.9.1/yaml.rb

What does __FILE__ == $PROGRAM_NAME mean in ruby?

__FILE__ always returns the path of the source file. It's not a variable so you can't assign value to it. Whether it returns a relative path or an absolute one depends on how you run the script.

$PROGRAM_NAME or $0 by default returns the command that boots the program (minus the path of ruby interpreter). For example, you have a script file test.rb like this:

#!/usr/bin/env ruby
puts __FILE__
puts $PROGRAM_NAME

If you run this script with ruby test.rb, it prints

test.rb
test.rb

If you run the script with ruby /path/to/test.rb, it prints

/path/to/test.rb
/path/to/test.rb

If you give the script an execution permission and run it with ./test.rb, it prints

./test.rb
./test.rb

Unlike __FILE__, $PROGRAM_NAME and $0 are real global variables, and you can change their values. $PROGRAM_NAME and $0 are aliases to each other, so you change the value of either one, the value of the other will change accordingly. For example, you have a test2.rb like this:

#!/usr/bin/env ruby
$0 = 'Hello, world!'
puts $0
puts $PROGRAM_NAME

it prints

Hello, world!
Hello, world!

What exactly does $:.unshift(File.expand_path(../../lib, __FILE__)) do?

$: holds Load path for scripts and binary modules by load or require. . And Array#unshift will prepend the new path to $:. File#expand_path Converts a pathname to an absolute pathname. __FILE__ is already answered here What does __FILE__ mean in Ruby?.

`__FILE__` not working within `DATA`/`__END__`

__END__ and DATA aren't really relevant here. You're simply passing a string to Kernel#eval. For example, a simple eval('__FILE__') also returns "(eval)" because that's the default filename. It can be changed by passing another string but as third argument:

eval('__FILE__', nil, 'hello.rb')  # => "hello.rb"

Or in your case:

eval(DATA.read, nil, __FILE__)


Related Topics



Leave a reply



Submit