Callback should yield with pattern every time
MODIFY
mrblib/string.rb
mrblib/string.rb
@@ -59,16 +59,26 @@ class String
# ISO 15.2.10.5.18
def gsub(*args, &block)
return to_enum(:gsub, *args) if args.length == 1 && !block
- if args.size == 2
+ raise ArgumentError, "wrong number of arguments" unless (1..2).include?(args.length)
+
pattern, replace = *args
plen = pattern.length
+ if args.length == 2 && block
+ block = nil
+ end
+ if !replace.nil? || !block
replace = replace.to_str
+ end
offset = 0
result = []
while found = index(pattern, offset)
result << self[offset, found - offset]
offset = found + plen
- result << replace.__sub_replace(self[0, found], pattern, self[offset..-1] || "")
+ result << if block
+ block.call(pattern).to_s
+ else
+ replace.__sub_replace(self[0, found], pattern, self[offset..-1] || "")
+ end
if plen == 0
result << self[offset, 1]
offset += 1
@@ -76,11 +86,6 @@ class String
end
result << self[offset..-1] if offset < length
result.join
- elsif args.size == 1 && block
- split(args[0], -1).join(block.call(args[0]))
- else
- raise ArgumentError, "wrong number of arguments"
- end
end
##

MODIFY
test/t/string.rb
test/t/string.rb
@@ -373,6 +373,11 @@ assert('String#gsub', '15.2.10.5.18') do
assert_equal('A', 'a'.gsub('a'){|w| w.capitalize })
assert_equal("<a><><>", 'a'.gsub('a', '<\0><\1><\2>'))
assert_equal(".h.e.l.l.o.", "hello".gsub("", "."))
+ a = []
+ assert_equal(".h.e.l.l.o.", "hello".gsub("") { |i| a << i; "." })
+ assert_equal(["", "", "", "", "", ""], a)
+ assert_raise(ArgumentError) { "".gsub }
+ assert_raise(ArgumentError) { "".gsub("", "", "") }
end
assert('String#gsub with backslash') do

Callback should yield with pattern every time