Skip to content

Commit

Permalink
Support String inheritance
Browse files Browse the repository at this point in the history
  • Loading branch information
meh committed Dec 25, 2013
1 parent b15ea9f commit b22350c
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 29 deletions.
90 changes: 86 additions & 4 deletions opal/corelib/string.rb
Expand Up @@ -3,6 +3,20 @@ class String

`def._isString = true`

def self.inherited(klass)
replace = Class.new(String::Wrapper)

%x{
klass._proto = replace._proto;
klass._proto._klass = klass;
klass._alloc = replace._alloc;
klass.__parent = #{String::Wrapper};
klass.$allocate = replace.$allocate;
klass.$new = replace.$new;
}
end

def self.try_convert(what)
what.to_str
rescue
Expand Down Expand Up @@ -69,9 +83,12 @@ def <=>(other)
end

def ==(other)
`!!(other._isString && self.valueOf() === other.valueOf())`
return false unless String === other

`#{to_s} == #{other.to_s}`
end

alias eql? ==
alias === ==

def =~(other)
Expand Down Expand Up @@ -767,8 +784,8 @@ def sum(n = 16)
%x{
var result = 0;
for (var i = 0, length = #{self}.length; i < length; i++) {
result += (#{self}.charCodeAt(i) % ((1 << n) - 1));
for (var i = 0, length = self.length; i < length; i++) {
result += (self.charCodeAt(i) % ((1 << n) - 1));
}
return result;
Expand Down Expand Up @@ -840,7 +857,7 @@ def to_proc
end

def to_s
`#{self}.toString()`
`self.toString()`
end

alias to_str to_s
Expand Down Expand Up @@ -1149,3 +1166,68 @@ def frozen?
end

Symbol = String

class String::Wrapper
def self.allocate(string = "")
obj = super()
`obj.literal = string`
obj
end

def self.new(*args, &block)
obj = allocate
obj.initialize(*args, &block)
obj
end

def self.[](*objects)
allocate(objects)
end

def initialize(string = '')
@literal = string
end

def method_missing(*args, &block)
result = @literal.__send__(*args, &block)

if `result._isString != null`
if `result == #@literal`
self
else
self.class.allocate(result)
end
else
result
end
end

def initialize_copy(other)
@literal = `other.literal`.clone
end

def respond_to?(name, *)
super || @literal.respond_to?(name)
end

def ==(other)
@literal == other
end

alias eql? ==
alias === ==

def to_s
@literal
end

def to_str
self
end

def inspect
@literal.inspect
end

# unwrapped results
end
1 change: 1 addition & 0 deletions spec/opal/filters/bugs/string.rb
Expand Up @@ -177,6 +177,7 @@
fails "String#split with Regexp returns a type error if limit can't be converted to an integer"
fails "String#split with Regexp returns subclass instances based on self"
fails "String#split with Regexp does not call constructor on created subclass instances"
fails "String#split with String does not call constructor on created subclass instances"

fails "String#squeeze negates sets starting with ^"
fails "String#squeeze squeezes all chars in a sequence"
Expand Down
25 changes: 0 additions & 25 deletions spec/opal/filters/unsupported/string_subclasses.rb

This file was deleted.

0 comments on commit b22350c

Please sign in to comment.