LaureMFischer / ga-multifiles-lab

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ways to load code.

Ways to load code

load, autoload, require and require_relative.

Load Path

Ruby will look in it's $LOAD_PATH global variable for a list of directories to look for ruby files.

Open pry and look at the $LOAD_PATH

pry(main)> $LOAD_PATH pry(main)> $:

Kernel#load

This will reload the ruby file every time it's called. Good for debugging.

pry(main)> load 'calendar.rb'

change the file

pry(main)> load './calendar.rb'

notice the changes

pry(main)> load './calendar'

Must have the .rb on the file name to load.

Kernel#require

This will load a ruby file ONCE. All subsequent require statements will not load the file.

*Doesn't need the .rb file extension, but won't hurt if it's there. *Does need the relative path './'.

pry(main)> require './calendar'

change the file

pry(main)> require './calendar'

notice the changes are NOT seen!

Kernel#require_relative

Problem with Kernel#relative is that the relative path is relative to where ruby was invoked/executed. Its not relative to where the file resides.

In the show_person.rb file we use this require to try to load the Person class.

require './lib/person' ...

When we run this in the root directory of this project it will work. Because it's looking for the file defining the Person class, person.rb, in the child directory 'lib'.

$ ruby bin/show_person.rb

OK, if we run it in the root directory

$ cd bin

If we cd into the bin directory and try to run this it will fail.

$ ruby show_person.rb

Fails, it's looking for the file in bin/lib/person.rb `require': cannot load such file -- ./lib/person (LoadError)

The fix is to use require_relative. This will try to find the file relative to the file that has that has the require_relative statement.

    In bin/show_person.rb:
  • uncomment require_relative '../lib/person'
  • comment out require './lib/person'
$ ruby bin/show_person.rb

Still OK, if run it in the root directory.

$ cd bin $ ruby show_person.rb

Still OK

$ cd ../tmp $ ruby ../bin/show_person.rb

Still OK.

You may run across an older hack for this problem. It adds the current directory of the file in the Ruby load path. DON'T USE THIS.

$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib")

LAB

Change code and see how load, require and require_relative behave.

  • Create Person class, in the lib dir, that has name and age attributes. It will also have a method to determine if person can vote. Initially a person can vote if the are over 18.
  • Open pry and "load" this person class.
  • Create a person that is age 19.
  • Can they vote?
  • Now change the person class so that the voting age is now 21.
  • load the person class. Was the change seen?
  • Do the above for require and require relative.

Create a make_voters.rb file in the bin directory.

This will create voters of different ages, some to young to vote.

  • In the lib/make_voters.rb file add this to the top of file. require '../lib/person'

  • Run the command from the root directory "ruby bin/make_voters.rb"

  • Run the command from the bin directory "cd bin; ruby make_voters.rb"

  • Run the command from your HOME directory "cd ~; ruby your path here/make_voters.rb"

  • Change the require in this file to require_relative and do the above.

About