corelib/string.rb in opal-0.4.4 vs corelib/string.rb in opal-0.5.0

- old
+ new

@@ -9,17 +9,15 @@ rescue nil end def self.new(str = '') - %x{ - return new native_string(str) - } + `new native_string(str)` end def %(data) - if data.is_a?(Array) + if Array === data format(self, *data) else format(self, data) end end @@ -29,73 +27,72 @@ if (count < 1) { return ''; } var result = '', - pattern = #{self}.valueOf(); + pattern = self; while (count > 0) { if (count & 1) { result += pattern; } - count >>= 1, pattern += pattern; + count >>= 1; + pattern += pattern; } return result; } end def +(other) - `#{self}.toString() + other` + %x{ + if (other._isString) { + return self + other; + } + } + + unless other.respond_to? :to_str + raise TypeError, "no implicit conversion of #{other.class.name} into String" + end + + `self + #{other.to_str}` end def <=>(other) %x{ - if (typeof other !== 'string') { - return nil; + if (other._isString) { + return self > other ? 1 : (self < other ? -1 : 0); } - - return #{self} > other ? 1 : (#{self} < other ? -1 : 0); } - end - def <(other) - `#{self} < other` - end + if other.respond_to? :to_str + other = other.to_str - def <=(other) - `#{self} <= other` + `self > other ? 1 : (self < other ? -1 : 0)` + end end - def >(other) - `#{self} > other` - end - - def >=(other) - `#{self} >= other` - end - def ==(other) - `other == native_string(#{self})` + `!!(other._isString && self.valueOf() === other.valueOf())` end alias === == def =~(other) %x{ - if (typeof other === 'string') { - #{ raise 'string given' }; + if (other._isString) { + #{raise TypeError, 'type mismatch: String given'}; } return #{other =~ self}; } end def [](index, length = undefined) %x{ - var size = #{self}.length; + var size = self.length; if (index._isRange) { var exclude = index.exclude, length = index.end, index = index.begin; @@ -120,190 +117,181 @@ if (length < 0) { length = 0; } - return #{self}.substr(index, length); + return self.substr(index, length); } if (index < 0) { - index += #{self}.length; + index += self.length; } if (length == null) { - if (index >= #{self}.length || index < 0) { + if (index >= self.length || index < 0) { return nil; } - return #{self}.substr(index, 1); + return self.substr(index, 1); } - if (index > #{self}.length || index < 0) { + if (index > self.length || index < 0) { return nil; } - return #{self}.substr(index, length); + return self.substr(index, length); } end def capitalize - `#{self}.charAt(0).toUpperCase() + #{self}.substr(1).toLowerCase()` + `self.charAt(0).toUpperCase() + self.substr(1).toLowerCase()` end def casecmp(other) %x{ - if (typeof other !== 'string') { - return other; + if (other._isString) { + return #{`self.toLowerCase()` <=> `other.toLowerCase()`}; } + } - var a = #{self}.toLowerCase(), - b = other.toLowerCase(); + unless other.respond_to? :to_str + raise TypeError, "no implicit conversion of #{other.class.name} into String" + end - return a > b ? 1 : (a < b ? -1 : 0); - } + `self.toLowerCase()` <=> `#{other.to_str}.toLowerCase()` end def center(width, padstr = ' ') + return self if `width === self.length` + %x{ - if (width <= #{self}.length) { - return #{self}; - } - else { - var ljustified = #{self.ljust( ((width + self.size)/2).floor, padstr)}; - var rjustified = #{self.rjust( ((width + self.size)/2).ceil, padstr)}; - return ljustified + rjustified.slice(#{self}.length); - } + var ljustified = #{ljust ((width + @length) / 2).floor, padstr}, + rjustified = #{rjust ((width + @length) / 2).ceil, padstr}; + + return ljustified + rjustified.slice(self.length); } end def chars - %x{ - for (var i = 0, length = #{self}.length; i < length; i++) { - #{yield `#{self}.charAt(i)`} - } - } + each_char.to_a end def chomp(separator = $/) + return self if `separator === nil || self.length === 0` + + if `separator._isString == null` + unless separator.respond_to? :to_str + raise TypeError, "no implicit conversion of #{separator.class.name} into String" + end + + separator = separator.to_str + end + %x{ - var strlen = #{self}.length; - var seplen = separator.length; - if (strlen > 0) { - if (separator === "\\n") { - var last = #{self}.charAt(strlen - 1); - if (last === "\\n" || last == "\\r") { - var result = #{self}.substr(0, strlen - 1); - if (strlen > 1 && #{self}.charAt(strlen - 2) === "\\r") { - result = #{self}.substr(0, strlen - 2); - } - return result; - } + if (separator === "\\n") { + return self.replace(/\\r?\\n?$/, ''); + } + else if (separator === "") { + return self.replace(/(\\r?\\n)+$/, ''); + } + else if (self.length > separator.length) { + var tail = self.substr(-1 * separator.length); + + if (tail === separator) { + return self.substr(0, self.length - separator.length); } - else if (separator === "") { - return #{self}.replace(/(?:\\n|\\r\\n)+$/, ''); - } - else if (strlen >= seplen) { - var tail = #{self}.substr(-1 * seplen); - if (tail === separator) { - return #{self}.substr(0, strlen - seplen); - } - } } - return #{self} } + + self end def chop - `#{self}.substr(0, #{self}.length - 1)` + `self.substr(0, self.length - 1)` end def chr - `#{self}.charAt(0)` + `self.charAt(0)` end def clone - `#{self}.slice()` + `self.slice()` end def count(str) - `(#{self}.length - #{self}.replace(new RegExp(str,"g"), '').length) / str.length` + `(self.length - self.replace(new RegExp(str, 'g'), '').length) / str.length` end alias dup clone def downcase - `#{self}.toLowerCase()` + `self.toLowerCase()` end - alias each_char chars + def each_char(&block) + return enum_for :each_char unless block_given? - def each_line (separator = $/) - return self.split(separator).each unless block_given? - %x{ - var chomped = #{self.chomp}; - var trailing_separator = #{self}.length != chomped.length - var splitted = chomped.split(separator); + for (var i = 0, length = self.length; i < length; i++) { + #{yield `self.charAt(i)`}; + } + } - if (!#{block_given?}) { - result = [] - for (var i = 0, length = splitted.length; i < length; i++) { - if (i < length - 1 || trailing_separator) { - result.push(splitted[i] + separator); - } - else { - result.push(splitted[i]); - } - } + self + end - return #{`result`.each}; - } + def each_line(separator = $/) + return split(separator) unless block_given? + %x{ + var chomped = #{chomp}, + trailing = self.length != chomped.length, + splitted = chomped.split(separator); + for (var i = 0, length = splitted.length; i < length; i++) { - if (i < length - 1 || trailing_separator) { - #{yield `splitted[i] + separator`} + if (i < length - 1 || trailing) { + #{yield `splitted[i] + separator`}; } else { - #{yield `splitted[i]`} + #{yield `splitted[i]`}; } } } + + self end def empty? - `#{self}.length === 0` + `self.length === 0` end def end_with?(*suffixes) %x{ for (var i = 0, length = suffixes.length; i < length; i++) { var suffix = suffixes[i]; - if (#{self}.length >= suffix.length && #{self}.substr(0 - suffix.length) === suffix) { + if (self.length >= suffix.length && self.substr(0 - suffix.length) === suffix) { return true; } } - - return false; } + + false end alias eql? == + alias equal? === - def equal?(val) - `#{self}.toString() === val.toString()` - end - - def getbyte(idx) - `#{self}.charCodeAt(idx)` - end - def gsub(pattern, replace = undefined, &block) - if pattern.is_a?(String) - pattern = /#{Regexp.escape(pattern)}/ + if String === pattern || pattern.respond_to?(:to_str) + pattern = /#{Regexp.escape(pattern.to_str)}/ end + unless Regexp === pattern + raise TypeError, "wrong argument type #{pattern.class} (expected Regexp)" + end + %x{ var pattern = pattern.toString(), options = pattern.substr(pattern.lastIndexOf('/') + 1) + 'g', regexp = pattern.substr(1, pattern.lastIndexOf('/') - 1); @@ -319,45 +307,58 @@ def hex to_i 16 end def include?(other) - `#{self}.indexOf(other) !== -1` + %x{ + if (other._isString) { + return self.indexOf(other) !== -1; + } + } + + unless other.respond_to? :to_str + raise TypeError, "no implicit conversion of #{other.class.name} into String" + end + + `self.indexOf(#{other.to_str}) !== -1` end def index(what, offset = nil) %x{ - if ( !(what != null && (what._isString || what._isRegexp)) ) { - #{raise TypeError, 'type mismatch'}; + if (!(what._isString || what._isRegexp)) { + #{raise TypeError, "type mismatch: #{what.class} given"}; } var result = -1; - if (offset != null) { + if (offset !== nil) { if (offset < 0) { - offset = offset + #{self}.length; + offset = offset + self.length; } - if (offset > #{self}.length) { + if (offset > self.length) { return nil; } - if (#{what.is_a?(Regexp)}) { - result = #{what =~ `#{self}.substr(offset)` || -1} - } else { - result = #{self}.substr(offset).indexOf(#{what}); + if (what._isRegexp) { + result = #{(what =~ `self.substr(offset)`) || -1} } + else { + result = self.substr(offset).indexOf(what); + } if (result !== -1) { result += offset; } - } else { - if (#{what.is_a?(Regexp)}) { + } + else { + if (what._isRegexp) { result = #{(what =~ self) || -1} - } else { - result = #{self}.indexOf(#{what}); } + else { + result = self.indexOf(what); + } } return result === -1 ? nil : result; } end @@ -375,54 +376,62 @@ '\\\\': '\\\\\\\\' }; escapable.lastIndex = 0; - return escapable.test(#{self}) ? '"' + #{self}.replace(escapable, function(a) { + return escapable.test(self) ? '"' + self.replace(escapable, function(a) { var c = meta[a]; return typeof c === 'string' ? c : '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' : '"' + #{self} + '"'; - } + }) + '"' : '"' + self + '"'; + } end def intern self end - alias lines each_line + def lines(separator = $/) + each_line(separator).to_a + end def length - `#{self}.length` + `self.length` end def ljust(width, padstr = ' ') + return self if `width <= self.length` + %x{ - var length = #{self}.length; + var index = -1, + result = ""; - if (width <= length) { - return #{self}; - } - else { - var index = -1, result = ""; + width -= self.length; - while (++index < (width - length)) { - result += padstr; - } - - return #{self} + result.slice(0, width - length); + while (++index < width) { + result += padstr; } + + return self + result.slice(0, width); } end def lstrip - `#{self}.replace(/^\\s*/, '')` + `self.replace(/^\\s*/, '')` end def match(pattern, pos = undefined, &block) - (pattern.is_a?(Regexp) ? pattern : /#{Regexp.escape(pattern)}/).match(self, pos, &block) + if String === pattern || pattern.respond_to?(:to_str) + pattern = /#{Regexp.escape(pattern.to_str)}/ + end + + unless Regexp === pattern + raise TypeError, "wrong argument type #{pattern.class} (expected Regexp)" + end + + pattern.match(self, pos, &block) end def next %x{ if (#{self}.length === 0) { @@ -497,26 +506,24 @@ return result === -1 ? nil : result; } end def rjust(width, padstr = ' ') + return self if `width <= self.length` + %x{ - if (width <= #{self}.length) { - return #{self}; - } - else { - var n_chars = Math.floor(width - #{self}.length) - var n_patterns = Math.floor(n_chars/padstr.length); - var result = Array(n_patterns + 1).join(padstr); - var remaining = n_chars - result.length; - return result + padstr.slice(0, remaining) + #{self}; - } + var chars = Math.floor(width - self.length), + patterns = Math.floor(chars / padstr.length), + result = Array(patterns + 1).join(padstr), + remaining = chars - result.length; + + return result + padstr.slice(0, remaining) + self; } end def rstrip - `#{self}.replace(/\\s*$/, '')` + `self.replace(/\\s*$/, '')` end def scan(pattern, &block) %x{ if (pattern.global) { @@ -997,11 +1004,11 @@ return new_str; } end def upcase - `#{self}.toUpperCase()` + `self.toUpperCase()` end def freeze self end @@ -1010,88 +1017,5 @@ true end end Symbol = String - -class MatchData < Array - attr_reader :post_match, :pre_match, :regexp, :string - - def self.new(regexp, match_groups) - %x{ - var instance = new Opal.MatchData._alloc; - for (var i = 0, len = match_groups.length; i < len; i++) { - var group = match_groups[i]; - if (group == undefined) { - instance.push(nil); - } - else { - instance.push(group); - } - } - instance._begin = match_groups.index; - instance.regexp = regexp; - instance.string = match_groups.input; - instance.pre_match = #{$` = `instance.string.substr(0, regexp.lastIndex - instance[0].length)`}; - instance.post_match = #{$' = `instance.string.substr(regexp.lastIndex)`}; - return #{$~ = `instance`}; - } - end - - def begin(pos) - %x{ - if (pos == 0 || pos == 1) { - return #{self}._begin; - } - else { - #{raise ArgumentError, 'MatchData#begin only supports 0th element'}; - } - } - end - - def captures - `#{self}.slice(1)` - end - - def inspect - %x{ - var str = "<#MatchData " + #{self}[0].$inspect() - for (var i = 1, len = #{self}.length; i < len; i++) { - str += " " + i + ":" + #{self}[i].$inspect(); - } - str += ">"; - return str; - } - end - - def to_s - `#{self}[0]` - end - - def to_n - `#{self}.valueOf()` - end - - def values_at(*indexes) - %x{ - var vals = []; - var match_length = #{self}.length; - for (var i = 0, length = indexes.length; i < length; i++) { - var pos = indexes[i]; - if (pos >= 0) { - vals.push(#{self}[pos]); - } - else { - pos = match_length + pos; - if (pos > 0) { - vals.push(#{self}[pos]); - } - else { - vals.push(nil); - } - } - } - - return vals; - } - end -end