summaryrefslogtreecommitdiffhomepage
path: root/mrblib
diff options
context:
space:
mode:
authorHiroshi Mimaki <[email protected]>2019-10-18 14:46:03 +0900
committerHiroshi Mimaki <[email protected]>2019-10-18 14:46:03 +0900
commitb6546835457d1935a9c77965686b2a1256874d96 (patch)
tree724cfd71a7c956b0648e8c58f3717d797fff5f29 /mrblib
parent8ee516436b8d174a50764939bee23a442aa00b3f (diff)
parent20d01f118ddb7e7f2f36926a7a3db35573611857 (diff)
downloadmruby-b6546835457d1935a9c77965686b2a1256874d96.tar.gz
mruby-b6546835457d1935a9c77965686b2a1256874d96.zip
Merge master.
Diffstat (limited to 'mrblib')
-rw-r--r--mrblib/array.rb30
-rw-r--r--mrblib/enum.rb22
-rw-r--r--mrblib/hash.rb12
-rw-r--r--mrblib/kernel.rb2
-rw-r--r--mrblib/numeric.rb8
-rw-r--r--mrblib/range.rb2
-rw-r--r--mrblib/string.rb167
7 files changed, 93 insertions, 150 deletions
diff --git a/mrblib/array.rb b/mrblib/array.rb
index d598efc77..6535d6d83 100644
--- a/mrblib/array.rb
+++ b/mrblib/array.rb
@@ -10,16 +10,16 @@ class Array
# and pass the respective element.
#
# ISO 15.2.12.5.10
- def each(&block)
- return to_enum :each unless block
+ # def each(&block)
+ # return to_enum :each unless block
- idx = 0
- while idx < length
- block.call(self[idx])
- idx += 1
- end
- self
- end
+ # idx = 0
+ # while idx < length
+ # block.call(self[idx])
+ # idx += 1
+ # end
+ # self
+ # end
##
# Calls the given block for each element of +self+
@@ -83,13 +83,15 @@ class Array
self
end
- def _inspect
+ def _inspect(recur_list)
size = self.size
return "[]" if size == 0
+ return "[...]" if recur_list[self.object_id]
+ recur_list[self.object_id] = true
ary=[]
i=0
while i<size
- ary<<self[i].inspect
+ ary<<self[i]._inspect(recur_list)
i+=1
end
"["+ary.join(", ")+"]"
@@ -99,11 +101,7 @@ class Array
#
# ISO 15.2.12.5.31 (x)
def inspect
- begin
- self._inspect
- rescue SystemStackError
- "[...]"
- end
+ self._inspect({})
end
# ISO 15.2.12.5.32 (x)
alias to_s inspect
diff --git a/mrblib/enum.rb b/mrblib/enum.rb
index 9bd74e1c4..15687e159 100644
--- a/mrblib/enum.rb
+++ b/mrblib/enum.rb
@@ -65,22 +65,22 @@ module Enumerable
end
##
- # Call the given block for each element
- # which is yield by +each+. Return
- # +ifnone+ if no block value was true.
- # Otherwise return the first block value
- # which had was true.
+ # Return the first element for which
+ # value from the block is true. If no
+ # object matches, calls +ifnone+ and
+ # returns its result. Otherwise returns
+ # +nil+.
#
# ISO 15.3.2.2.4
def detect(ifnone=nil, &block)
- ret = ifnone
+ return to_enum :detect, ifnone unless block
+
self.each{|*val|
if block.call(*val)
- ret = val.__svalue
- break
+ return val.__svalue
end
}
- ret
+ ifnone.call unless ifnone.nil?
end
##
@@ -284,6 +284,8 @@ module Enumerable
#
# ISO 15.3.2.2.16
def partition(&block)
+ return to_enum :partition unless block
+
ary_T = []
ary_F = []
self.each{|*val|
@@ -304,6 +306,8 @@ module Enumerable
#
# ISO 15.3.2.2.17
def reject(&block)
+ return to_enum :reject unless block
+
ary = []
self.each{|*val|
ary.push(val.__svalue) unless block.call(*val)
diff --git a/mrblib/hash.rb b/mrblib/hash.rb
index 609883ecb..b49e987c7 100644
--- a/mrblib/hash.rb
+++ b/mrblib/hash.rb
@@ -186,15 +186,17 @@ class Hash
end
# internal method for Hash inspection
- def _inspect
+ def _inspect(recur_list)
return "{}" if self.size == 0
+ return "{...}" if recur_list[self.object_id]
+ recur_list[self.object_id] = true
ary=[]
keys=self.keys
size=keys.size
i=0
while i<size
k=keys[i]
- ary<<(k._inspect + "=>" + self[k]._inspect)
+ ary<<(k._inspect(recur_list) + "=>" + self[k]._inspect(recur_list))
i+=1
end
"{"+ary.join(", ")+"}"
@@ -204,11 +206,7 @@ class Hash
#
# ISO 15.2.13.4.30 (x)
def inspect
- begin
- self._inspect
- rescue SystemStackError
- "{...}"
- end
+ self._inspect({})
end
# ISO 15.2.13.4.31 (x)
alias to_s inspect
diff --git a/mrblib/kernel.rb b/mrblib/kernel.rb
index 4700684b6..7c3ea9420 100644
--- a/mrblib/kernel.rb
+++ b/mrblib/kernel.rb
@@ -40,7 +40,7 @@ module Kernel
end
# internal method for inspect
- def _inspect
+ def _inspect(_recur_list)
self.inspect
end
diff --git a/mrblib/numeric.rb b/mrblib/numeric.rb
index 5a3c5eb58..5926518d5 100644
--- a/mrblib/numeric.rb
+++ b/mrblib/numeric.rb
@@ -105,14 +105,14 @@ module Integral
return to_enum(:step, num, step) unless block
i = __coerce_step_counter(num, step)
- if num == nil
+ if num == self || step.infinite?
+ block.call(i) if step > 0 && i <= (num||i) || step < 0 && i >= (num||-i)
+ elsif num == nil
while true
block.call(i)
i += step
end
- return self
- end
- if step > 0
+ elsif step > 0
while i <= num
block.call(i)
i += step
diff --git a/mrblib/range.rb b/mrblib/range.rb
index 5bd2521e8..392cc2274 100644
--- a/mrblib/range.rb
+++ b/mrblib/range.rb
@@ -26,7 +26,7 @@ class Range
return self
end
- if val.kind_of?(String) && last.kind_of?(String) # fixnums are special
+ if val.kind_of?(String) && last.kind_of?(String) # strings are special
if val.respond_to? :upto
return val.upto(last, exclude_end?, &block)
else
diff --git a/mrblib/string.rb b/mrblib/string.rb
index 64e85c5b6..0e7c8dc12 100644
--- a/mrblib/string.rb
+++ b/mrblib/string.rb
@@ -3,24 +3,51 @@
#
# ISO 15.2.10
class String
+ # ISO 15.2.10.3
include Comparable
+
##
# Calls the given block for each line
# 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
@@ -103,18 +130,15 @@ class String
self.replace(str)
end
- ##
- # Calls the given block for each match of +pattern+
- # If no block is given return an array with all
- # matches of +pattern+.
- #
- # ISO 15.2.10.5.32
- def scan(reg, &block)
- ### *** TODO *** ###
- unless Object.const_defined?(:Regexp)
- raise NotImplementedError, "scan not available (yet)"
- end
- end
+# ##
+# # Calls the given block for each match of +pattern+
+# # If no block is given return an array with all
+# # matches of +pattern+.
+# #
+# # ISO 15.2.10.5.32
+# def scan(pattern, &block)
+# # TODO: String#scan is not implemented yet
+# end
##
# Replace only the first match of +pattern+ with
@@ -166,20 +190,9 @@ class String
end
##
- # Call the given block for each character of
- # +self+.
- def each_char(&block)
- pos = 0
- while pos < self.size
- block.call(self[pos])
- pos += 1
- end
- self
- end
-
- ##
# Call the given block for each byte of +self+.
def each_byte(&block)
+ return to_enum(:each_byte, &block) unless block
bytes = self.bytes
pos = 0
while pos < bytes.size
@@ -189,86 +202,16 @@ class String
self
end
- ##
- # 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
- case pos
- when 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(''))
- else
- raise IndexError, "string not matched"
- end
- when Range
- head = pos.begin
- tail = pos.end
- tail += self.length if tail < 0
- unless pos.exclude_end?
- tail += 1
- end
- return self[head, tail-head]=value
- 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(''))
- end
- return value
- 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
-
+ # those two methods requires Regexp that is optional in mruby
##
# ISO 15.2.10.5.3
- def =~(re)
- re =~ self
- end
+ #def =~(re)
+ # re =~ self
+ #end
##
# ISO 15.2.10.5.27
- def match(re, &block)
- if String === re
- if Object.const_defined?(:Regexp)
- r = Regexp.new(re)
- r.match(self, &block)
- else
- raise NotImplementedError, "String#match needs Regexp class"
- end
- else
- re.match(self, &block)
- end
- end
-end
-
-##
-# String is comparable
-#
-# ISO 15.2.10.3
-module Comparable; end
-class String
- include Comparable
+ #def match(re, &block)
+ # re.match(self, &block)
+ #end
end