I forgot to mention that in order to be able to translate XPath to Smalltalk
I added these methods to my Smalltalk:
AbstractSequence>>
�� afterSubCollection: aSequence [ifAbsent: exceptionBlock]
������ "based on substring-after"
�� beforeSubCollection: aSequence [ifAbsent: exceptionBlock]
������ "based on substring-before"
I'm not going to display the code, which is pretty simple, because there is a
serious efficiency problem with these.�� (The Java equivalent, had there been
one, would not have had this problem, but since I think Java 7 it would too.)
Imagine that we have a string consisting of N instances of separators, and
we want to split it into pieces.
�� [s includesSubCollection: separator] whileTrue: [
�������� self process: (s beforeSubCollection: separator).
�������� s := s afterSubCollection: separator].
�� s isEmpty ifFalse: [
�������� self process: s].
Do I need to explain why this takes O(N**2) time?
However,
�� r := ReadStream on: s.
�� [r atEnd] whileFalse: [
�������� self process: (r upToAll: separator)].
is linear time (assuming an efficient #upToAll:).
My previous remarks about boundary issues apply here as well, of course.
My previous remarks about wanting to see the context do too.