mbigras
mbigras

Reputation: 8055

Difference between require and load wrt to "load" and "execute"

Below are some snippets from the documentation for Kernel:

Kernel#load

Loads and executes the Ruby program in the file filename...

Kernel#require

Loads the given name...

I know there are differences between require and load for example:

I'm wondering about the distinction between the word "load" and the word "executes".

The documentation makes it seem like they are two different things. To me, "load" would mean "Hey I know about this file now" while "execute" would mean "Hey I know about this file now and I'm going to run all the commands also"

But I don't think that's right.

For example, given the following structure:

$  tree
.
├── bar.rb
├── baz.rb
└── foo.rb

0 directories, 3 files

with foo.rb:

$LOAD_PATH << __dir__
require 'bar'
load 'baz.rb'

bar.rb:

puts "Inside of bar..."

baz.rb:

puts "Inside of baz..."

When I run foo.rb I would expect "Inside of baz..." to print but not "Inside of bar..." because load "loads and executes" while require just "loads". But what actually happens is both seem to "execute":

$  ruby foo.rb
Inside of bar...
Inside of baz...

So is there a difference between "loading" and "executing" a ruby file?

Upvotes: 5

Views: 193

Answers (1)

akuhn
akuhn

Reputation: 27793

The file is always executed.

In Ruby there is no such thing as loading a file without executing it. Everything is a statement in Ruby and has to be executed. Even class and def are just statements.

To illustrate this here's a silly example

class Mystery < [Array, Object, String, Fixnum].sample
  ...
end 

This creates a class with a random superclass. Just to illustrate that Ruby has no declarations but executable statements only.

So there is no such thing as not executing a Ruby file. The difference between load and require is as you described, the latter keeps track of all loaded files to avoid reloading them.


PS, and another example

ruby --dump insns -e 'def example; end'
== disasm: <RubyVM::InstructionSequence:<main>@-e>======================
0000 trace            1                                               (   1)
0002 putspecialobject 1
0004 putspecialobject 2
0006 putobject        :example
0008 putiseq          example
0010 opt_send_without_block <callinfo!mid:core#define_method, argc:3, ARGS_SIMPLE>
0012 leave            
== disasm: <RubyVM::InstructionSequence:example@-e>=====================
0000 trace            8                                               (   1)
0002 putnil           
0003 trace            16                                              (   1)
0005 leave            

As you can see def example; end is a statement and internally calls the define_method method. So def is just syntactic sugar for a method call.

Upvotes: 7

Related Questions