Upgrade to Pro — share decks privately, control downloads, hide ads and more …

In the beginning, there was require...

Adam McCrea
November 20, 2019

In the beginning, there was require...

Almost every Ruby program begins with the "require" method, but many of us don't pause to think about what it's doing until it fails us.

What happens when we call "require"? How does Ruby find what we're looking for? Is Bundler somehow involved? What about "require_relative" and "require_dependency"?

This talk will guide beginner and intermediate Rubyists through these foundational concepts that power our Ruby programs, from single-file script to a behemoth Rails 6 app.

Adam McCrea

November 20, 2019
Tweet

More Decks by Adam McCrea

Other Decks in Technology

Transcript

  1. REQUIRE A STANDARD LIBRARY > CSV # NameError (uninitialized constant

    CSV) > require 'csv' # true > CSV # CSV > require 'csv' # false
  2. > Kernel.methods.sort # [ :attr_accessor, # :attr_reader, # :attr_writer, #

    ... # :puts, # :raise, # :require, # :require_relative, # ...
  3. REQUIRE A GEM > Minitest # NameError (uninitialized constant Minitest)

    > require 'minitest' # true > Minitest # Minitest
  4. GEM ACTIVATION > $LOAD_PATH.grep(/minitest/) # [] > require 'minitest' #

    true > $LOAD_PATH.grep(/minitest/) # [".../ruby/2.6.4/lib/ruby/gems/2.6.0/gems/minitest-5.11.3/lib"]
  5. KERNEL#REQUIRE FROM RUBYGEMS Check LOADED_FEATURES Check LOAD_PATH Check for a

    matching installed gem Add gem's lib* dir to LOAD_PATH Resume default require behavior
  6. REQUIRE WITHIN A PROJECT ~/project ├── main.rb └── lib └──

    example.rb # main.rb require 'example' require 'lib/example'
  7. REQUIRE WITHIN A PROJECT ~/project ├── main.rb └── lib └──

    example.rb # main.rb require '/Users/Adam/project/lib/example'
  8. REQUIRE WITHIN A PROJECT ~/project ├── main.rb └── lib └──

    example.rb # main.rb require './lib/example' $ ruby project/main.rb
  9. ADD TO LOAD PATH ~/project ├── main.rb └── lib └──

    example.rb # main.rb $LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib') require 'example'
  10. ALTER LOAD_PATH AT RUNTIME ~/project ├── main.rb └── test ├──

    test_helper.rb └── example_test.rb # example_test.rb require 'test_helper' $ ruby -I test test/example_test.rb
  11. REQUIRE RELATIVE ~/project ├── main.rb └── lib └── example.rb #

    main.rb require './lib/example' require_relative 'lib/example'
  12. GEM VERSIONS > require 'minitest' # true $ gem list

    minitest # minitest (5.12.2, 5.11.3) > Minitest::VERSION # "5.12.2"
  13. BUNDLER # Gemfile gem 'minitest', '~> 5.11.0' ❯ bundle install

    # Resolving dependencies... # Using minitest 5.11.3
  14. > require 'bundler' > Bundler.setup > $LOAD_PATH # [ "/Users/adam/.asdf/plugins/ruby/rubygems-plugin",

    # ".../ruby/2.6.4/lib/ruby/gems/2.6.0/gems/minitest-5.11.3/lib", # ... > require 'minitest' # true > Minitest::VERSION # "5.11.3"
  15. KERNEL#AUTOLOAD # lib/example.rb class Example puts "Example has loaded" end

    # main.rb $LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib') autoload :Example, 'example' Example # Example has loaded
  16. # app/models/active_storage/blob.rb class ActiveStorage::Blob < ActiveRecord::Base require_dependency "active_storage/blob/analyzable" require_dependency "active_storage/blob/identifiable"

    require_dependency "active_storage/blob/representable" include Analyzable include Identifiable include Representable # ... end