function rstrip(s::AbstractString, chars::Chars=_default_delims)
a = start(s)
i = endof(s)
while a ≤ i
c = s[i]
j = prevind(s, i)
c in chars || return SubString(s, 1:i)
i = j
end
SubString(s, a, a-1)
end
I think strings are now expected to use 1 as their first index, so that should always work. But it’s indeed a bit silly to call start in one place and use 1 in another. Would you make a pull request to use a? You can edit the file directly on GitHub.
yuyichao is correct here: it is the last line that should be fixed, to be either Substring(s, 1:0) or simply "".
I think the second might be preferable, because you don’t want to keep around a unnecessary pointer to s, that might prevent it from getting GCed laster.
This is a common confusion, that the iterator state == index, which isn’t always true.
Yeah, that’s right. This is what happens when you try to write generic code without any actual implementations for which indices and iteration state differ. Since strings are now required to use 1 as their first index, we can as well use 1 everywhere instead of a.
However, we can’t return "" because of type stability.
True - for my Strs.jl code, I have an empty_str(::Type{S}) where {S<:...} = ... for that case, so that all “” values are the same (which is fine since these strings are immutable).
Possibly S("") would work, if you have function rstrip(s::S, chars::Chars=_default_delims) where {S<:AbstractString}
Base already defines one for this. (Since * is string concatenation, one returns the empty string.) But it is not applicable in this case because of type stability: rstrip must return a SubString in all cases.
I just wanted to point out that having to define one (or zero) for strings was not such an obvious or inevitable consequence of the choice of * for concatenation.
Is it documented, as part of the API that needs to be implemented by anybody adding a new AbstractString type, as I am doing?
Nice! I just verified, the fallback works just fine for my strings package - one(UTF32Str) gives me a “” of type UTF32Str, as expected, without me having to had a method for it.
I think it would be an issue of a string type where the value of start(str) is not 1.
You could create a reversed string type, that returned a start value of sizeof(str), for example, and used prevind to walk backwards, for example, to show the bug.
I guess we could change the GenericString type, which is used to test that the string functions do not make more assumptions than the interface allows, to have start return something different from 1.