tags:

views:

145

answers:

4

In Smalltalk, if given the string 'OneTwoThree', I'd like to remove the last 'Three' part, .e., In Squeak method finder notation: 'OneTwoThree' . 'Three' . 'OneTwo'.

The best I can come up with is:

'OneTwoThree' allButLast: 'Three' size,

but it doesn't feel very Smalltalk-ish, because it uses the substring length, rather than the substring itself. How would you code it?

+5  A: 

I usually use #copyReplaceAll:with: method, if the last string is not repeated elsewhere in the original string of course:

'OneTwoThree' copyReplaceAll: 'Three' with: ''
Janko Mivšek
Yup, but that'll replace ALL appearences of 'Three'. But yes, it's short and sweet.
nes1983
But just for your case I think your solution is still the best.
Janko Mivšek
+1  A: 

If you need everything after only the last occurence removed:

|original cutOut lastEnd currentEnd modified|

original := 'OneTwoThree'.
cutOut := 'Three'.
lastEnd := 0.
[currentEnd := lastEnd.
lastEnd := original indexOf: cutOut startingAt: lastEnd +1.
lastEnd = 0 ] whileFalse.

modified := currentStart > 0 ifTrue: [original first: currentEnd] ifFalse: [original copy]

Rydier
Mmmm this code is not very object oriented. The options described above are far better because they actually reuse provided code. In smalltalk this kind of procedural code is considered as a sin.
Koder_
Well, neither of the two methods above does what he asked, from how I interpreted it; remove the last part of a string, starting at the last occurrence of another string. readStream upToAll: returns a string with everything after the first occurrence of 'Three' removed. copyReplaceAll: returns the string with all occurences of 'Three' removed, and nothing else. So while they reuse what others have created convenience methods for, that doesn't actually help if it's not what he's trying to do :)
Rydier
BTW; if you consider that kind of code a "sin", try looking at the actual implementations of copyReplaceAll:with: and upToAll: ;)
Rydier
You're right, rydier. It appears that there isn't a clever convenience method for everything, yet. If Stream had upToLastAll:, that'd do it.
nes1983
+6  A: 
'OneTwoThree' readStream upToAll: 'Three'
Lukas Renggli
+2  A: 

In the Moose project, there should be a method #removeSuffix: that removes a given suffix, if present.

Adrian