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:
require
will tack on an rb
extension while load
will notrequire
will store the ruby file path inside $LOADED_FEATURES
aka $"
while load
will notrequire
will search $LOADED_FEATURES
before "loading" the file again while load
will notI'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?
require_relative requires a file specifically pointed to relative to the file that calls it. require requires a file included in the $LOAD_PATH.
You should use load function mainly for the purpose of loading code from other files that are being dynamically changed so as to get updated code every time. Require reads the file from the file system, parses it, saves to the memory, and runs it in a given place.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With