What Is Up With __file__ And $0

The first time I encountered if __FILE__ == $0 I was more puzzled as to why to use it rather than what is actually doing. Let’s try first explaing the differnet parts of the statement and then examine a couple of examples.

What is __FILE__ anyway?

Ruby, like any language, has some reserved keywords including if, return, class; one of them happens to be __FILE__. Ruby uses __FILE__ to hold the current source file name.

How about $0 ?

A prepended $ on a variable’s name indicates a global variable. In this case, $0 contains the name of the script being executed. For example, if you run ruby hello_world.rb, the value of $0 would be hello_world.

Show me the money

To our example now:

if __FILE__ == $0
  ...
end

Now we know $0 and also __FILE__ so let’s put it together. The code inside the if statement will get executed if the file that contains the source code is the same file I’m executing! I’m not joking, that’s what it means. If you feel puzzled or stupified you are suppose to. Why on earth do I need this then?!?!?

A quick example

Let’s create 2 files, one named hello_world.rb and another one hello_pluto.rb:

# hello_world

puts "Hello world"
# hello_pluto

require_relative "hello_world"

puts "Hello Pluto"

If you run ruby hello_world what do you expect to happen? It will output “hello world”. Fairly simple.

Now, what will happen when you run ruby hello_pluto?

Hello world
Hello Pluto

Interesting, right? It actually runs the file hello_world as well. Now stick the code from hello_world inside the if statement and run hello_pluto again:

# hello_world

if __FILE__ == $0
  puts "Hello world"
end

As expected, the only thing you see being printed is Hello Pluto. So, that if statment guarantees that any code that lies within the statement will only run if the source file is the same as the script you are running.

A real example

Let’s say you are one of those good developers that test their code. You have create a Person class and you want to test it.

# Using RSpec
# We have predefined a subject user

describe "#greeting" do
  it "greets the users" do
    expect(user.greeting("Bill")).to eql("Hello Bill")
  end
end

Now, the class:

class Person
  def greeting(name)
    "Hello #{name}"
  end
end

p = Person.new
puts p.greeting("John")

What will it happen when you run your spec in this case? It will execute the two lines of code in the main scope. So you are technically running the whole script first before you even run the tests.

Even worst, if you require Person in several files, as soon as you run any of them they will start executing the code in the main first! Imagine if Person is actually doing some heavy computing and you unnecessary run it each time you require it in another file.

Now you know what the cryptic __FILE__ is and also why is it useful to sometimes use if __FILE__ == $0.

A step further with File

File objects are awesome and they deserve a separate post but we can see a more pragmatic example of __FILE__ so let’s jump on it.

File.expand_path

File.expand_path converts a path name to an absolute path name. You can change its relative path by passing a second argument that will be used a the starting point.

Let’s see if it’s easy to understand now what __FILE__ is doing in a more pragmatic approach:

# My source code lies within a directory called index.html

grab_my_base_css = File.expand_path("../../assets/base.css", __FILE__)
found_and_read = File.read(grab_my_base_css)
...

By passing __FILE__, I am able to create an absolute path that is relative to the source file. Plus, I don’t need to worry what my source code’s file name is or if it will change in the future.


yourname

Keep this sentence less than 13 words or it won't look good.