I don't understand the meaning of $:<< "."
in Ruby.
I upgraded Ruby to 1.9.1, but a program was not working. My classmate told me that I am supposed to add $:<< "."
What does $:<< "."
do?
I don't understand the meaning of $:<< "."
in Ruby.
I upgraded Ruby to 1.9.1, but a program was not working. My classmate told me that I am supposed to add $:<< "."
What does $:<< "."
do?
$:
is the variable that holds an array of paths that make up your Ruby's load path <<
appends an item to the end of the array .
refers to the current directory
1 2 3
| | |
V V V
$: << "."
So you are adding the current directory to Ruby's load path
References:
Can be found in the Execution Environment Variables
section of of this page from The Pragmatic Programmers Guide
An array of strings, where each string specifies a directory to be searched for Ruby scripts and binary extensions used by the load and require methods. The initial value is the value of the arguments passed via the -I command-line option, followed by an installation-defined standard library location, followed by the current directory (“.”)[Obviously this link is for an older version of Ruby as this is still in there]. This variable may be set from within a program to alter the default search path; typically, programs use $: << dir to append dir to the path.
Can be found in the docs for array at ruby-doc.org.
Append—Pushes the given object on to the end of this array. This expression returns the array itself, so several appends may be chained together.
Since version 1.9, Ruby doesn't look for required files in the current working directory AKA .
. The $LOAD_PATH
or $:
global variable is an array of paths where Ruby looks for files you require
.
By adding $:<< "."
to your files, you are actually telling Ruby to include your current directory in the search paths. That overrides new Ruby behavior.
In your example you add working directory ("."
) to ruby load path ($:
).
Working directory ("."
) was removed from load path (global variable $:
or $-I
or $LOAD_PATH
) in Ruby 1.9 because it was considered a security risk:
==Project1/main1.rb:
$: << "." require 'init'
==Project1/init.rb:
puts 'init 1'
And you have alike project:
==Project2/main2.rb:
$: << "." require 'init'
==Project2/init.rb:
puts 'init 2'
If you run Project1 from Project2 folder, then main1.rb will require Project2/init.rb, not Project1/init.rb:
~/Projects/Project2$ ruby ../Project1/main1.rb
init 2 # may be unexpected an dangerous
~/Projects/Project2$ ruby main2.rb
init 2
You can change your working directory in your code, e.g. using Dir.chdir
:
ruby-1.9.2-p290 :002 > puts File.expand_path('.')
=> /home/alex/Projects
ruby-1.9.2-p290 :003 > Dir.chdir('..')
ruby-1.9.2-p290 :004 > puts File.expand_path('.')
=> /home/alex
I recommend you to use the following techniques instead of $: << '.'
:
require_relative (Ruby 1.9 only)
Add folder of the file to the working directory (common approach because it is compatible with Ruby 1.8): $: << File.expand_path('..', __FILE__) etc.
. __FILE__
is a reference to the current file name. File.expand_path converts a pathname to an absolute pathname.