As I was reading the latest entry in Brett Hallett's blog, titled "Rewriting a script into a callable method", I saw the code:
i := 20.
d := '0123456789abcdefghijklmnopqrstuvwxyz'.
l := d size.
s := String new: i.
1 to: i do: [ :x |
s at: x put: (d at: (Random between: 1 and: l))
].
s printNl.
This code didn't look very smalltalk-like to me. So I thought a bit about what was striking me odd, and it was all those explicit #at: and #at:put: calls. Not to mention confusing uses of "i" and "l" in a bad font. :)
The first two lines aren't bad. I'd keep them, although I'd probably name the values a bit more intention-revealing:
desiredLength := 20.
sourceCharacterSet := '0123456789abcdefghijklmnopqrstuvwxyz'.
But the rest of the code starts going a bit odd. Consider the expression:
d at: (Random between: 1 and: (d size))
(factoring out the temp variable). This is equivalent to simply:
d atRandom
And the loop there is collecting together "desiredLength" number of these random selections. So let's say that using a Collection-style method instead:
(1 to: desiredLength) collect: [:each | sourceCharacterSet atRandom]
We're now much closer to the result. The problem is that we now have an OrderedCollection of Characters, not a string. But a simple class-mapping will fix that, because Strings know how to create themselves from Collections of Characters:
((1 to: desiredLength) collect: [:each | sourceCharacterSet atRandom]) as: String
And there we have it. If #collect: didn't barf on a 0-arg block, we wouldn't need the misleading ":each" in there either. (Developed with
Squeak... not sure how unstandard this stuff is, or if it's just missing in GNU Smalltalk.)
Comments
why not using a single loop:
(String new: desiredLength) collect: [:each | sourceCharacterSet atRandom]
And it can confuse the newbie (will the String be modified in place?).
Take a look at: Matrix class>>#new:tabulate:
Second argument is a block (take two arguments, row and column indices).
We could have this selector in SequenceableCollection class too (with a single index).
#(1 4 9 16) is for example (Array new: 4 tabulate: [:index | index squared]).
And here:
String new: desiredLength tabulate: [:index | sourceCharacterSet atRandom].
Of course you would still prefer a zero argument block... What you eventually can test in #new:tabulate:
Ah, SequenceableCollection allSelectors size -> 749, too much is never enough, we always want to add some new!
Better call it
(String new: desiredLength generator: [sourceCharacterSet atRandom])
Speaking of misleading :each of #collect: , I have made #timesCollect: and used quite a lot.
Your last code will look like this if you use it.
(desiredLength timesCollect: [ sourceCharacterSet atRandom]) as: String
(1 to: desiredLength) inject: (String new: desiredLength) into: [:s :i | s at: i put: sourceCharacterSet atRandom ; yourself].
порно бесплатно, порно, бесплатное порно, порно ролики бесплатно, порно скачать бесплатно, порно онлайн, порно ролики онлайн
порно фото, эротика, порно фотографии, огромные сиськи, гламурная эротика, красивое порно фото
Бесплатное порно
Проститутки Москвы Взлом, хакеры, защита заработок в сети, форекс, инвестиции rihanna песни, rihanna клипы, rihanna фото белый каталог Рестораны в Москве, развлечения Москвы Игры, игровые новости Бесплатный белый каталог Фильмы онлайн