1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Warn non-nil $/ [Feature #14240]

This commit is contained in:
Nobuyoshi Nakada 2020-01-21 08:37:44 +09:00
parent 6298ec2875
commit 8a7e0aaaef
No known key found for this signature in database
GPG key ID: 4BC7D6DF58D8DF60
Notes: git 2020-02-23 16:49:04 +09:00
18 changed files with 75 additions and 29 deletions

4
io.c
View file

@ -13288,8 +13288,8 @@ Init_IO(void)
rb_gc_register_mark_object(rb_default_rs); rb_gc_register_mark_object(rb_default_rs);
rb_rs = rb_default_rs; rb_rs = rb_default_rs;
rb_output_rs = Qnil; rb_output_rs = Qnil;
rb_define_hooked_variable("$/", &rb_rs, 0, rb_str_setter); rb_define_hooked_variable("$/", &rb_rs, 0, deprecated_str_setter);
rb_define_hooked_variable("$-0", &rb_rs, 0, rb_str_setter); rb_define_hooked_variable("$-0", &rb_rs, 0, deprecated_str_setter);
rb_define_hooked_variable("$\\", &rb_output_rs, 0, deprecated_str_setter); rb_define_hooked_variable("$\\", &rb_output_rs, 0, deprecated_str_setter);
rb_define_virtual_variable("$_", get_LAST_READ_LINE, set_LAST_READ_LINE); rb_define_virtual_variable("$_", get_LAST_READ_LINE, set_LAST_READ_LINE);

View file

@ -16,7 +16,7 @@ describe "IO#puts" do
ScratchPad.clear ScratchPad.clear
@io.close if @io @io.close if @io
rm_r @name rm_r @name
$/ = @before_separator suppress_warning {$/ = @before_separator}
end end
it "writes just a newline when given no args" do it "writes just a newline when given no args" do
@ -105,7 +105,7 @@ describe "IO#puts" do
end end
it "ignores the $/ separator global" do it "ignores the $/ separator global" do
$/ = ":" suppress_warning {$/ = ":"}
@io.puts(5).should == nil @io.puts(5).should == nil
ScratchPad.recorded.should == "5\n" ScratchPad.recorded.should == "5\n"
end end

View file

@ -22,11 +22,11 @@ describe "IO#readlines" do
describe "when passed no arguments" do describe "when passed no arguments" do
before :each do before :each do
@sep, $/ = $/, " " suppress_warning {@sep, $/ = $/, " "}
end end
after :each do after :each do
$/ = @sep suppress_warning {$/ = @sep}
end end
it "returns an Array containing lines based on $/" do it "returns an Array containing lines based on $/" do
@ -184,7 +184,7 @@ describe "IO.readlines" do
after :each do after :each do
Encoding.default_external = @external Encoding.default_external = @external
Encoding.default_internal = @internal Encoding.default_internal = @internal
$/ = @dollar_slash suppress_warning {$/ = @dollar_slash}
end end
it "encodes lines using the default external encoding" do it "encodes lines using the default external encoding" do
@ -196,7 +196,7 @@ describe "IO.readlines" do
it "encodes lines using the default internal encoding, when set" do it "encodes lines using the default internal encoding, when set" do
Encoding.default_external = Encoding::UTF_8 Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_16 Encoding.default_internal = Encoding::UTF_16
$/ = $/.encode Encoding::UTF_16 suppress_warning {$/ = $/.encode Encoding::UTF_16}
lines = IO.readlines(@name) lines = IO.readlines(@name)
lines.all? { |s| s.encoding == Encoding::UTF_16 }.should be_true lines.all? { |s| s.encoding == Encoding::UTF_16 }.should be_true
end end

View file

@ -168,12 +168,12 @@ describe :io_each_default_separator, shared: true do
before :each do before :each do
@io = IOSpecs.io_fixture "lines.txt" @io = IOSpecs.io_fixture "lines.txt"
ScratchPad.record [] ScratchPad.record []
@sep, $/ = $/, " " suppress_warning {@sep, $/ = $/, " "}
end end
after :each do after :each do
@io.close if @io @io.close if @io
$/ = @sep suppress_warning {$/ = @sep}
end end
it "uses $/ as the default line separator" do it "uses $/ as the default line separator" do

View file

@ -60,11 +60,11 @@ describe :io_readlines_options_19, shared: true do
end end
after :each do after :each do
$/ = @sep suppress_warning {$/ = @sep}
end end
it "defaults to $/ as the separator" do it "defaults to $/ as the separator" do
$/ = " " suppress_warning {$/ = " "}
result = IO.send(@method, @name, 10, &@object) result = IO.send(@method, @name, 10, &@object)
(result ? result : ScratchPad.recorded).should == IOSpecs.lines_space_separator_limit (result ? result : ScratchPad.recorded).should == IOSpecs.lines_space_separator_limit
end end

View file

@ -49,7 +49,7 @@ module KernelSpecs
def self.chomp(str, method, sep="\n") def self.chomp(str, method, sep="\n")
code = "$_ = #{str.inspect}; $/ = #{sep.inspect}; #{method}; print $_" code = "$_ = #{str.inspect}; $/ = #{sep.inspect}; #{method}; print $_"
IO.popen([*ruby_exe, "-n", "-e", code], "r+") do |io| IO.popen([*ruby_exe, "-W0", "-n", "-e", code], "r+") do |io|
io.puts io.puts
io.close_write io.close_write
io.read io.read

View file

@ -8,8 +8,9 @@ describe "Kernel#warn" do
end end
after :each do after :each do
$VERBOSE = @before_verbose $VERBOSE = nil
$/ = @before_separator $/ = @before_separator
$VERBOSE = @before_verbose
end end
it "is a private method" do it "is a private method" do

View file

@ -6,11 +6,13 @@ describe "String#chomp" do
describe "when passed no argument" do describe "when passed no argument" do
before do before do
# Ensure that $/ is set to the default value # Ensure that $/ is set to the default value
@verbose, $VERBOSE = $VERBOSE, nil
@dollar_slash, $/ = $/, "\n" @dollar_slash, $/ = $/, "\n"
end end
after do after do
$/ = @dollar_slash $/ = @dollar_slash
$VERBOSE = @verbose
end end
it "does not modify a String with no trailing carriage return or newline" do it "does not modify a String with no trailing carriage return or newline" do
@ -179,11 +181,13 @@ describe "String#chomp!" do
describe "when passed no argument" do describe "when passed no argument" do
before do before do
# Ensure that $/ is set to the default value # Ensure that $/ is set to the default value
@verbose, $VERBOSE = $VERBOSE, nil
@dollar_slash, $/ = $/, "\n" @dollar_slash, $/ = $/, "\n"
end end
after do after do
$/ = @dollar_slash $/ = @dollar_slash
$VERBOSE = @verbose
end end
it "modifies self" do it "modifies self" do
@ -350,11 +354,13 @@ end
describe "String#chomp" do describe "String#chomp" do
before :each do before :each do
@verbose, $VERBOSE = $VERBOSE, nil
@before_separator = $/ @before_separator = $/
end end
after :each do after :each do
$/ = @before_separator $/ = @before_separator
$VERBOSE = @verbose
end end
it "does not modify a multi-byte character" do it "does not modify a multi-byte character" do
@ -379,11 +385,13 @@ end
describe "String#chomp!" do describe "String#chomp!" do
before :each do before :each do
@verbose, $VERBOSE = $VERBOSE, nil
@before_separator = $/ @before_separator = $/
end end
after :each do after :each do
$/ = @before_separator $/ = @before_separator
$VERBOSE = @verbose
end end
it "returns nil when the String is not modified" do it "returns nil when the String is not modified" do

View file

@ -84,7 +84,7 @@ describe :string_each_line, shared: true do
end end
after :each do after :each do
$/ = @before_separator suppress_warning {$/ = @before_separator}
end end
it "as the separator when none is given" do it "as the separator when none is given" do
@ -96,10 +96,10 @@ describe :string_each_line, shared: true do
expected = [] expected = []
str.send(@method, sep) { |x| expected << x } str.send(@method, sep) { |x| expected << x }
$/ = sep suppress_warning {$/ = sep}
actual = [] actual = []
str.send(@method) { |x| actual << x } suppress_warning {str.send(@method) { |x| actual << x }}
actual.should == expected actual.should == expected
end end

View file

@ -541,6 +541,7 @@ $stdout IO The current standard output. Assignment to $std
describe "Predefined global $/" do describe "Predefined global $/" do
before :each do before :each do
@verbose, $VERBOSE = $VERBOSE, nil
@dollar_slash = $/ @dollar_slash = $/
@dollar_dash_zero = $-0 @dollar_dash_zero = $-0
end end
@ -548,6 +549,7 @@ describe "Predefined global $/" do
after :each do after :each do
$/ = @dollar_slash $/ = @dollar_slash
$-0 = @dollar_dash_zero $-0 = @dollar_dash_zero
$VERBOSE = @verbose
end end
it "can be assigned a String" do it "can be assigned a String" do
@ -589,6 +591,7 @@ end
describe "Predefined global $-0" do describe "Predefined global $-0" do
before :each do before :each do
@verbose, $VERBOSE = $VERBOSE, nil
@dollar_slash = $/ @dollar_slash = $/
@dollar_dash_zero = $-0 @dollar_dash_zero = $-0
end end
@ -596,6 +599,7 @@ describe "Predefined global $-0" do
after :each do after :each do
$/ = @dollar_slash $/ = @dollar_slash
$-0 = @dollar_dash_zero $-0 = @dollar_dash_zero
$VERBOSE = @verbose
end end
it "can be assigned a String" do it "can be assigned a String" do

View file

@ -76,12 +76,13 @@ describe "StringIO#gets when passed no argument" do
@io.gets.should == "this is\n" @io.gets.should == "this is\n"
begin begin
old_sep, $/ = $/, " " old_sep = $/
suppress_warning {$/ = " "}
@io.gets.should == "an " @io.gets.should == "an "
@io.gets.should == "example\nfor " @io.gets.should == "example\nfor "
@io.gets.should == "StringIO#gets" @io.gets.should == "StringIO#gets"
ensure ensure
$/ = old_sep suppress_warning {$/ = old_sep}
end end
end end

View file

@ -64,12 +64,13 @@ describe "StringIO#readline when passed no argument" do
@io.readline.should == "this is\n" @io.readline.should == "this is\n"
begin begin
old_sep, $/ = $/, " " old_sep = $/
suppress_warning {$/ = " "}
@io.readline.should == "an " @io.readline.should == "an "
@io.readline.should == "example\nfor " @io.readline.should == "example\nfor "
@io.readline.should == "StringIO#readline" @io.readline.should == "StringIO#readline"
ensure ensure
$/ = old_sep suppress_warning {$/ = old_sep}
end end
end end

View file

@ -51,10 +51,11 @@ describe "StringIO#readlines when passed no argument" do
it "returns an Array containing lines based on $/" do it "returns an Array containing lines based on $/" do
begin begin
old_sep, $/ = $/, " " old_sep = $/;
suppress_warning {$/ = " "}
@io.readlines.should == ["this ", "is\nan ", "example\nfor ", "StringIO#readlines"] @io.readlines.should == ["this ", "is\nan ", "example\nfor ", "StringIO#readlines"]
ensure ensure
$/ = old_sep suppress_warning {$/ = old_sep}
end end
end end

View file

@ -71,11 +71,12 @@ describe :stringio_each_no_arguments, shared: true do
it "uses $/ as the default line separator" do it "uses $/ as the default line separator" do
seen = [] seen = []
begin begin
old_rs, $/ = $/, " " old_rs = $/
suppress_warning {$/ = " "}
@io.send(@method) {|s| seen << s } @io.send(@method) {|s| seen << s }
seen.should eql(["a ", "b ", "c ", "d ", "e\n1 ", "2 ", "3 ", "4 ", "5"]) seen.should eql(["a ", "b ", "c ", "d ", "e\n1 ", "2 ", "3 ", "4 ", "5"])
ensure ensure
$/ = old_rs suppress_warning {$/ = old_rs}
end end
end end

View file

@ -59,7 +59,7 @@ describe "CApiGlobalSpecs" do
end end
after :each do after :each do
$/ = @dollar_slash suppress_warning {$/ = @dollar_slash}
end end
it "returns \\n by default" do it "returns \\n by default" do
@ -67,7 +67,7 @@ describe "CApiGlobalSpecs" do
end end
it "returns the value of $/" do it "returns the value of $/" do
$/ = "foo" suppress_warning {$/ = "foo"}
@f.rb_rs.should == "foo" @f.rb_rs.should == "foo"
end end
end end

View file

@ -8245,6 +8245,21 @@ chomp_newline(const char *p, const char *e, rb_encoding *enc)
return e; return e;
} }
static VALUE
get_rs(void)
{
VALUE rs = rb_rs;
if (!NIL_P(rs) &&
(!RB_TYPE_P(rs, T_STRING) ||
RSTRING_LEN(rs) != 1 ||
RSTRING_PTR(rs)[0] != '\n')) {
rb_warn("$/ is set to non-default value");
}
return rs;
}
#define rb_rs get_rs()
static VALUE static VALUE
rb_str_enumerate_lines(int argc, VALUE *argv, VALUE str, VALUE ary) rb_str_enumerate_lines(int argc, VALUE *argv, VALUE str, VALUE ary)
{ {

View file

@ -160,10 +160,10 @@ module OpenSSL::TestPairM
ssl_pair {|s1, s2| ssl_pair {|s1, s2|
begin begin
old = $/ old = $/
$/ = '*' EnvUtil.suppress_warning {$/ = '*'}
s1.puts 'a' s1.puts 'a'
ensure ensure
$/ = old EnvUtil.suppress_warning {$/ = old}
end end
s1.close s1.close
assert_equal("a\n", s2.read) assert_equal("a\n", s2.read)

View file

@ -387,6 +387,8 @@ CODE
end end
def test_chomp def test_chomp
verbose, $VERBOSE = $VERBOSE, nil
assert_equal(S("hello"), S("hello").chomp("\n")) assert_equal(S("hello"), S("hello").chomp("\n"))
assert_equal(S("hello"), S("hello\n").chomp("\n")) assert_equal(S("hello"), S("hello\n").chomp("\n"))
save = $/ save = $/
@ -452,9 +454,12 @@ CODE
assert_equal("foo", s.chomp("\n")) assert_equal("foo", s.chomp("\n"))
ensure ensure
$/ = save $/ = save
$VERBOSE = verbose
end end
def test_chomp! def test_chomp!
verbose, $VERBOSE = $VERBOSE, nil
a = S("hello") a = S("hello")
a.chomp!(S("\n")) a.chomp!(S("\n"))
@ -511,6 +516,7 @@ CODE
s = S("").freeze s = S("").freeze
assert_raise_with_message(FrozenError, /frozen/) {s.chomp!} assert_raise_with_message(FrozenError, /frozen/) {s.chomp!}
$VERBOSE = nil # EnvUtil.suppress_warning resets $VERBOSE to the original state
s = S("ax") s = S("ax")
o = Struct.new(:s).new(s) o = Struct.new(:s).new(s)
@ -519,6 +525,7 @@ CODE
"x" "x"
end end
assert_raise_with_message(FrozenError, /frozen/) {s.chomp!(o)} assert_raise_with_message(FrozenError, /frozen/) {s.chomp!(o)}
$VERBOSE = nil # EnvUtil.suppress_warning resets $VERBOSE to the original state
s = S("hello") s = S("hello")
assert_equal("hel", s.chomp!('lo')) assert_equal("hel", s.chomp!('lo'))
@ -569,6 +576,7 @@ CODE
assert_equal("foo", s.chomp!("\n")) assert_equal("foo", s.chomp!("\n"))
ensure ensure
$/ = save $/ = save
$VERBOSE = verbose
end end
def test_chop def test_chop
@ -859,6 +867,8 @@ CODE
end end
def test_each def test_each
verbose, $VERBOSE = $VERBOSE, nil
save = $/ save = $/
$/ = "\n" $/ = "\n"
res=[] res=[]
@ -878,6 +888,7 @@ CODE
assert_equal(S("world"), res[1]) assert_equal(S("world"), res[1])
ensure ensure
$/ = save $/ = save
$VERBOSE = verbose
end end
def test_each_byte def test_each_byte
@ -1055,6 +1066,8 @@ CODE
end end
def test_each_line def test_each_line
verbose, $VERBOSE = $VERBOSE, nil
save = $/ save = $/
$/ = "\n" $/ = "\n"
res=[] res=[]
@ -1101,6 +1114,7 @@ CODE
end end
ensure ensure
$/ = save $/ = save
$VERBOSE = verbose
end end
def test_each_line_chomp def test_each_line_chomp