From b05d736b49a6d3a99b7f75c74ffd9b6613c453d3 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 29 May 2015 17:01:44 +0900 Subject: update mrblib/*.rb files to conform (some of) Rubocop checks --- mrblib/string.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'mrblib/string.rb') diff --git a/mrblib/string.rb b/mrblib/string.rb index 1d9ea9e6a..90aad5d32 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -12,7 +12,7 @@ class String def each_line(&block) # expect that str.index accepts an Integer for 1st argument as a byte data offset = 0 - while(pos = self.index(0x0a, offset)) + while pos = self.index(0x0a, offset) block.call(self[offset, pos + 1 - offset]) offset = pos + 1 end @@ -106,7 +106,7 @@ class String # +self+. def each_char(&block) pos = 0 - while(pos < self.size) + while pos < self.size block.call(self[pos]) pos += 1 end @@ -118,7 +118,7 @@ class String def each_byte(&block) bytes = self.bytes pos = 0 - while(pos < bytes.size) + while pos < bytes.size block.call(bytes[pos]) pos += 1 end -- cgit v1.2.3 From 5dd2b8e16f33b84773cdebeec4b6a86a511e8e9c Mon Sep 17 00:00:00 2001 From: Tomoyuki Sahara Date: Mon, 8 Jun 2015 17:32:14 +0900 Subject: gsub/sub supports back references in substitutes. fixes #2816. This implementation is compatible with CRuby's String#gsub/sub except \1 ... \9 and \+. They are useless without Regexp library. --- mrblib/string.rb | 39 +++++++++++++++++++++++++++++++++++++-- test/t/string.rb | 18 ++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) (limited to 'mrblib/string.rb') diff --git a/mrblib/string.rb b/mrblib/string.rb index 90aad5d32..ee097ad6d 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -20,6 +20,30 @@ class String self end + # private method for gsub/sub + def __sub_replace(pre, m, post) + s = "" + i = 0 + while j = index("\\", i) + break if j == length-1 + t = case self[j+1] + when "\\" + "\\" + when "`" + pre + when "&", "0" + m + when "'" + post + else + self[j, 2] + end + s += self[i, j-i] + t + i = j + 2 + end + s + self[i, length-i] + end + ## # Replace all matches of +pattern+ with +replacement+. # Call block (if given) for each match and replace @@ -29,7 +53,17 @@ class String # ISO 15.2.10.5.18 def gsub(*args, &block) if args.size == 2 - split(args[0], -1).join(args[1]) + s = "" + i = 0 + while j = index(args[0], i) + seplen = args[0].length + k = j + seplen + pre = self[0, j] + post = self[k, length-k] + s += self[i, j-i] + args[1].__sub_replace(pre, args[0], post) + i = k + end + s + self[i, length-i] elsif args.size == 1 && block split(args[0], -1).join(block.call(args[0])) else @@ -76,7 +110,8 @@ class String # ISO 15.2.10.5.36 def sub(*args, &block) if args.size == 2 - split(args[0], 2).join(args[1]) + pre, post = split(args[0], 2) + pre + args[1].__sub_replace(pre, args[0], post) + post elsif args.size == 1 && block split(args[0], 2).join(block.call(args[0])) else diff --git a/test/t/string.rb b/test/t/string.rb index 63e4af000..ee6fe0848 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -254,6 +254,15 @@ assert('String#gsub', '15.2.10.5.18') do assert_equal('A', 'a'.gsub('a'){|w| w.capitalize }) end +assert('String#gsub with backslash') do + s = 'abXcdXef' + assert_equal 'ab<\\>cd<\\>ef', s.gsub('X', '<\\\\>') + assert_equal 'abcdef', s.gsub('X', '<\\&>') + assert_equal 'abcdef', s.gsub('X', '<\\0>') + assert_equal 'abcdef', s.gsub('X', '<\\`>') + assert_equal 'abcdef', s.gsub('X', '<\\\'>') +end + assert('String#gsub!', '15.2.10.5.19') do a = 'abcabc' a.gsub!('b', 'B') @@ -416,6 +425,15 @@ assert('String#sub', '15.2.10.5.36') do assert_equal 'aa$', 'aa#'.sub('#', '$') end +assert('String#sub with backslash') do + s = 'abXcdXef' + assert_equal 'ab<\\>cdXef', s.sub('X', '<\\\\>') + assert_equal 'abcdXef', s.sub('X', '<\\&>') + assert_equal 'abcdXef', s.sub('X', '<\\0>') + assert_equal 'abcdXef', s.sub('X', '<\\`>') + assert_equal 'abcdXef', s.sub('X', '<\\\'>') +end + assert('String#sub!', '15.2.10.5.37') do a = 'abcabc' a.sub!('b', 'B') -- cgit v1.2.3 From 08c12ab7bffaa1b96a3e4f9eee34e155eeec9310 Mon Sep 17 00:00:00 2001 From: Jared Breeden Date: Thu, 16 Jul 2015 15:33:07 -0700 Subject: Don't crash if pattern not found for sub --- mrblib/string.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'mrblib/string.rb') diff --git a/mrblib/string.rb b/mrblib/string.rb index ee097ad6d..23cf02e97 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -111,6 +111,7 @@ class String def sub(*args, &block) if args.size == 2 pre, post = split(args[0], 2) + return self unless post # The sub target wasn't found in the string pre + args[1].__sub_replace(pre, args[0], post) + post elsif args.size == 1 && block split(args[0], 2).join(block.call(args[0])) -- cgit v1.2.3 From 11524f6f678fde684941937413b6bc2cba23b630 Mon Sep 17 00:00:00 2001 From: "go.kikuta" Date: Thu, 20 Aug 2015 17:52:30 +0900 Subject: string.rb: refactor code (remove redundant code) --- mrblib/string.rb | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) (limited to 'mrblib/string.rb') diff --git a/mrblib/string.rb b/mrblib/string.rb index 23cf02e97..05b13cb43 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -80,12 +80,8 @@ class String # ISO 15.2.10.5.19 def gsub!(*args, &block) str = self.gsub(*args, &block) - if str != self - self.replace(str) - self - else - nil - end + return nil if str == self + self.replace(str) end ## @@ -129,12 +125,8 @@ class String # ISO 15.2.10.5.37 def sub!(*args, &block) str = self.sub(*args, &block) - if str != self - self.replace(str) - self - else - nil - end + return nil if str == self + self.replace(str) end ## @@ -165,20 +157,16 @@ class String # Modify +self+ by replacing the content of +self+ # at the position +pos+ with +value+. def []=(pos, value) - if pos < 0 - pos += self.length - end + pos += self.length if pos < 0 b = self[0, pos] - a = self[pos+1..-1] + a = self[pos + 1..-1] self.replace([b, value, a].join('')) end ## # ISO 15.2.10.5.3 def =~(re) - if re.respond_to? :to_str - raise TypeError, "type mismatch: String given" - end + raise TypeError, "type mismatch: String given" if re.respond_to? :to_str re =~ self end -- cgit v1.2.3 From f1c23a0f75a4a38c5077e1df30af200f3700752f Mon Sep 17 00:00:00 2001 From: takahashim Date: Wed, 16 Sep 2015 18:50:03 +0900 Subject: support String#[]= with 3 args --- mrblib/string.rb | 49 ++++++++++++++++++++++++++++++++++++------- test/t/string.rb | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 7 deletions(-) (limited to 'mrblib/string.rb') diff --git a/mrblib/string.rb b/mrblib/string.rb index 05b13cb43..5765cff9b 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -154,13 +154,48 @@ class String end ## - # Modify +self+ by replacing the content of +self+ - # at the position +pos+ with +value+. - def []=(pos, value) - pos += self.length if pos < 0 - b = self[0, pos] - a = self[pos + 1..-1] - self.replace([b, value, a].join('')) + # Modify +self+ by replacing the content of +self+. + # The portion of the string affected is determined using the same criteria as +String#[]+. + def []=(*args) + anum = args.size + if anum == 2 + pos, value = args + if pos.kind_of? String + posnum = self.index(pos) + if posnum + b = self[0, posnum.to_i] + a = self[(posnum + pos.length)..-1] + self.replace([b, value, a].join('')) + return value + else + raise IndexError, "string not matched" + end + else + pos += self.length if pos < 0 + if pos < 0 || pos > self.length + raise IndexError, "index #{args[0]} out of string" + end + b = self[0, pos.to_i] + a = self[pos + 1..-1] + self.replace([b, value, a].join('')) + return value + end + elsif anum == 3 + pos, len, value = args + pos += self.length if pos < 0 + if pos < 0 || pos > self.length + raise IndexError, "index #{args[0]} out of string" + end + if len < 0 + raise IndexError, "negative length #{len}" + end + b = self[0, pos.to_i] + a = self[pos + len..-1] + self.replace([b, value, a].join('')) + return value + else + raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)" + end end ## diff --git a/test/t/string.rb b/test/t/string.rb index 7326adce9..87aec0e21 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -122,6 +122,69 @@ assert('String#[] with Range') do assert_equal 'bc', j2 end +assert('String#[]=') do + # length of args is 1 + a = 'abc' + a[0] = 'X' + assert_equal 'Xbc', a + + b = 'abc' + b[-1] = 'X' + assert_equal 'abX', b + + c = 'abc' + assert_raise(IndexError) do + c[10] = 'X' + end + + d = 'abc' + assert_raise(IndexError) do + d[-10] = 'X' + end + + e = 'abc' + e[1.1] = 'X' + assert_equal 'aXc', e + + + # length of args is 2 + a1 = 'abc' + assert_raise(IndexError) do + a1[0, -1] = 'X' + end + + b1 = 'abc' + assert_raise(IndexError) do + b1[10, 0] = 'X' + end + + c1 = 'abc' + assert_raise(IndexError) do + c1[-10, 0] = 'X' + end + + d1 = 'abc' + d1[0, 0] = 'X' + assert_equal 'Xabc', d1 + + e1 = 'abc' + e1[1, 3] = 'X' + assert_equal 'aX', e1 + + # args is RegExp + # It will be tested in mrbgems. + + # args is String + a3 = 'abc' + a3['bc'] = 'X' + assert_equal a3, 'aX' + + b3 = 'abc' + assert_raise(IndexError) do + b3['XX'] = 'Y' + end +end + assert('String#capitalize', '15.2.10.5.7') do a = 'abc' a.capitalize -- cgit v1.2.3