summaryrefslogtreecommitdiffhomepage
path: root/mrblib
diff options
context:
space:
mode:
Diffstat (limited to 'mrblib')
-rw-r--r--mrblib/array.rb35
-rw-r--r--mrblib/enum.rb37
-rw-r--r--mrblib/error.rb15
-rw-r--r--mrblib/hash.rb27
-rw-r--r--mrblib/kernel.rb2
-rw-r--r--mrblib/numeric.rb40
-rw-r--r--mrblib/range.rb14
-rw-r--r--mrblib/string.rb115
8 files changed, 166 insertions, 119 deletions
diff --git a/mrblib/array.rb b/mrblib/array.rb
index bd8d5930f..65dd0d665 100644
--- a/mrblib/array.rb
+++ b/mrblib/array.rb
@@ -16,7 +16,7 @@ class Array
while idx < length and length <= self.length and length = self.length-1
elm = self[idx += 1]
unless elm
- if elm == nil and length >= self.length
+ if elm.nil? and length >= self.length
break
end
end
@@ -34,7 +34,7 @@ class Array
return to_enum :each_index unless block_given?
idx = 0
- while(idx < length)
+ while idx < length
block.call(idx)
idx += 1
end
@@ -50,9 +50,7 @@ class Array
def collect!(&block)
return to_enum :collect! unless block_given?
- self.each_index{|idx|
- self[idx] = block.call(self[idx])
- }
+ self.each_index { |idx| self[idx] = block.call(self[idx]) }
self
end
@@ -72,10 +70,10 @@ class Array
self.clear
if size > 0
- self[size - 1] = nil # allocate
+ self[size - 1] = nil # allocate
idx = 0
- while(idx < size)
+ while idx < size
self[idx] = (block)? block.call(idx): obj
idx += 1
end
@@ -146,7 +144,7 @@ class Array
# equal, then that inequality is the return value. If all the
# values found are equal, then the return is based on a
# comparison of the array lengths. Thus, two arrays are
- # ``equal'' according to <code>Array#<=></code> if and only if they have
+ # "equal" according to <code>Array#<=></code> if and only if they have
# the same length and the value of each element is equal to the
# value of the corresponding element in the other array.
#
@@ -158,14 +156,11 @@ class Array
len = self.size
n = other.size
- if len > n
- len = n
- end
+ len = n if len > n
i = 0
while i < len
n = (self[i] <=> other[i])
- return n if n == nil
- return n if n != 0
+ return n if n.nil? || n != 0
i += 1
end
len = self.size - other.size
@@ -185,20 +180,14 @@ class Array
self.delete_at(i)
ret = key
end
- if ret == nil && block
- block.call
- else
- ret
- end
+ return block.call if ret.nil? && block
+ ret
end
# internal method to convert multi-value to single value
def __svalue
- if self.size < 2
- self.first
- else
- self
- end
+ return self.first if self.size < 2
+ self
end
end
diff --git a/mrblib/enum.rb b/mrblib/enum.rb
index 6bf219283..f0c9a4884 100644
--- a/mrblib/enum.rb
+++ b/mrblib/enum.rb
@@ -24,17 +24,9 @@ module Enumerable
# ISO 15.3.2.2.1
def all?(&block)
if block
- self.each{|*val|
- unless block.call(*val)
- return false
- end
- }
+ self.each{|*val| return false unless block.call(*val)}
else
- self.each{|*val|
- unless val.__svalue
- return false
- end
- }
+ self.each{|*val| return false unless val.__svalue}
end
true
end
@@ -49,17 +41,9 @@ module Enumerable
# ISO 15.3.2.2.2
def any?(&block)
if block
- self.each{|*val|
- if block.call(*val)
- return true
- end
- }
+ self.each{|*val| return true if block.call(*val)}
else
- self.each{|*val|
- if val.__svalue
- return true
- end
- }
+ self.each{|*val| return true if val.__svalue}
end
false
end
@@ -75,9 +59,7 @@ module Enumerable
return to_enum :collect unless block
ary = []
- self.each{|*val|
- ary.push(block.call(*val))
- }
+ self.each{|*val| ary.push(block.call(*val))}
ary
end
@@ -183,9 +165,7 @@ module Enumerable
# ISO 15.3.2.2.10
def include?(obj)
self.each{|*val|
- if val.__svalue == obj
- return true
- end
+ return true if val.__svalue == obj
}
false
end
@@ -402,8 +382,11 @@ module Enumerable
# redefine #hash 15.3.1.3.15
def hash
h = 12347
+ i = 0
self.each do |e|
- h ^= e.hash
+ n = e.hash << (i % 16)
+ h ^= n
+ i += 1
end
h
end
diff --git a/mrblib/error.rb b/mrblib/error.rb
index d76dd9c56..2674af7a2 100644
--- a/mrblib/error.rb
+++ b/mrblib/error.rb
@@ -1,18 +1,3 @@
-##
-# Exception
-#
-# ISO 15.2.22
-class Exception
-
- ##
- # Raise an exception.
- #
- # ISO 15.2.22.4.1
- def self.exception(*args, &block)
- self.new(*args, &block)
- end
-end
-
# ISO 15.2.24
class ArgumentError < StandardError
end
diff --git a/mrblib/hash.rb b/mrblib/hash.rb
index e7c51fb1f..48ac96e56 100644
--- a/mrblib/hash.rb
+++ b/mrblib/hash.rb
@@ -10,7 +10,7 @@ class Hash
# hash.
#
# ISO 15.2.13.4.1
- def == (hash)
+ def ==(hash)
return true if self.equal?(hash)
begin
hash = hash.to_hash
@@ -54,7 +54,7 @@ class Hash
#
# ISO 15.2.13.4.8
def delete(key, &block)
- if block && ! self.has_key?(key)
+ if block && !self.has_key?(key)
block.call(key)
else
self.__delete(key)
@@ -319,6 +319,29 @@ class Hash
h
end
+ ##
+ # call-seq:
+ # hsh.rehash -> hsh
+ #
+ # Rebuilds the hash based on the current hash values for each key. If
+ # values of key objects have changed since they were inserted, this
+ # method will reindex <i>hsh</i>.
+ #
+ # h = {"AAA" => "b"}
+ # h.keys[0].chop!
+ # h #=> {"AA"=>"b"}
+ # h["AA"] #=> nil
+ # h.rehash #=> {"AA"=>"b"}
+ # h["AA"] #=> "b"
+ #
+ def rehash
+ h = {}
+ self.each{|k,v|
+ h[k] = v
+ }
+ self.replace(h)
+ end
+
def __update(h)
h.each_key{|k| self[k] = h[k]}
self
diff --git a/mrblib/kernel.rb b/mrblib/kernel.rb
index 8c9b122f2..38af3b310 100644
--- a/mrblib/kernel.rb
+++ b/mrblib/kernel.rb
@@ -27,7 +27,7 @@ module Kernel
def loop(&block)
return to_enum :loop unless block
- while(true)
+ while true
yield
end
rescue StopIteration
diff --git a/mrblib/numeric.rb b/mrblib/numeric.rb
index 1f44a2c81..6e4c5027f 100644
--- a/mrblib/numeric.rb
+++ b/mrblib/numeric.rb
@@ -48,7 +48,7 @@ module Integral
return to_enum(:downto, num) unless block_given?
i = self.to_i
- while(i >= num)
+ while i >= num
block.call(i)
i -= 1
end
@@ -89,7 +89,7 @@ module Integral
return to_enum(:upto, num) unless block_given?
i = self.to_i
- while(i <= num)
+ while i <= num
block.call(i)
i += 1
end
@@ -100,18 +100,18 @@ module Integral
# Calls the given block from +self+ to +num+
# incremented by +step+ (default 1).
#
- def step(num, step=1, &block)
+ def step(num, step = 1, &block)
raise ArgumentError, "step can't be 0" if step == 0
return to_enum(:step, num, step) unless block_given?
i = if num.kind_of? Float then self.to_f else self end
if step > 0
- while(i <= num)
+ while i <= num
block.call(i)
i += step
end
else
- while(i >= num)
+ while i >= num
block.call(i)
i += step
end
@@ -165,16 +165,30 @@ class Float
# floats should be compatible to integers.
def >> other
n = self.to_i
- other.to_i.times {
- n /= 2
- }
- n
+ other = other.to_i
+ if other < 0
+ n << -other
+ else
+ other.times { n /= 2 }
+ if n.abs < 1
+ if n >= 0
+ 0
+ else
+ -1
+ end
+ else
+ n.to_i
+ end
+ end
end
def << other
n = self.to_i
- other.to_i.times {
- n *= 2
- }
- n.to_i
+ other = other.to_i
+ if other < 0
+ n >> -other
+ else
+ other.times { n *= 2 }
+ n
+ end
end
end
diff --git a/mrblib/range.rb b/mrblib/range.rb
index 1ec9ac508..5e5fd9bdc 100644
--- a/mrblib/range.rb
+++ b/mrblib/range.rb
@@ -26,29 +26,23 @@ class Range
return self
end
- unless val.respond_to? :succ
- raise TypeError, "can't iterate"
- end
+ raise TypeError, "can't iterate" unless val.respond_to? :succ
return self if (val <=> last) > 0
- while((val <=> last) < 0)
+ while (val <=> last) < 0
block.call(val)
val = val.succ
end
- if not exclude_end? and (val <=> last) == 0
- block.call(val)
- end
+ block.call(val) if !exclude_end? && (val <=> last) == 0
self
end
# redefine #hash 15.3.1.3.15
def hash
h = first.hash ^ last.hash
- if self.exclude_end?
- h += 1
- end
+ h += 1 if self.exclude_end?
h
end
end
diff --git a/mrblib/string.rb b/mrblib/string.rb
index 1d9ea9e6a..5765cff9b 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
@@ -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
@@ -46,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
##
@@ -76,7 +106,9 @@ 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)
+ 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]))
else
@@ -93,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
##
@@ -106,7 +134,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 +146,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
@@ -126,23 +154,54 @@ class String
end
##
- # Modify +self+ by replacing the content of +self+
- # at the position +pos+ with +value+.
- def []=(pos, value)
- if pos < 0
- pos += self.length
+ # 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
- b = self[0, pos]
- 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