Entirely against my will, I once worked in a perl shop, and I noticed
that perlites liked joining things. Whenever I find myself wanting to join a bunch of items together (e.g. to make a path) I am never satisfied with the result and so I took a look at the Collections/String classes to see whether anything fitted nicely. I came up with SequencableCollection>>join: aCollection ^ self class streamContents: [ :stream | aCollection do: [ :each | stream nextPut: each ] separatedBy: [ stream nextPutAll: self ] ] and Character>>join: aCollectionOfStrings ^ self class streamContents: [ :stream | aCollectionOfStrings do: [ :each | stream nextPutAll: each ] separatedBy: [ stream nextPut: self ] ] and Collection>>joinWith: aCollection aCollection join: self ---- This now allows (Array with: 1 with: 2) join: (Array with: 3 with: 4 with: 5) $/ join: (Array with: 'Hello' with: 'my' with: 'World'). any thoughts? I am curious as to why #join: hasn't made it into the core image, and if it were to how would it happen? Keith ___________________________________________________________ The all-new Yahoo! Mail goes wherever you go - free your email address from your Internet provider. http://uk.docs.yahoo.com/nowyoucan.html |
On 14-Sep-06, at 4:57 PM, Keith Hodges wrote: > Entirely against my will, I once worked in a perl shop, and I > noticed that perlites liked joining things. > > Whenever I find myself wanting to join a bunch of items together > (e.g. to make a path) I am never satisfied with the result and so I > took a look at the Collections/String classes to see whether > anything fitted nicely. Well, first point is that you shouldn't make paths like that. Filenames are *not* strings. If you use constructs like FileDirectory default directoryNamed:'foo' you'd get a properly (well, as properly as we can manage right now) made file directory object with a properly formed pathname. It would handle platform path separator issues, for example. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim The generation of random numbers is too important to be left to chance. |
In answer to your first point, I was not intending to use join for that,
it was 'only' an example. To be honest I dont think much of Squeak's directory/path classes I contributed to a nice ruby 'Path' module about 5 years ago which was quite elegant. Keith ___________________________________________________________ To help you stay safe and secure online, we've developed the all new Yahoo! Security Centre. http://uk.security.yahoo.com |
In reply to this post by keith1y
Hi Keith,
on Fri, 15 Sep 2006 01:57:52 +0200, wrote: ... > any thoughts? I am curious as to why #join: hasn't made it into the core > image, and if it were to how would it happen? There are several reasons for the absence of #join: - the most important one is, that nobody needs it (or else you would have found it). Imagine Pearl with the full Squeak Stream hierarchy, why use join? - streaming is more flexible when you keep control, it allows better maintainable and adaptable code. - #join: must be implemented in *base* classes in order to work. String streamContents: [:...] must not be implemented anywhere, it's always where want need it. Just my CHF 0.05 /Klaus > Keith |
On Sep 14, 2006, at 6:25 PM, Klaus D. Witzel wrote: > Hi Keith, > > on Fri, 15 Sep 2006 01:57:52 +0200, wrote: > ... >> any thoughts? I am curious as to why #join: hasn't made it into >> the core image, and if it were to how would it happen? > > There are several reasons for the absence of #join: > > - the most important one is, that nobody needs it (or else you > would have found it). Imagine Pearl with the full Squeak Stream > hierarchy, why use join? Sure we need it. At Smallthought, we have a package of utility methods that includes: SequencableCollection>>joinTokens: aString ^ String streamContents: [:s | self do: [:ea | s nextPutAll: ea asString] separatedBy: [s nextPutAll: aString]] Looking through my sends to it, the argument is always either ' ' or ', ', so #joinedWithSpaces and #joinedWithCommas would probably be sensible methods to have too. Avi |
Hi Avi,
on Fri, 15 Sep 2006 03:31:02 +0200, wrote: > On Sep 14, 2006, at 6:25 PM, Klaus D. Witzel wrote: >> Hi Keith, >> on Fri, 15 Sep 2006 01:57:52 +0200, wrote: >> ... >>> any thoughts? I am curious as to why #join: hasn't made it into the >>> core image, and if it were to how would it happen? >> >> There are several reasons for the absence of #join: >> >> - the most important one is, that nobody needs it (or else you would >> have found it). Imagine Pearl with the full Squeak Stream hierarchy, >> why use join? > > Sure we need it. At Smallthought, we have a package of utility methods > that includes: > > SequencableCollection>>joinTokens: aString > ^ String streamContents: > [:s | > self do: [:ea | s nextPutAll: ea asString] separatedBy: [s nextPutAll: > aString]] > > Looking through my sends to it, the argument is always either ' ' or ', > ', so #joinedWithSpaces and #joinedWithCommas would probably be sensible > methods to have too. No nitpicking intended, the question and the answer was from the perspective why Squeak doesn't have it. But you're right, one counterexample brings my nobody case to fall :) /Klaus > Avi |
In reply to this post by Avi Bryant
Thanks Avi,
thats just the method that I was looking for! So please let's get it added to the base image ;-) This request is somewhat academic since I am stuck in 3.8 for a while until Magma supports 3.9. Keith >> >> - the most important one is, that nobody needs it (or else you would >> have found it). Imagine Pearl with the full Squeak Stream hierarchy, >> why use join? > > Sure we need it. At Smallthought, we have a package of utility > methods that includes: > > SequencableCollection>>joinTokens: aString > ^ String streamContents: > [:s | > self do: [:ea | s nextPutAll: ea asString] separatedBy: [s > nextPutAll: aString]] > > Looking through my sends to it, the argument is always either ' ' or > ', ', so #joinedWithSpaces and #joinedWithCommas would probably be > sensible methods to have too. > > Avi > > ___________________________________________________________ All new Yahoo! Mail "The new Interface is stunning in its simplicity and ease of use." - PC Magazine http://uk.docs.yahoo.com/nowyoucan.html |
In reply to this post by Avi Bryant
Poking around a frequently used image I find:
String>>splitOn: aString and SequenceableCollection>>joinOn: aString And I use them quite a bit when processing input. On Sep 14, 2006, at 6:31 PM, Avi Bryant wrote: > On Sep 14, 2006, at 6:25 PM, Klaus D. Witzel wrote: > >> Hi Keith, >> >> on Fri, 15 Sep 2006 01:57:52 +0200, wrote: >> ... >>> any thoughts? I am curious as to why #join: hasn't made it into >>> the core image, and if it were to how would it happen? >> >> There are several reasons for the absence of #join: >> >> - the most important one is, that nobody needs it (or else you >> would have found it). Imagine Pearl with the full Squeak Stream >> hierarchy, why use join? > > Sure we need it. At Smallthought, we have a package of utility > methods that includes: > > SequencableCollection>>joinTokens: aString > ^ String streamContents: > [:s | > self do: [:ea | s nextPutAll: ea asString] separatedBy: [s > nextPutAll: aString]] > > Looking through my sends to it, the argument is always either ' ' > or ', ', so #joinedWithSpaces and #joinedWithCommas would probably > be sensible methods to have too. > > Avi > |
In reply to this post by keith1y
>> Sure we need it. At Smallthought, we have a package of utility
>> methods that includes: >> >> SequencableCollection>>joinTokens: aString >> ^ String streamContents: >> [:s | >> self do: [:ea | s nextPutAll: ea asString] separatedBy: [s >> nextPutAll: aString]] >> >> Looking through my sends to it, the argument is always either ' ' or >> ', ', so #joinedWithSpaces and #joinedWithCommas would probably be >> sensible methods to have too. >> >> Avi Funny, one of the first extension methods I added when I learned Smalltalk, was join as well, I'm still amazed it isn't already there. I got tired of typing out the stream version, and in all but one case, I was also joining on either ' ' or ', '. Collection>>join: aString ^String streamContents: [:stream | self do: [:each | stream nextPutAll: each] separatedBy: [stream nextPutAll: aString]] Avi, is there a reason you chose SequencableColleciton over just Collection, I'm curious if I've put mine in the wrong place, and the implications of doing so? |
In reply to this post by tblanchard
> Poking around a frequently used image I find:
> > String>>splitOn: aString > and > SequenceableCollection>>joinOn: aString > > And I use them quite a bit when processing input. Care to share your #splitOn:, my #split: was just a synonym for #findTokens: which I recently realized didn't do what I thought it did. |
OK
splitOn: aString | idx lastIdx | idx := lastIdx := 1. ^Array streamContents: [:s | [idx <= self size] whileTrue: [ idx := self findString: aString startingAt: lastIdx. idx = 0 ifTrue: [idx := self size + 1]. s nextPut: (self copyFrom: lastIdx to: idx-1). lastIdx := idx + aString size. ] ] On Sep 14, 2006, at 8:48 PM, Ramon Leon wrote: >> Poking around a frequently used image I find: >> String>>splitOn: aString >> and >> SequenceableCollection>>joinOn: aString >> And I use them quite a bit when processing input. > > Care to share your #splitOn:, my #split: was just a synonym for > #findTokens: which I recently realized didn't do what I thought it > did. > > |
In reply to this post by Ramon Leon-4
On Sep 14, 2006, at 8:44 PM, Ramon Leon wrote: > Avi, is there a reason you chose SequencableColleciton over just > Collection, I'm curious if I've put mine in the wrong place, and > the implications of doing so? Only that the output is deterministic for a SequenceableCollection and not for, say, a Set. Avi |
In reply to this post by tblanchard
> splitOn: aString
> > | idx lastIdx | > idx := lastIdx := 1. > > ^Array streamContents: > [:s | > [idx <= self size] whileTrue: > [ > idx := self findString: aString startingAt: lastIdx. > idx = 0 ifTrue: [idx := self size + 1]. > s nextPut: (self copyFrom: lastIdx to: idx-1). > lastIdx := idx + aString size. > ] > ] Cool, thanks. |
In reply to this post by keith1y
Oscar and Damien did an implementation of join and split and I would
really like to ease perl people and include such protocols in the next release (with tests) Now if would be nice to have a discussion on the implementations http://bugs.impara.de/view.php?id=4874 > I came up with > > SequencableCollection>>join: aCollection > > ^ self class streamContents: [ :stream | > aCollection > do: [ :each | stream nextPut: each ] > separatedBy: [ stream nextPutAll: self ] ] > > > and > > Character>>join: aCollectionOfStrings > > ^ self class streamContents: [ :stream | > aCollectionOfStrings > do: [ :each | stream nextPutAll: each ] > separatedBy: [ stream nextPut: self ] ] > > and > > Collection>>joinWith: aCollection > > aCollection join: self > > ---- > This now allows > (Array with: 1 with: 2) join: (Array with: 3 with: 4 with: 5) > $/ join: (Array with: 'Hello' with: 'my' with: 'World'). > > any thoughts? I am curious as to why #join: hasn't made it into the > core image, and if it were to how would it happen? > > Keith > > > ___________________________________________________________ The all- > new Yahoo! Mail goes wherever you go - free your email address from > your Internet provider. http://uk.docs.yahoo.com/nowyoucan.html > |
In reply to this post by keith1y
hi guys
could you sit down and propose a cool set of names and implementation and we include it in 3.10 http://bugs.impara.de/view.php?id=4874 |
In reply to this post by stephane ducasse-2
I'll just mention that mine are modeled on the NextStep routines
NSString>>componentsSeparatedByString: NSArray>>componentsJoinedByString: they behave exactly the same way. On Sep 15, 2006, at 8:37 AM, stephane ducasse wrote: > Oscar and Damien did an implementation of join and split and I > would really like to ease > perl people and include such protocols in the next release (with > tests) > Now if would be nice to have a discussion on the implementations > > http://bugs.impara.de/view.php?id=4874 > >> I came up with >> >> SequencableCollection>>join: aCollection >> >> ^ self class streamContents: [ :stream | >> aCollection >> do: [ :each | stream nextPut: each ] >> separatedBy: [ stream nextPutAll: self ] ] >> >> >> and >> >> Character>>join: aCollectionOfStrings >> >> ^ self class streamContents: [ :stream | >> aCollectionOfStrings >> do: [ :each | stream nextPutAll: each ] >> separatedBy: [ stream nextPut: self ] ] >> >> and >> >> Collection>>joinWith: aCollection >> >> aCollection join: self >> >> ---- >> This now allows >> (Array with: 1 with: 2) join: (Array with: 3 with: 4 with: 5) >> $/ join: (Array with: 'Hello' with: 'my' with: 'World'). >> >> any thoughts? I am curious as to why #join: hasn't made it into >> the core image, and if it were to how would it happen? >> >> Keith >> >> >> ___________________________________________________________ The >> all-new Yahoo! Mail goes wherever you go - free your email address >> from your Internet provider. http://uk.docs.yahoo.com/nowyoucan.html >> > > |
On 9/15/06, Todd Blanchard <[hidden email]> wrote:
> I'll just mention that mine are modeled on the NextStep routines > > NSString>>componentsSeparatedByString: > NSArray>>componentsJoinedByString: Are you using an Objective-C bridge here ? -- Damien Pollet type less, do more |
In reply to this post by stephane ducasse-2
stephane ducasse wrote:
> Oscar and Damien did an implementation of join and split and I would > really like to ease > perl people and include such protocols in the next release (with tests) > Now if would be nice to have a discussion on the implementations I've also had a brush with Perl, so was looking for join/split too. Here's what I have. Notice that split: expects a charater argument. IIRC, the reason I did that was to make it easier to implement the equivalent method on VAST. Also, the joinWith: doesn't use nextPutAll:separatedBy: so I could easily implement an equivalent method in VAST and VW. SequenceableCollection joinWith: separator "Answer a string with elements converted to strings and separated by separator." | ws | ws := WriteStream on: (String new: 100). self withIndexDo: [:each :i | ws nextPutAll: each asString. i < self size ifTrue: [ ws nextPutAll: separator ]. ]. ^ws contents String>>split: ch | pieces i prev | pieces := OrderedCollection new. i := 0. [(i := self indexOf: ch startingAt: (prev := i + 1)) == 0] whileFalse: [prev < i ifTrue: [pieces add: (self copyFrom: prev to: i - 1)]. prev == i ifTrue: [pieces add: String new]]. prev <= self size ifTrue: [pieces add: (self copyFrom: prev to: self size)]. (self isEmpty not and: [self last = ch]) ifTrue: [pieces add: String new]. ^pieces |
In reply to this post by Damien Pollet
No, I just reproduced their behavior in Squeak.
On Sep 15, 2006, at 9:29 AM, Damien Pollet wrote: > On 9/15/06, Todd Blanchard <[hidden email]> wrote: >> I'll just mention that mine are modeled on the NextStep routines >> >> NSString>>componentsSeparatedByString: >> NSArray>>componentsJoinedByString: > > Are you using an Objective-C bridge here ? > > -- > Damien Pollet > type less, do more > |
In reply to this post by stephane ducasse-2
Hi Folks, Let me summarize my thoughts on the topic of split and join. General: - As far as I can tell, neither split: nor join: can be easily simulated by existing methods On split: - split: is fairly specific to strings, though it could be generalized to other kinds of Sequenceables - split: should take a String, not a Character, as its argument (as in Ruby & friends) - generally speaking, the argument to split: should be a Regex, so it makes sense to make String>>split: an extension to String from the regex package (i.e., VB-Regex) - string-matching is a well-known problem, so we should avoid ad hoc solutions. See for example http://doi.acm.org/10.1145/360825.360855 For this reason I think that split: should depend on VB-Regex, unless someone want's to implement one of the modern algoirthms I propose that: String>>split: ^ regexString asRegex split: self As follows Regex>>split: aString | result lastPosition | result := OrderedCollection new. stream := aString readStream. lastPosition := stream position. [ self searchStream: stream ] whileTrue: [ result add: (aString copyFrom: lastPosition+1 to: (self subBeginning: 1)). self assert: lastPosition < stream position description: 'Regex cannot match null string'. lastPosition := stream position ]. result add: (aString copyFrom: lastPosition+1 to: aString size). ^ result NB: - Assertion is needed to avoid infinite loops in case of null Regex. On join: - join: is the conceptual inverse of split: (see the tests in http:// squeaksource.com/RubyShards/) - join: obviously works for Sequenceables as well as Strings I propose adding the following method to either SequenceableCollection or OrderedCollection [the tradeoff is not clear to me]. join: anOrderedCollection "Implicit precondition: my elements are all OrderedCollections" | result index | result := (self at: 1) writeStream. result nextPutAll: (self at: 1). index := 2. [index <= self size] whileTrue: [ result nextPutAll: anOrderedCollection. result nextPutAll: (self at: index). index := index + 1. ]. ^ result contents This will clearly work not only for Strings but for other kinds of collections too. SplitJoinTest>>setUp eg := 'Now is the time for all good men to come to the aid of the party'. SplitJoinTest>>testJoin self assert: ((eg split: 'the') join: 'the') = eg. self assert: ({ {1. 2}. {4. 5} } asOrderedCollection join: {3}) = {1. 2. 3. 4. 5}. Is anyone convinced? Oscar On Sep 15, 2006, at 17:40, stephane ducasse wrote: > hi guys > > could you sit down and propose a cool set of names and > implementation and we include it in 3.10 > > http://bugs.impara.de/view.php?id=4874 > |
Free forum by Nabble | Edit this page |