Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #365 from jerith/jerith/String#sub
Implementation of String#sub.
  • Loading branch information
alex committed Feb 15, 2013
2 parents 0234269 + f7c5fca commit 88b854d
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 6 deletions.
39 changes: 37 additions & 2 deletions tests/objects/test_stringobject.py
Expand Up @@ -426,9 +426,9 @@ def test_includep(self, space):

def test_gsub(self, space):
w_res = space.execute("""
return 'hello'.gsub("he", "ha")
return 'hello hello'.gsub("he", "ha")
""")
assert space.str_w(w_res) == "hallo"
assert space.str_w(w_res) == "hallo hallo"
w_res = space.execute("""
return 'hello'.gsub(/(.)/, "ha")
""")
Expand Down Expand Up @@ -459,6 +459,41 @@ def test_gsub(self, space):
""")
assert space.str_w(w_res) == "he21oo"

def test_sub(self, space):
w_res = space.execute("""
return 'hello hello'.sub("he", "ha")
""")
assert space.str_w(w_res) == "hallo hello"
w_res = space.execute("""
return 'hello'.sub(/(.)/, "ha")
""")
assert space.str_w(w_res) == "haello"
w_res = space.execute("""
return 'hello'.sub(/(.)/, "ha\\\\1ho")
""")
assert space.str_w(w_res) == "hahhoello"
w_res = space.execute("""
return 'hello'.sub(/(.)/) { |e| e + "1" }
""")
assert space.str_w(w_res) == "h1ello"
w_res = space.execute("""
return 'hello'.sub('l') { |e| e + "1" }
""")
assert space.str_w(w_res) == "hel1lo"
w_res = space.execute("""
return 'hello'.sub(/[eo]/, 'e' => 3, 'o' => '*')
""")
assert space.str_w(w_res) == "h3llo"
w_res = space.execute("""
return 'hello'.sub("e", 'e' => 3, 'o' => '*')
""")
assert space.str_w(w_res) == "h3llo"
w_res = space.execute("""
replacements = [1, 2]
return 'helloo'.sub("l", Hash.new { |h, k| replacements.pop() })
""")
assert space.str_w(w_res) == "he2loo"

def test_succ(self, space):
w_res = space.execute('return "abcd".succ')
assert space.str_w(w_res) == "abce"
Expand Down
19 changes: 15 additions & 4 deletions topaz/objects/stringobject.py
Expand Up @@ -792,6 +792,13 @@ def method_includep(self, space, substr):

@classdef.method("gsub")
def method_gsub(self, space, w_pattern, w_replacement=None, block=None):
return self.gsub_main(space, w_pattern, w_replacement, block, first_only=False)

@classdef.method("sub")
def method_sub(self, space, w_pattern, w_replacement=None, block=None):
return self.gsub_main(space, w_pattern, w_replacement, block, first_only=True)

def gsub_main(self, space, w_pattern, w_replacement, block, first_only):
if w_replacement is None and block is None:
raise NotImplementedError("gsub enumerator")

Expand All @@ -806,16 +813,16 @@ def method_gsub(self, space, w_pattern, w_replacement=None, block=None):
)

if space.is_kind_of(w_pattern, space.w_regexp):
return self.gsub_regexp(space, w_pattern, replacement, w_hash, block)
return self.gsub_regexp(space, w_pattern, replacement, w_hash, block, first_only)
elif space.is_kind_of(w_pattern, space.w_string):
return self.gsub_string(space, w_pattern, replacement, w_hash, block)
return self.gsub_string(space, w_pattern, replacement, w_hash, block, first_only)
else:
raise space.error(
space.w_TypeError,
"wrong argument type %s (expected Regexp)" % space.getclass(w_replacement).name
)

def gsub_regexp(self, space, w_pattern, replacement, w_hash, block):
def gsub_regexp(self, space, w_pattern, replacement, w_hash, block, first_only):
result = []
pos = 0
string = space.str_w(self)
Expand All @@ -840,6 +847,8 @@ def gsub_regexp(self, space, w_pattern, replacement, w_hash, block):
result += self.gsub_regexp_hash(space, w_hash, w_matchdata)
pos = ctx.match_end
ctx.reset(pos)
if first_only:
break
result += string[pos:]
return space.newstr_fromchars(result)

Expand Down Expand Up @@ -870,7 +879,7 @@ def gsub_regexp_hash(self, space, w_hash, w_match):
w_arg = space.send(w_match, space.newsymbol("[]"), [space.newint(0)])
return self.gsub_lookup_hash(space, w_hash, w_arg)

def gsub_string(self, space, w_pattern, replacement, w_hash, block):
def gsub_string(self, space, w_pattern, replacement, w_hash, block, first_only):
result = []
pos = 0
string = space.str_w(self)
Expand All @@ -888,6 +897,8 @@ def gsub_string(self, space, w_pattern, replacement, w_hash, block):
pos = idx + len(pattern)
else:
break
if first_only:
break
result += string[pos:]
return space.newstr_fromchars(result)

Expand Down

0 comments on commit 88b854d

Please sign in to comment.