summaryrefslogtreecommitdiff
path: root/spec/ruby/language/predefined_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/language/predefined_spec.rb')
-rw-r--r--spec/ruby/language/predefined_spec.rb842
1 files changed, 590 insertions, 252 deletions
diff --git a/spec/ruby/language/predefined_spec.rb b/spec/ruby/language/predefined_spec.rb
index 61ca0d8237..fc1667a38f 100644
--- a/spec/ruby/language/predefined_spec.rb
+++ b/spec/ruby/language/predefined_spec.rb
@@ -1,4 +1,5 @@
require_relative '../spec_helper'
+require_relative '../core/exception/shared/set_backtrace'
require 'stringio'
# The following tables are excerpted from Programming Ruby: The Pragmatic Programmer's Guide'
@@ -7,37 +8,33 @@ require 'stringio'
# Entries marked [r/o] are read-only and an error will be raised of the program attempts to
# modify them. Entries marked [thread] are thread local.
-=begin
-Exception Information
----------------------------------------------------------------------------------------------------
-
-$! Exception The exception object passed to raise. [thread]
-$@ Array The stack backtrace generated by the last exception. [thread]
-=end
-
-=begin
-Pattern Matching Variables
----------------------------------------------------------------------------------------------------
-
-These variables are set to nil after an unsuccessful pattern match.
-
-$& String The string matched (following a successful pattern match). This variable is
- local to the current scope. [r/o, thread]
-$+ String The contents of the highest-numbered group matched following a successful
- pattern match. Thus, in "cat" =~/(c|a)(t|z)/, $+ will be set to “t”. This
- variable is local to the current scope. [r/o, thread]
-$` String The string preceding the match in a successful pattern match. This variable
- is local to the current scope. [r/o, thread]
-$' String The string following the match in a successful pattern match. This variable
- is local to the current scope. [r/o, thread]
-$1 to $<N> String The contents of successive groups matched in a successful pattern match. In
- "cat" =~/(c|a)(t|z)/, $1 will be set to “a” and $2 to “t”. This variable
- is local to the current scope. [r/o, thread]
-$~ MatchData An object that encapsulates the results of a successful pattern match. The
- variables $&, $`, $', and $1 to $<N> are all derived from $~. Assigning to $~
- changes the values of these derived variables. This variable is local to the
- current scope. [thread]
-=end
+# Exception Information
+# ---------------------------------------------------------------------------------------------------
+#
+# $! Exception The exception object passed to raise. [thread]
+# $@ Array The stack backtrace generated by the last exception. [thread]
+
+# Pattern Matching Variables
+# ---------------------------------------------------------------------------------------------------
+#
+# These variables are set to nil after an unsuccessful pattern match.
+#
+# $& String The string matched (following a successful pattern match). This variable is
+# local to the current scope. [r/o, thread]
+# $+ String The contents of the highest-numbered group matched following a successful
+# pattern match. Thus, in "cat" =~/(c|a)(t|z)/, $+ will be set to “t”. This
+# variable is local to the current scope. [r/o, thread]
+# $` String The string preceding the match in a successful pattern match. This variable
+# is local to the current scope. [r/o, thread]
+# $' String The string following the match in a successful pattern match. This variable
+# is local to the current scope. [r/o, thread]
+# $1 to $<N> String The contents of successive groups matched in a successful pattern match. In
+# "cat" =~/(c|a)(t|z)/, $1 will be set to “a” and $2 to “t”. This variable
+# is local to the current scope. [r/o, thread]
+# $~ MatchData An object that encapsulates the results of a successful pattern match. The
+# variables $&, $`, $', and $1 to $<N> are all derived from $~. Assigning to $~
+# changes the values of these derived variables. This variable is local to the
+# current scope. [thread]
describe "Predefined global $~" do
@@ -53,10 +50,10 @@ describe "Predefined global $~" do
it "is set to nil if the last match was unsuccessful" do
/foo/ =~ 'foo'
- $~.nil?.should == false
+ $~.should_not.nil?
/foo/ =~ 'bar'
- $~.nil?.should == true
+ $~.should.nil?
end
it "is set at the method-scoped level rather than block-scoped" do
@@ -75,7 +72,7 @@ describe "Predefined global $~" do
match2.should_not == nil
$~.should == match2
- eval 'match3 = /baz/.match("baz")'
+ match3 = /baz/.match("baz")
match3.should_not == nil
$~.should == match3
@@ -92,8 +89,8 @@ describe "Predefined global $~" do
$~ = /foo/.match("foo")
$~.should be_an_instance_of(MatchData)
- lambda { $~ = Object.new }.should raise_error(TypeError)
- lambda { $~ = 1 }.should raise_error(TypeError)
+ -> { $~ = Object.new }.should raise_error(TypeError, 'wrong argument type Object (expected MatchData)')
+ -> { $~ = 1 }.should raise_error(TypeError, 'wrong argument type Integer (expected MatchData)')
end
it "changes the value of derived capture globals when assigned" do
@@ -137,9 +134,22 @@ describe "Predefined global $&" do
end
it "sets the encoding to the encoding of the source String" do
- "abc".force_encoding(Encoding::EUC_JP) =~ /b/
+ "abc".dup.force_encoding(Encoding::EUC_JP) =~ /b/
$&.encoding.should equal(Encoding::EUC_JP)
end
+
+ it "is read-only" do
+ -> {
+ eval %q{$& = ""}
+ }.should raise_error(SyntaxError, /Can't set variable \$&/)
+ end
+
+ it "is read-only when aliased" do
+ alias $predefined_spec_ampersand $&
+ -> {
+ $predefined_spec_ampersand = ""
+ }.should raise_error(NameError, '$predefined_spec_ampersand is a read-only variable')
+ end
end
describe "Predefined global $`" do
@@ -150,14 +160,27 @@ describe "Predefined global $`" do
end
it "sets the encoding to the encoding of the source String" do
- "abc".force_encoding(Encoding::EUC_JP) =~ /b/
+ "abc".dup.force_encoding(Encoding::EUC_JP) =~ /b/
$`.encoding.should equal(Encoding::EUC_JP)
end
it "sets an empty result to the encoding of the source String" do
- "abc".force_encoding(Encoding::ISO_8859_1) =~ /a/
+ "abc".dup.force_encoding(Encoding::ISO_8859_1) =~ /a/
$`.encoding.should equal(Encoding::ISO_8859_1)
end
+
+ it "is read-only" do
+ -> {
+ eval %q{$` = ""}
+ }.should raise_error(SyntaxError, /Can't set variable \$`/)
+ end
+
+ it "is read-only when aliased" do
+ alias $predefined_spec_backquote $`
+ -> {
+ $predefined_spec_backquote = ""
+ }.should raise_error(NameError, '$predefined_spec_backquote is a read-only variable')
+ end
end
describe "Predefined global $'" do
@@ -168,14 +191,27 @@ describe "Predefined global $'" do
end
it "sets the encoding to the encoding of the source String" do
- "abc".force_encoding(Encoding::EUC_JP) =~ /b/
+ "abc".dup.force_encoding(Encoding::EUC_JP) =~ /b/
$'.encoding.should equal(Encoding::EUC_JP)
end
it "sets an empty result to the encoding of the source String" do
- "abc".force_encoding(Encoding::ISO_8859_1) =~ /c/
+ "abc".dup.force_encoding(Encoding::ISO_8859_1) =~ /c/
$'.encoding.should equal(Encoding::ISO_8859_1)
end
+
+ it "is read-only" do
+ -> {
+ eval %q{$' = ""}
+ }.should raise_error(SyntaxError, /Can't set variable \$'/)
+ end
+
+ it "is read-only when aliased" do
+ alias $predefined_spec_single_quote $'
+ -> {
+ $predefined_spec_single_quote = ""
+ }.should raise_error(NameError, '$predefined_spec_single_quote is a read-only variable')
+ end
end
describe "Predefined global $+" do
@@ -191,9 +227,22 @@ describe "Predefined global $+" do
end
it "sets the encoding to the encoding of the source String" do
- "abc".force_encoding(Encoding::EUC_JP) =~ /(b)/
+ "abc".dup.force_encoding(Encoding::EUC_JP) =~ /(b)/
$+.encoding.should equal(Encoding::EUC_JP)
end
+
+ it "is read-only" do
+ -> {
+ eval %q{$+ = ""}
+ }.should raise_error(SyntaxError, /Can't set variable \$\+/)
+ end
+
+ it "is read-only when aliased" do
+ alias $predefined_spec_plus $+
+ -> {
+ $predefined_spec_plus = ""
+ }.should raise_error(NameError, '$predefined_spec_plus is a read-only variable')
+ end
end
describe "Predefined globals $1..N" do
@@ -218,7 +267,7 @@ describe "Predefined globals $1..N" do
end
it "sets the encoding to the encoding of the source String" do
- "abc".force_encoding(Encoding::EUC_JP) =~ /(b)/
+ "abc".dup.force_encoding(Encoding::EUC_JP) =~ /(b)/
$1.encoding.should equal(Encoding::EUC_JP)
end
end
@@ -233,12 +282,12 @@ describe "Predefined global $stdout" do
end
it "raises TypeError error if assigned to nil" do
- lambda { $stdout = nil }.should raise_error(TypeError)
+ -> { $stdout = nil }.should raise_error(TypeError, '$stdout must have write method, NilClass given')
end
it "raises TypeError error if assigned to object that doesn't respond to #write" do
obj = mock('object')
- lambda { $stdout = obj }.should raise_error(TypeError)
+ -> { $stdout = obj }.should raise_error(TypeError)
obj.stub!(:write)
$stdout = obj
@@ -247,6 +296,22 @@ describe "Predefined global $stdout" do
end
describe "Predefined global $!" do
+ it "is Fiber-local" do
+ Fiber.new do
+ raise "hi"
+ rescue
+ Fiber.yield
+ end.resume
+
+ $!.should == nil
+ end
+
+ it "is read-only" do
+ -> {
+ $! = []
+ }.should raise_error(NameError, '$! is a read-only variable')
+ end
+
# See http://jira.codehaus.org/browse/JRUBY-5550
it "remains nil after a failed core class \"checked\" coercion against a class that defines method_missing" do
$!.should == nil
@@ -398,6 +463,22 @@ describe "Predefined global $!" do
$!.should == nil
end
+ it "should be cleared when an exception is rescued even when a non-local return from block" do
+ def foo
+ [ 1 ].each do
+ begin
+ raise StandardError.new('err')
+ rescue => e
+ $!.should == e
+ return
+ end
+ end
+ end
+
+ foo
+ $!.should == nil
+ end
+
it "should not be cleared when an exception is not rescued" do
e = StandardError.new
begin
@@ -490,44 +571,112 @@ describe "Predefined global $!" do
end
end
-=begin
-Input/Output Variables
----------------------------------------------------------------------------------------------------
-
-$/ String The input record separator (newline by default). This is the value that rou-
- tines such as Kernel#gets use to determine record boundaries. If set to
- nil, gets will read the entire file.
-$-0 String Synonym for $/.
-$\ String The string appended to the output of every call to methods such as
- Kernel#print and IO#write. The default value is nil.
-$, String The separator string output between the parameters to methods such as
- Kernel#print and Array#join. Defaults to nil, which adds no text.
-$. Fixnum The number of the last line read from the current input file.
-$; String The default separator pattern used by String#split. May be set from the
- command line using the -F flag.
-$< Object An object that provides access to the concatenation of the contents of all
- the files given as command-line arguments or $stdin (in the case where
- there are no arguments). $< supports methods similar to a File object:
- binmode, close, closed?, each, each_byte, each_line, eof, eof?,
- file, filename, fileno, getc, gets, lineno, lineno=, path, pos, pos=,
- read, readchar, readline, readlines, rewind, seek, skip, tell, to_a,
- to_i, to_io, to_s, along with the methods in Enumerable. The method
- file returns a File object for the file currently being read. This may change
- as $< reads through the files on the command line. [r/o]
-$> IO The destination of output for Kernel#print and Kernel#printf. The
- default value is $stdout.
-$_ String The last line read by Kernel#gets or Kernel#readline. Many string-
- related functions in the Kernel module operate on $_ by default. The vari-
- able is local to the current scope. [thread]
-$-F String Synonym for $;.
-$stderr IO The current standard error output.
-$stdin IO The current standard input.
-$stdout IO The current standard output. Assignment to $stdout is deprecated: use
- $stdout.reopen instead.
-=end
+describe "Predefined global $@" do
+ it "is Fiber-local" do
+ Fiber.new do
+ raise "hi"
+ rescue
+ Fiber.yield
+ end.resume
+
+ $@.should == nil
+ end
+
+ it "is set to a backtrace of a rescued exception" do
+ begin
+ raise
+ rescue
+ $@.should be_an_instance_of(Array)
+ $@.should == $!.backtrace
+ end
+ end
+
+ it "is cleared when an exception is rescued" do
+ begin
+ raise
+ rescue
+ end
+
+ $@.should == nil
+ end
+
+ it "is not set when there is no current exception" do
+ $@.should == nil
+ end
+
+ it "is set to a backtrace of a rescued exception" do
+ begin
+ raise
+ rescue
+ $@.should be_an_instance_of(Array)
+ $@.should == $!.backtrace
+ end
+ end
+
+ it "is not read-only" do
+ begin
+ raise
+ rescue
+ $@ = []
+ $@.should == []
+ end
+ end
+
+ it_behaves_like :exception_set_backtrace, -> backtrace {
+ exception = nil
+ begin
+ raise
+ rescue
+ $@ = backtrace
+ exception = $!
+ end
+ exception
+ }
+
+ it "cannot be assigned when there is no a rescued exception" do
+ -> {
+ $@ = []
+ }.should raise_error(ArgumentError, '$! not set')
+ end
+end
+
+# Input/Output Variables
+# ---------------------------------------------------------------------------------------------------
+#
+# $/ String The input record separator (newline by default). This is the value that rou-
+# tines such as Kernel#gets use to determine record boundaries. If set to
+# nil, gets will read the entire file.
+# $-0 String Synonym for $/.
+# $\ String The string appended to the output of every call to methods such as
+# Kernel#print and IO#write. The default value is nil.
+# $, String The separator string output between the parameters to methods such as
+# Kernel#print and Array#join. Defaults to nil, which adds no text.
+# $. Integer The number of the last line read from the current input file.
+# $; String The default separator pattern used by String#split. May be set from the
+# command line using the -F flag.
+# $< Object An object that provides access to the concatenation of the contents of all
+# the files given as command-line arguments or $stdin (in the case where
+# there are no arguments). $< supports methods similar to a File object:
+# binmode, close, closed?, each, each_byte, each_line, eof, eof?,
+# file, filename, fileno, getc, gets, lineno, lineno=, path, pos, pos=,
+# read, readchar, readline, readlines, rewind, seek, skip, tell, to_a,
+# to_i, to_io, to_s, along with the methods in Enumerable. The method
+# file returns a File object for the file currently being read. This may change
+# as $< reads through the files on the command line. [r/o]
+# $> IO The destination of output for Kernel#print and Kernel#printf. The
+# default value is $stdout.
+# $_ String The last line read by Kernel#gets or Kernel#readline. Many string-
+# related functions in the Kernel module operate on $_ by default. The vari-
+# able is local to the current scope. [thread]
+# $-F String Synonym for $;.
+# $stderr IO The current standard error output.
+# $stdin IO The current standard input.
+# $stdout IO The current standard output. Assignment to $stdout is deprecated: use
+# $stdout.reopen instead.
describe "Predefined global $/" do
before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
@dollar_slash = $/
@dollar_dash_zero = $-0
end
@@ -535,14 +684,42 @@ describe "Predefined global $/" do
after :each do
$/ = @dollar_slash
$-0 = @dollar_dash_zero
+ $VERBOSE = @verbose
end
- it "can be assigned a String" do
- str = "abc"
- $/ = str
- $/.should equal(str)
+ ruby_version_is ""..."4.0" do
+ it "can be assigned a String" do
+ str = +"abc"
+ $/ = str
+ $/.should equal(str)
+ end
end
+ ruby_version_is "4.0" do
+ it "makes a new frozen String from the assigned String" do
+ string_subclass = Class.new(String)
+ str = string_subclass.new("abc")
+ str.instance_variable_set(:@ivar, 1)
+ $/ = str
+ $/.should.frozen?
+ $/.should be_an_instance_of(String)
+ $/.should_not.instance_variable_defined?(:@ivar)
+ $/.should == str
+ end
+
+ it "makes a new frozen String if it's not frozen" do
+ str = +"abc"
+ $/ = str
+ $/.should.frozen?
+ $/.should == str
+ end
+
+ it "assigns the given String if it's frozen and has no instance variables" do
+ str = "abc".freeze
+ $/ = str
+ $/.should equal(str)
+ end
+ end
it "can be assigned nil" do
$/ = nil
$/.should be_nil
@@ -552,7 +729,6 @@ describe "Predefined global $/" do
($/ = "xyz").should == "xyz"
end
-
it "changes $-0" do
$/ = "xyz"
$-0.should equal($/)
@@ -562,20 +738,25 @@ describe "Predefined global $/" do
obj = mock("$/ value")
obj.should_not_receive(:to_str)
- lambda { $/ = obj }.should raise_error(TypeError)
+ -> { $/ = obj }.should raise_error(TypeError, 'value of $/ must be String')
end
- it "raises a TypeError if assigned a Fixnum" do
- lambda { $/ = 1 }.should raise_error(TypeError)
+ it "raises a TypeError if assigned an Integer" do
+ -> { $/ = 1 }.should raise_error(TypeError, 'value of $/ must be String')
end
it "raises a TypeError if assigned a boolean" do
- lambda { $/ = true }.should raise_error(TypeError)
+ -> { $/ = true }.should raise_error(TypeError, 'value of $/ must be String')
+ end
+
+ it "warns if assigned non-nil" do
+ -> { $/ = "_" }.should complain(/warning: (?:non-nil )?[`']\$\/' is deprecated/)
end
end
describe "Predefined global $-0" do
before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
@dollar_slash = $/
@dollar_dash_zero = $-0
end
@@ -583,12 +764,41 @@ describe "Predefined global $-0" do
after :each do
$/ = @dollar_slash
$-0 = @dollar_dash_zero
+ $VERBOSE = @verbose
end
- it "can be assigned a String" do
- str = "abc"
- $-0 = str
- $-0.should equal(str)
+ ruby_version_is ""..."4.0" do
+ it "can be assigned a String" do
+ str = +"abc"
+ $-0 = str
+ $-0.should equal(str)
+ end
+ end
+
+ ruby_version_is "4.0" do
+ it "makes a new frozen String from the assigned String" do
+ string_subclass = Class.new(String)
+ str = string_subclass.new("abc")
+ str.instance_variable_set(:@ivar, 1)
+ $-0 = str
+ $-0.should.frozen?
+ $-0.should be_an_instance_of(String)
+ $-0.should_not.instance_variable_defined?(:@ivar)
+ $-0.should == str
+ end
+
+ it "makes a new frozen String if it's not frozen" do
+ str = +"abc"
+ $-0 = str
+ $-0.should.frozen?
+ $-0.should == str
+ end
+
+ it "assigns the given String if it's frozen and has no instance variables" do
+ str = "abc".freeze
+ $-0 = str
+ $-0.should equal(str)
+ end
end
it "can be assigned nil" do
@@ -609,15 +819,62 @@ describe "Predefined global $-0" do
obj = mock("$-0 value")
obj.should_not_receive(:to_str)
- lambda { $-0 = obj }.should raise_error(TypeError)
+ -> { $-0 = obj }.should raise_error(TypeError, 'value of $-0 must be String')
end
- it "raises a TypeError if assigned a Fixnum" do
- lambda { $-0 = 1 }.should raise_error(TypeError)
+ it "raises a TypeError if assigned an Integer" do
+ -> { $-0 = 1 }.should raise_error(TypeError, 'value of $-0 must be String')
end
it "raises a TypeError if assigned a boolean" do
- lambda { $-0 = true }.should raise_error(TypeError)
+ -> { $-0 = true }.should raise_error(TypeError, 'value of $-0 must be String')
+ end
+
+ it "warns if assigned non-nil" do
+ -> { $-0 = "_" }.should complain(/warning: (?:non-nil )?[`']\$-0' is deprecated/)
+ end
+end
+
+describe "Predefined global $\\" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ @dollar_backslash = $\
+ end
+
+ after :each do
+ $\ = @dollar_backslash
+ $VERBOSE = @verbose
+ end
+
+ it "can be assigned a String" do
+ str = "abc"
+ $\ = str
+ $\.should equal(str)
+ end
+
+ it "can be assigned nil" do
+ $\ = nil
+ $\.should be_nil
+ end
+
+ it "returns the value assigned" do
+ ($\ = "xyz").should == "xyz"
+ end
+
+ it "does not call #to_str to convert the object to a String" do
+ obj = mock("$\\ value")
+ obj.should_not_receive(:to_str)
+
+ -> { $\ = obj }.should raise_error(TypeError, 'value of $\ must be String')
+ end
+
+ it "raises a TypeError if assigned not String" do
+ -> { $\ = 1 }.should raise_error(TypeError, 'value of $\ must be String')
+ -> { $\ = true }.should raise_error(TypeError, 'value of $\ must be String')
+ end
+
+ it "warns if assigned non-nil" do
+ -> { $\ = "_" }.should complain(/warning: (?:non-nil )?[`']\$\\' is deprecated/)
end
end
@@ -631,7 +888,11 @@ describe "Predefined global $," do
end
it "raises TypeError if assigned a non-String" do
- lambda { $, = Object.new }.should raise_error(TypeError)
+ -> { $, = Object.new }.should raise_error(TypeError, 'value of $, must be String')
+ end
+
+ it "warns if assigned non-nil" do
+ -> { $, = "_" }.should complain(/warning: (?:non-nil )?[`']\$,' is deprecated/)
end
end
@@ -658,7 +919,17 @@ describe "Predefined global $." do
obj = mock("bad-value")
obj.should_receive(:to_int).and_return('abc')
- lambda { $. = obj }.should raise_error(TypeError)
+ -> { $. = obj }.should raise_error(TypeError)
+ end
+end
+
+describe "Predefined global $;" do
+ after :each do
+ $; = nil
+ end
+
+ it "warns if assigned non-nil" do
+ -> { $; = "_" }.should complain(/warning: (?:non-nil )?[`']\$;' is deprecated/)
end
end
@@ -692,7 +963,7 @@ describe "Predefined global $_" do
match.should == "bar\n"
$_.should == match
- eval 'match = stdin.gets'
+ match = stdin.gets
match.should == "baz\n"
$_.should == match
@@ -731,56 +1002,52 @@ describe "Predefined global $_" do
end
end
-=begin
-Execution Environment Variables
----------------------------------------------------------------------------------------------------
-
-$0 String The name of the top-level Ruby program being executed. Typically this will
- be the program’s filename. On some operating systems, assigning to this
- variable will change the name of the process reported (for example) by the
- ps(1) command.
-$* Array An array of strings containing the command-line options from the invoca-
- tion of the program. Options used by the Ruby interpreter will have been
- removed. [r/o]
-$" Array An array containing the filenames of modules loaded by require. [r/o]
-$$ Fixnum The process number of the program being executed. [r/o]
-$? Process::Status The exit status of the last child process to terminate. [r/o, thread]
-$: Array 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, fol-
- lowed by the current directory (“.”). 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. [r/o]
-$-a Object True if the -a option is specified on the command line. [r/o]
-$-d Object Synonym for $DEBUG.
-$DEBUG Object Set to true if the -d command-line option is specified.
-__FILE__ String The name of the current source file. [r/o]
-$F Array The array that receives the split input line if the -a command-line option is
- used.
-$FILENAME String The name of the current input file. Equivalent to $<.filename. [r/o]
-$-i String If in-place edit mode is enabled (perhaps using the -i command-line
- option), $-i holds the extension used when creating the backup file. If you
- set a value into $-i, enables in-place edit mode.
-$-I Array Synonym for $:. [r/o]
-$-K String Sets the multibyte coding system for strings and regular expressions. Equiv-
- alent to the -K command-line option.
-$-l Object Set to true if the -l option (which enables line-end processing) is present
- on the command line. [r/o]
-__LINE__ String The current line number in the source file. [r/o]
-$LOAD_PATH Array A synonym for $:. [r/o]
-$-p Object Set to true if the -p option (which puts an implicit while gets . . . end
- loop around your program) is present on the command line. [r/o]
-$SAFE Fixnum The current safe level. This variable’s value may never be
- reduced by assignment. [thread] (Not implemented in Rubinius)
-$VERBOSE Object Set to true if the -v, --version, -W, or -w option is specified on the com-
- mand line. Set to false if no option, or -W1 is given. Set to nil if -W0
- was specified. Setting this option to true causes the interpreter and some
- library routines to report additional information. Setting to nil suppresses
- all warnings (including the output of Kernel.warn).
-$-v Object Synonym for $VERBOSE.
-$-w Object Synonym for $VERBOSE.
-=end
+# Execution Environment Variables
+# ---------------------------------------------------------------------------------------------------
+#
+# $0 String The name of the top-level Ruby program being executed. Typically this will
+# be the program’s filename. On some operating systems, assigning to this
+# variable will change the name of the process reported (for example) by the
+# ps(1) command.
+# $* Array An array of strings containing the command-line options from the invoca-
+# tion of the program. Options used by the Ruby interpreter will have been
+# removed. [r/o]
+# $" Array An array containing the filenames of modules loaded by require. [r/o]
+# $$ Integer The process number of the program being executed. [r/o]
+# $? Process::Status The exit status of the last child process to terminate. [r/o, thread]
+# $: Array 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, fol-
+# lowed by the current directory (“.”). 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. [r/o]
+# $-a Object True if the -a option is specified on the command line. [r/o]
+# $-d Object Synonym for $DEBUG.
+# $DEBUG Object Set to true if the -d command-line option is specified.
+# __FILE__ String The name of the current source file. [r/o]
+# $F Array The array that receives the split input line if the -a command-line option is
+# used.
+# $FILENAME String The name of the current input file. Equivalent to $<.filename. [r/o]
+# $-i String If in-place edit mode is enabled (perhaps using the -i command-line
+# option), $-i holds the extension used when creating the backup file. If you
+# set a value into $-i, enables in-place edit mode.
+# $-I Array Synonym for $:. [r/o]
+# $-K String Sets the multibyte coding system for strings and regular expressions. Equiv-
+# alent to the -K command-line option.
+# $-l Object Set to true if the -l option (which enables line-end processing) is present
+# on the command line. [r/o]
+# __LINE__ String The current line number in the source file. [r/o]
+# $LOAD_PATH Array A synonym for $:. [r/o]
+# $-p Object Set to true if the -p option (which puts an implicit while gets . . . end
+# loop around your program) is present on the command line. [r/o]
+# $VERBOSE Object Set to true if the -v, --version, -W, or -w option is specified on the com-
+# mand line. Set to false if no option, or -W1 is given. Set to nil if -W0
+# was specified. Setting this option to true causes the interpreter and some
+# library routines to report additional information. Setting to nil suppresses
+# all warnings (including the output of Kernel.warn).
+# $-v Object Synonym for $VERBOSE.
+# $-w Object Synonym for $VERBOSE.
describe "Execution variable $:" do
it "is initialized to an array of strings" do
$:.is_a?(Array).should == true
@@ -799,20 +1066,38 @@ describe "Execution variable $:" do
it "can be changed via <<" do
$: << "foo"
$:.should include("foo")
+ ensure
+ $:.delete("foo")
end
it "is read-only" do
- lambda {
+ -> {
$: = []
- }.should raise_error(NameError)
+ }.should raise_error(NameError, '$: is a read-only variable')
- lambda {
+ -> {
$LOAD_PATH = []
- }.should raise_error(NameError)
+ }.should raise_error(NameError, '$LOAD_PATH is a read-only variable')
- lambda {
+ -> {
$-I = []
- }.should raise_error(NameError)
+ }.should raise_error(NameError, '$-I is a read-only variable')
+ end
+
+ it "default $LOAD_PATH entries until sitelibdir included have @gem_prelude_index set" do
+ skip "no sense in ruby itself" if MSpecScript.instance_variable_defined?(:@testing_ruby)
+
+ if platform_is :windows
+ # See https://github.com/ruby/setup-ruby/pull/762#issuecomment-2917460440
+ $:.should.find { |e| File.realdirpath(e) == RbConfig::CONFIG['sitelibdir'] }
+ idx = $:.index { |e| File.realdirpath(e) == RbConfig::CONFIG['sitelibdir'] }
+ else
+ $:.should.include?(RbConfig::CONFIG['sitelibdir'])
+ idx = $:.index(RbConfig::CONFIG['sitelibdir'])
+ end
+
+ $:[idx..-1].all? { |p| p.instance_variable_defined?(:@gem_prelude_index) }.should be_true
+ $:[0...idx].all? { |p| !p.instance_variable_defined?(:@gem_prelude_index) }.should be_true
end
end
@@ -822,37 +1107,37 @@ describe "Global variable $\"" do
end
it "is read-only" do
- lambda {
+ -> {
$" = []
- }.should raise_error(NameError)
+ }.should raise_error(NameError, '$" is a read-only variable')
- lambda {
+ -> {
$LOADED_FEATURES = []
- }.should raise_error(NameError)
+ }.should raise_error(NameError, '$LOADED_FEATURES is a read-only variable')
end
end
describe "Global variable $<" do
it "is read-only" do
- lambda {
+ -> {
$< = nil
- }.should raise_error(NameError)
+ }.should raise_error(NameError, '$< is a read-only variable')
end
end
describe "Global variable $FILENAME" do
it "is read-only" do
- lambda {
+ -> {
$FILENAME = "-"
- }.should raise_error(NameError)
+ }.should raise_error(NameError, '$FILENAME is a read-only variable')
end
end
describe "Global variable $?" do
it "is read-only" do
- lambda {
+ -> {
$? = nil
- }.should raise_error(NameError)
+ }.should raise_error(NameError, '$? is a read-only variable')
end
it "is thread-local" do
@@ -863,19 +1148,19 @@ end
describe "Global variable $-a" do
it "is read-only" do
- lambda { $-a = true }.should raise_error(NameError)
+ -> { $-a = true }.should raise_error(NameError, '$-a is a read-only variable')
end
end
describe "Global variable $-l" do
it "is read-only" do
- lambda { $-l = true }.should raise_error(NameError)
+ -> { $-l = true }.should raise_error(NameError, '$-l is a read-only variable')
end
end
describe "Global variable $-p" do
it "is read-only" do
- lambda { $-p = true }.should raise_error(NameError)
+ -> { $-p = true }.should raise_error(NameError, '$-p is a read-only variable')
end
end
@@ -897,6 +1182,18 @@ describe "Global variable $-d" do
end
describe "Global variable $VERBOSE" do
+ before :each do
+ @verbose = $VERBOSE
+ end
+
+ after :each do
+ $VERBOSE = @verbose
+ end
+
+ it "is false by default" do
+ $VERBOSE.should be_false
+ end
+
it "converts truthy values to true" do
[true, 1, 0, [], ""].each do |true_value|
$VERBOSE = true_value
@@ -951,7 +1248,7 @@ describe "Global variable $0" do
it "is the path given as the main script and the same as __FILE__" do
script = "fixtures/dollar_zero.rb"
- Dir.chdir(File.dirname(__FILE__)) do
+ Dir.chdir(__dir__) do
ruby_exe(script).should == "#{script}\n#{script}\nOK"
end
end
@@ -974,26 +1271,24 @@ describe "Global variable $0" do
end
it "raises a TypeError when not given an object that can be coerced to a String" do
- lambda { $0 = nil }.should raise_error(TypeError)
+ -> { $0 = nil }.should raise_error(TypeError)
end
end
-=begin
-Standard Objects
----------------------------------------------------------------------------------------------------
-
-ARGF Object A synonym for $<.
-ARGV Array A synonym for $*.
-ENV Object A hash-like object containing the program’s environment variables. An
- instance of class Object, ENV implements the full set of Hash methods. Used
- to query and set the value of an environment variable, as in ENV["PATH"]
- and ENV["term"]="ansi".
-false FalseClass Singleton instance of class FalseClass. [r/o]
-nil NilClass The singleton instance of class NilClass. The value of uninitialized
- instance and global variables. [r/o]
-self Object The receiver (object) of the current method. [r/o]
-true TrueClass Singleton instance of class TrueClass. [r/o]
-=end
+# Standard Objects
+# ---------------------------------------------------------------------------------------------------
+#
+# ARGF Object A synonym for $<.
+# ARGV Array A synonym for $*.
+# ENV Object A hash-like object containing the program’s environment variables. An
+# instance of class Object, ENV implements the full set of Hash methods. Used
+# to query and set the value of an environment variable, as in ENV["PATH"]
+# and ENV["term"]="ansi".
+# false FalseClass Singleton instance of class FalseClass. [r/o]
+# nil NilClass The singleton instance of class NilClass. The value of uninitialized
+# instance and global variables. [r/o]
+# self Object The receiver (object) of the current method. [r/o]
+# true TrueClass Singleton instance of class TrueClass. [r/o]
describe "The predefined standard objects" do
it "includes ARGF" do
@@ -1016,7 +1311,7 @@ describe "The predefined standard object nil" do
end
it "raises a SyntaxError if assigned to" do
- lambda { eval("nil = true") }.should raise_error(SyntaxError)
+ -> { eval("nil = true") }.should raise_error(SyntaxError, /Can't assign to nil/)
end
end
@@ -1026,7 +1321,7 @@ describe "The predefined standard object true" do
end
it "raises a SyntaxError if assigned to" do
- lambda { eval("true = false") }.should raise_error(SyntaxError)
+ -> { eval("true = false") }.should raise_error(SyntaxError, /Can't assign to true/)
end
end
@@ -1036,67 +1331,62 @@ describe "The predefined standard object false" do
end
it "raises a SyntaxError if assigned to" do
- lambda { eval("false = nil") }.should raise_error(SyntaxError)
+ -> { eval("false = nil") }.should raise_error(SyntaxError, /Can't assign to false/)
end
end
describe "The self pseudo-variable" do
it "raises a SyntaxError if assigned to" do
- lambda { eval("self = 1") }.should raise_error(SyntaxError)
+ -> { eval("self = 1") }.should raise_error(SyntaxError, /Can't change the value of self/)
end
end
-=begin
-Global Constants
----------------------------------------------------------------------------------------------------
-
-The following constants are defined by the Ruby interpreter.
-
-DATA IO If the main program file contains the directive __END__, then
- the constant DATA will be initialized so that reading from it will
- return lines following __END__ from the source file.
-FALSE FalseClass Synonym for false.
-NIL NilClass Synonym for nil.
-RUBY_PLATFORM String The identifier of the platform running this program. This string
- is in the same form as the platform identifier used by the GNU
- configure utility (which is not a coincidence).
-RUBY_RELEASE_DATE String The date of this release.
-RUBY_VERSION String The version number of the interpreter.
-STDERR IO The actual standard error stream for the program. The initial
- value of $stderr.
-STDIN IO The actual standard input stream for the program. The initial
- value of $stdin.
-STDOUT IO The actual standard output stream for the program. The initial
- value of $stdout.
-SCRIPT_LINES__ Hash If a constant SCRIPT_LINES__ is defined and references a Hash,
- Ruby will store an entry containing the contents of each file it
- parses, with the file’s name as the key and an array of strings as
- the value.
-TOPLEVEL_BINDING Binding A Binding object representing the binding at Ruby’s top level—
- the level where programs are initially executed.
-TRUE TrueClass Synonym for true.
-=end
+# Global Constants
+# ---------------------------------------------------------------------------------------------------
+#
+# The following constants are defined by the Ruby interpreter.
+#
+# DATA IO If the main program file contains the directive __END__, then
+# the constant DATA will be initialized so that reading from it will
+# return lines following __END__ from the source file.
+# FALSE FalseClass Synonym for false (deprecated, removed in Ruby 3).
+# NIL NilClass Synonym for nil (deprecated, removed in Ruby 3).
+# RUBY_PLATFORM String The identifier of the platform running this program. This string
+# is in the same form as the platform identifier used by the GNU
+# configure utility (which is not a coincidence).
+# RUBY_RELEASE_DATE String The date of this release.
+# RUBY_VERSION String The version number of the interpreter.
+# STDERR IO The actual standard error stream for the program. The initial
+# value of $stderr.
+# STDIN IO The actual standard input stream for the program. The initial
+# value of $stdin.
+# STDOUT IO The actual standard output stream for the program. The initial
+# value of $stdout.
+# SCRIPT_LINES__ Hash If a constant SCRIPT_LINES__ is defined and references a Hash,
+# Ruby will store an entry containing the contents of each file it
+# parses, with the file’s name as the key and an array of strings as
+# the value.
+# TOPLEVEL_BINDING Binding A Binding object representing the binding at Ruby’s top level—
+# the level where programs are initially executed.
+# TRUE TrueClass Synonym for true (deprecated, removed in Ruby 3).
describe "The predefined global constants" do
- it "includes TRUE" do
- Object.const_defined?(:TRUE).should == true
- -> {
- TRUE.should equal(true)
- }.should complain(/constant ::TRUE is deprecated/)
+ describe "TRUE" do
+ it "is no longer defined" do
+ Object.const_defined?(:TRUE).should == false
+ end
end
- it "includes FALSE" do
- Object.const_defined?(:FALSE).should == true
- -> {
- FALSE.should equal(false)
- }.should complain(/constant ::FALSE is deprecated/)
+ describe "FALSE" do
+ it "is no longer defined" do
+ Object.const_defined?(:FALSE).should == false
+ end
end
- it "includes NIL" do
- Object.const_defined?(:NIL).should == true
- -> {
- NIL.should equal(nil)
- }.should complain(/constant ::NIL is deprecated/)
+ describe "NIL" do
+ it "is no longer defined" do
+ Object.const_defined?(:NIL).should == false
+ end
end
it "includes STDIN" do
@@ -1126,7 +1416,6 @@ describe "The predefined global constants" do
it "includes TOPLEVEL_BINDING" do
Object.const_defined?(:TOPLEVEL_BINDING).should == true
end
-
end
describe "The predefined global constant" do
@@ -1141,13 +1430,24 @@ describe "The predefined global constant" do
end
describe "STDIN" do
- it "has the same external encoding as Encoding.default_external" do
- STDIN.external_encoding.should equal(Encoding.default_external)
- end
+ platform_is_not :windows do
+ it "has the same external encoding as Encoding.default_external" do
+ STDIN.external_encoding.should equal(Encoding.default_external)
+ end
+
+ it "has the same external encoding as Encoding.default_external when that encoding is changed" do
+ Encoding.default_external = Encoding::ISO_8859_16
+ STDIN.external_encoding.should equal(Encoding::ISO_8859_16)
+ end
- it "has the same external encoding as Encoding.default_external when that encoding is changed" do
- Encoding.default_external = Encoding::ISO_8859_16
- STDIN.external_encoding.should equal(Encoding::ISO_8859_16)
+ it "has nil for the internal encoding" do
+ STDIN.internal_encoding.should be_nil
+ end
+
+ it "has nil for the internal encoding despite Encoding.default_internal being changed" do
+ Encoding.default_internal = Encoding::IBM437
+ STDIN.internal_encoding.should be_nil
+ end
end
it "has the encodings set by #set_encoding" do
@@ -1162,15 +1462,6 @@ describe "The predefined global constant" do
"p [STDIN.external_encoding.name, STDIN.internal_encoding.name]"
ruby_exe(code).chomp.should == %{["IBM775", "IBM866"]}
end
-
- it "has nil for the internal encoding" do
- STDIN.internal_encoding.should be_nil
- end
-
- it "has nil for the internal encoding despite Encoding.default_internal being changed" do
- Encoding.default_internal = Encoding::IBM437
- STDIN.internal_encoding.should be_nil
- end
end
describe "STDOUT" do
@@ -1234,3 +1525,50 @@ describe "The predefined global constant" do
end
end
end
+
+describe "$LOAD_PATH.resolve_feature_path" do
+ it "returns what will be loaded without actual loading, .rb file" do
+ extension, path = $LOAD_PATH.resolve_feature_path('pp')
+ extension.should == :rb
+ path.should.end_with?('/pp.rb')
+ end
+
+ it "returns what will be loaded without actual loading, .so file" do
+ require 'rbconfig'
+ skip "no dynamically loadable standard extension" if RbConfig::CONFIG["EXTSTATIC"] == "static"
+
+ extension, path = $LOAD_PATH.resolve_feature_path('etc')
+ extension.should == :so
+ path.should.end_with?("/etc.#{RbConfig::CONFIG['DLEXT']}")
+ end
+
+ it "return nil if feature cannot be found" do
+ $LOAD_PATH.resolve_feature_path('noop').should be_nil
+ end
+end
+
+# Some other pre-defined global variables
+
+describe "Predefined global $=" do
+ before :each do
+ @verbose, $VERBOSE = $VERBOSE, nil
+ @dollar_assign = $=
+ end
+
+ after :each do
+ $= = @dollar_assign
+ $VERBOSE = @verbose
+ end
+
+ it "warns when accessed" do
+ -> { a = $= }.should complain(/is no longer effective/)
+ end
+
+ it "warns when assigned" do
+ -> { $= = "_" }.should complain(/is no longer effective/)
+ end
+
+ it "returns the value assigned" do
+ ($= = "xyz").should == "xyz"
+ end
+end