问题
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?
回答1:
$:
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 directory1 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 GuideAn 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.
回答2:
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.
回答3:
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:
- Your working directory may be any folder, and your script will require files from this folder if these files have appropriate names. For example you have 2 files in Project1 folder main.rb and init.rb:
==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.
来源:https://stackoverflow.com/questions/8636328/what-does-do-to-rubys-require-path