summaryrefslogtreecommitdiffhomepage
path: root/mrblib
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2019-09-12 21:19:42 +0900
committerGitHub <[email protected]>2019-09-12 21:19:42 +0900
commit6bbdb97e7533d1fcf2bc5a2a20b42d1c0e5a9bf3 (patch)
tree81adc816a29f9e096ee9bc702a959d37694f4e81 /mrblib
parentb98bf36a15705d760a25a01ac844768bd691e731 (diff)
parent46c972f746f37a26104b1e9f317ce5a02daa9f40 (diff)
downloadmruby-6bbdb97e7533d1fcf2bc5a2a20b42d1c0e5a9bf3.tar.gz
mruby-6bbdb97e7533d1fcf2bc5a2a20b42d1c0e5a9bf3.zip
Merge pull request #4527 from lopopolo/string-each-line-paragraph-mode
Add paragraph mode to String#each_line in mrblib
Diffstat (limited to 'mrblib')
-rw-r--r--mrblib/string.rb47
1 files changed, 36 insertions, 11 deletions
diff --git a/mrblib/string.rb b/mrblib/string.rb
index c26cdb1e2..0e7c8dc12 100644
--- a/mrblib/string.rb
+++ b/mrblib/string.rb
@@ -11,18 +11,43 @@ class String
# and pass the respective line.
#
# ISO 15.2.10.5.15
- def each_line(rs = "\n", &block)
- return to_enum(:each_line, rs, &block) unless block
- return block.call(self) if rs.nil?
- rs.__to_str
- offset = 0
- rs_len = rs.length
- this = dup
- while pos = this.index(rs, offset)
- block.call(this[offset, pos + rs_len - offset])
- offset = pos + rs_len
+ def each_line(separator = "\n", &block)
+ return to_enum(:each_line, separator) unless block
+
+ if separator.nil?
+ block.call(self)
+ return self
+ end
+ raise TypeError unless separator.is_a?(String)
+
+ paragraph_mode = false
+ if separator.empty?
+ paragraph_mode = true
+ separator = "\n\n"
+ end
+ start = 0
+ string = dup
+ self_len = length
+ sep_len = separator.length
+ should_yield_subclass_instances = self.class != String
+
+ while (pointer = string.index(separator, start))
+ pointer += sep_len
+ pointer += 1 while paragraph_mode && string[pointer] == "\n"
+ if should_yield_subclass_instances
+ block.call(self.class.new(string[start, pointer - start]))
+ else
+ block.call(string[start, pointer - start])
+ end
+ start = pointer
+ end
+ return self if start == self_len
+
+ if should_yield_subclass_instances
+ block.call(self.class.new(string[start, self_len - start]))
+ else
+ block.call(string[start, self_len - start])
end
- block.call(this[offset, this.size - offset]) if this.size > offset
self
end