Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

ruby

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 not
  • require will store the ruby file path inside $LOADED_FEATURES aka $" while load will not
  • require will search $LOADED_FEATURES before "loading" the file again while load will not

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?

like image 890
mbigras Avatar asked Dec 31 '16 20:12

mbigras


People also ask

What is the difference between require and Require_relative?

require_relative requires a file specifically pointed to relative to the file that calls it. require requires a file included in the $LOAD_PATH.

What is difference between load and require in Ruby?

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.


1 Answers

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.

like image 118
akuhn Avatar answered Oct 12 '22 13:10

akuhn