Pharo-dev
By thread
pharo-dev@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
November 2014
- 1013 messages
Re: [Pharo-dev] class variable slots?
by Tudor Girba
Hi Eliot,
Thanks. I know what class variables are, I was just asking if there is a
Slot-like meta-object in the implementation :).
Cheers,
Doru
On Wed, Nov 26, 2014 at 7:36 PM, Eliot Miranda <eliot.miranda(a)gmail.com>
wrote:
> Hi Tudor,
>
> On Wed, Nov 26, 2014 at 6:02 AM, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>
>> Hi,
>>
>> As far as I see, the class variables are not slots. Is that correct?
>>
>
> That's right. They're associations in class pools, and are visible in the
> instance-side and class-side methods of the class and all its subclasses.
> See Class>>bindingOf: and Class's inst var classPool. Shared pools are
> similar. A shared pool stores its variables in its class pool, but other
> classes can have its class vars in scope by including the shared pool in
> its pool dictionaries.
>
>
>> If not, how do I get the slots?
>>
>
> Well, just for clarity (at least I hope it'll bring clarity). One can
> access the variables via
>
> MyClass classPool associations
>
> Note that these are entirely different from class instance variables,
> which are inst var slots in the class object. These hold things like the
> class's superclass, its method dictionary, etc. But one can add inst vars
> to one's own class. There are many examples of this. Since these slots
> are per-class every class gets its own copy of the slot, and because these
> are inst vars, they are only in scope in class-side methods of the defining
> class and subclasses.
>
> HTH
>
>
>>
>> Cheers,
>> Doru
>>
>>
>> --
>> www.tudorgirba.com
>>
>> "Every thing has its own flow"
>>
>
>
>
> --
> best,
> Eliot
>
--
www.tudorgirba.com
"Every thing has its own flow"
Nov. 27, 2014
Re: [Pharo-dev] class variable slots?
by Tudor Girba
Hi,
Indeed, this is what I am looking for: a dedicated object representing the
class variable. This kind of objects become particularly useful in an
interface like the inspector because we can define dedicated views on them.
If they are generic associations or symbols, we cannot do much.
Cheers,
Doru
On Wed, Nov 26, 2014 at 9:10 PM, Marcus Denker <marcus.denker(a)inria.fr>
wrote:
>
> On 26 Nov 2014, at 19:36, Eliot Miranda <eliot.miranda(a)gmail.com> wrote:
>
> Hi Tudor,
>
> On Wed, Nov 26, 2014 at 6:02 AM, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>
>> Hi,
>>
>> As far as I see, the class variables are not slots. Is that correct?
>>
>
> That's right. They're associations in class pools, and are visible in the
> instance-side and class-side methods of the class and all its subclasses.
> See Class>>bindingOf: and Class's inst var classPool. Shared pools are
> similar. A shared pool stores its variables in its class pool, but other
> classes can have its class vars in scope by including the shared pool in
> its pool dictionaries.
>
>
>> If not, how do I get the slots?
>>
>
> Well, just for clarity (at least I hope it'll bring clarity). One can
> access the variables via
>
> MyClass classPool associations
>
> Note that these are entirely different from class instance variables,
> which are inst var slots in the class object. These hold things like the
> class's superclass, its method dictionary, etc. But one can add inst vars
> to one's own class. There are many examples of this. Since these slots
> are per-class every class gets its own copy of the slot, and because these
> are inst vars, they are only in scope in class-side methods of the defining
> class and subclasses.
>
>
> One we did for Pharo4 is to use the Associations of Globals to model these
> variables as meta-objects (in the same spirit as the Slot objects).
>
> Thos means that
> -> there is an Api to get them
> -> they have an API to read /write
>
> This is just âsugarâ on what the associations did already:
>
> global := SmalltalkImage classVariableNamed: #CompilerClass.
> global read.
> global class
> ==> ClassVariable
>
> Then, I added that the Compiler actually delegates code generation for
> read and write
> to these meta-objects, meaning you can subclass them and add special kinds
> of Globals
> with special semantics (just like Slot Subclasses). This could be used for
> e.g.active globals
> that announce when changed.
>
> But the real use-case for this is putting meta-links on these globals.
>
> e.g. add a class TT with class var T and a method that reads it.
>
>
> |link |
> link := MetaLink new
> metaObject: Halt;
> selector: #now.
>
> (TT classVariableNamed: #T) link: link.
>
> TT new readT
> -> halt.
>
> This means that we can out break-points on class variables (as opposed to
> a single read or write).
>
> This all needs a bit more work to be really usableâ¦
>
> Marcus
>
>
>
>
>
--
www.tudorgirba.com
"Every thing has its own flow"
Nov. 27, 2014
Re: [Pharo-dev] Stream instead of string concatenation
by Sven Van Caekenberghe
> On 27 Nov 2014, at 10:10, phil(a)highoctane.be wrote:
>
> I find myself using things like:
>
> 'Some {1} is going to {2} after {3}' seasideTranslated format: { anObject. 'crip', #crap }
I also use that often.
Yes, it is not very efficient, but it is high level and easy to use. In most cases that is more important.
It is only when you know that something is on a critical path that you have to think about performance.
Of course, for base classes in the system, the tradeoff can be different, efficiency in execution speed and memory usage (garbage creation) become more important.
> String>>format is
>
> format: collection
> "Format the receiver by interpolating elements from collection, as in the following examples:
> 'Today is {1}.' format: {Date today}.
> 'Today is {date}.' format: (Dictionary with: #date->Date today).
> 'In {1} you can escape \{ by prefixing it with \\' format: {'strings'}. "
>
> ^ self class new: self size streamContents: [ :result | | stream |
> stream := self readStream.
> [ stream atEnd ] whileFalse: [ | currentChar |
> (currentChar := stream next) == ${
> ifTrue: [ | expression index |
> expression := stream upTo: $}.
> index := Integer readFrom: expression ifFail: [ expression ].
> result nextPutAll: (collection at: index) asString ]
> ifFalse: [
> currentChar == $\
> ifTrue: [ stream atEnd ifFalse: [ result nextPut: stream next ] ]
> ifFalse: [ result nextPut: currentChar ] ] ] ]
>
> The code calls asString (which is nice) and Integer readFrom: which parses.
> It also uses nextPutAll:
>
> So a kind of mixed performance bag.
> Not to mention that there is the seasideTranslated lookup.
>
> Is there any best practice here? It is quite a common idiom I think.
>
> Phil
>
> On Thu, Nov 27, 2014 at 9:59 AM, stepharo <stepharo(a)free.fr> wrote:
> Sven started to write a chapter GoodPractice on PharoForTheEntreprise. If you want to imporve it just go.
>
> https://github.com/SquareBracketAssociates/PharoForTheEnterprise-english/tr…
>
> Stef
>
>
> !Some Good Coding Practices
>
> Best Smalltalk Practices by Kent Beck, Smalltalk by Example and Smalltalk with Style are three excellent books about coding practices. Every Smalltalkers should read them. Still there are some coding practices that programmers should be aware of.
>
> In this chapter we present some simple and good practices that make your code often more efficient and avoid generating unnecessary garbage.
>
> !!Avoid unnecessary string concatenations
>
> In Smalltalk, the message ==,== \mthindex{String}{,} concatenates two strings. It is handy but this message is really costly since it copies the receiver. Therefore avoid it as much as possible and especially in loop since it multiplies the effect.
>
> Prefer to use \ct{streamContents:} \mthindex{String}{streamContents:}, ==nextPut:== and ==nextPutAll:== since they avoid the duplication. The message ==streamContents:== expects a block would argument is a stream on the receiver.
>
> Let us have a look at the following code snippet.
> [[[
> String streamContents: [:s |
> #('Pharo''s' 'goal' 'is' 'to' 'deliver' 'a' 'clean,' 'innovative,' 'free' 'open-source' 'Smalltalk' 'environment.' 'By' 'providing' 'a' 'stable' 'and' 'small' 'core' 'system,' 'excellent' 'dev' 'tools,' 'and' 'maintained' 'releases,' 'Pharo' 'is' 'an' 'attractive' 'platform' 'to' 'build' 'and' 'deploy' 'mission' 'critical' 'Smalltalk' 'applications.')
> do: [:each | s nextPutAll: each; nextPut: Character space].
> s contents]
> ]]]
>
> Note that we took an example with many strings to stress the effect, but the bench results shows already a 4 factor.
>
> [[[
> [String streamContents: [:s |
> #('Pharo''s' 'goal' 'is' 'to' 'deliver' 'a' 'clean,' 'innovative,' 'free' 'open-source' 'Smalltalk' 'environment.' 'By' 'providing' 'a' 'stable' 'and' 'small' 'core' 'system,' 'excellent' 'dev' 'tools,' 'and' 'maintained' 'releases,' 'Pharo' 'is' 'an' 'attractive' 'platform' 'to' 'build' 'and' 'deploy' 'mission' 'critical' 'Smalltalk' 'applications.')
> do: [:each | s nextPutAll: each; nextPut: Character space].
> s contents]] bench
> --> '110,000 per second.'
>
> [| s|
> s := ''.
> #('Pharo''s' 'goal' 'is' 'to' 'deliver' 'a' 'clean,' 'innovative,' 'free' 'open-source' 'Smalltalk' 'environment.' 'By' 'providing' 'a' 'stable' 'and' 'small' 'core' 'system,' 'excellent' 'dev' 'tools,' 'and' 'maintained' 'releases,' 'Pharo' 'is' 'an' 'attractive' 'platform' 'to' 'build' 'and' 'deploy' 'mission' 'critical' 'Smalltalk' 'applications.')
> do: [:each | s := s , each , Character space asString].
> s ] bench
> --> '31,500 per second.'
> ]]]
>
>
>
> Another example that may be a bit draft and fuzzy but gives an idea of the cost that you may gain.
>
> [[[
> String streamContents: [:s |
> Smalltalk globals allClasses do: [:each |
> s nextPutAll: each name].
> s contents]] bench
> --> '246 per second.'
>
> | s |
> s := ''.
> [Smalltalk globals allClasses
> do: [:each | s := s, each name]] bench
> --> '2.01 per second.'
> ]]]
>
>
> !!!Preallocate when possible.
> Preallocate when possible the string used with\ct{new:streamContents:}. For example, the following method does not take advantage that the result is always a 8 characters string.
>
> [[[
> Time>>print24
> "Return as 8-digit string 'hh:mm:ss', with leading zeros if needed"
> ^String streamContents:
> [ :aStream | self print24: true on: aStream ]
> ]]]
>
> This version does the same but more efficiently, since the system does not have to reallocate the underlying buffer.
> [[[
> Time>>print24
> "Return as 8-digit string 'hh:mm:ss', with leading zeros if needed"
> ^ String new: 8 streamContents: [ :aStream |
> self print24: true on: aStream ]
> ]]]
>
> !!! Use ==nextPut:== when possible.
> When you can, use ==nextPut:== use it instead of ==nextPutAll:==. Indeed ==nextPutAll:== requires that the argument is a container of elements. When you have already the element, no need to create an extra container.
>
> For example better use the second form.
> [[[
> stream nextPutAll: '0'
> ]]]
>
> [[[
> stream nextPut: $0
> ]]]
>
>
> !!Avoid creating temporary objects
>
> The computation of minute in Time could be written as \ct{asDuration minutes}. However, this solution
> creates a duration object that is only used to get the minutes.
> In addition to be slow such approach generates extra garbage which stresses the garbage collector.
>
> [[[
> Time>>minute
> ^ self asDuration minutes
>
> Time>>asDuration
> "Answer the duration since midnight"
> ^ Duration seconds: seconds nanoSeconds: nanos
> ]]]
>
> A much better solution is to use the encapsulation of the class Time and performs the computation locally as
>
> [[[
> Time>>minute
> "Answer a number that represents the number of complete minutes in the receiver,
> after the number of complete hours has been removed."
> ^ (seconds rem: SecondsInHour) quo: SecondsInMinute
> ]]]
>
> !! Avoid several iterations on the same collection
> It may seem obvious but it is better to iterate once than two on the same collection, when we can do what we want in a single pass.
>
> For example, the following code creates a first string then creates another one where the character ==$:== is removed.
>
> [[[
> Time>>hhmm24
> "Return a string of the form 1123 (for 11:23 am), 2154 (for 9:54 pm), of exactly 4 digits"
> ^(String streamContents:
> [ :aStream | self print24: true showSeconds: false on: aStream ])
> copyWithout: $:
> ]]]
>
> Better implement it as
>
>
> [[[
> Time>>hhmm24
> "Return a string of the form 1123 (for 11:23 am), 2154 (for 9:54 pm), of exactly 4 digits"
> ^ String new: 4 streamContents: [ :aStream |
> self hour printOn: aStream base: 10 length: 2 padded: true.
> self minute printOn: aStream base: 10 length: 2 padded: true ]
> ]]]
>
>
> have a look at:
> http://www.slideshare.net/esug/design-principlesbehindpatagonia
>
>
> Le 27/11/14 09:22, Max Leske a écrit :
> On 26.11.2014, at 17:32, Ben Coman <btc(a)openInWorld.com> wrote:
>
> Yuriy Tymchuk wrote:
> Hi everyone!
> There is a Lint rule that suggests to use stream instead of strings concatenation. What is the most common way, to create a string this way, because the only thing I can come up with is:
> String streamContents: [ :stream |
> stream
> nextPutAll: 'Hello';
> nextPut: $ ;
> nextPutAll: 'Worldâ]
> But Iâm not sure if it is the preferred solution.
> Cheers
> Uko
> This is typical advise, but previous discussion found it to be not necessarily true.
>
> https://www.mail-archive.com/pharo-dev@lists.pharo.org/msg08162.html
>
> Very good advice, thanks Ben!
>
> Perhaps the rule should be ammended/deleted.
> Maybe a metric can be derived from Svenâs observations, e.g. âdonât apply if the strings are constantsâ etc. I donât think the rule should be deleted because in the general case itâs important to understand that streams can be more efficient.
>
> cheers -ben
>
>
>
>
>
>
>
Nov. 27, 2014
Re: [Pharo-dev] [SO] SSL exception with ZnSecureServer
by Sven Van Caekenberghe
Thanks!
> On 27 Nov 2014, at 10:02, phil(a)highoctane.be wrote:
>
> I have added an answer to the SO thread.
>
> Phil
>
> On Thu, Nov 27, 2014 at 9:54 AM, phil(a)highoctane.be <phil(a)highoctane.be> wrote:
> I tried the procedure and it works fine on my Ubuntu 14.04 LTS and Pharo 3.0
>
> Little script with the steps in attach.
>
> Server started as follows:
>
> (ZnSecureServer on: 1235)
> certificate: '/home/philippeback/.ssh/server.pem';
> logToTranscript;
> start;
> yourself.
>
> <image.png>
>
> Cool to have! The Z* things are really awesome and inspiring.
>
> Phil
>
>
> On Thu, Nov 27, 2014 at 9:29 AM, Sven Van Caekenberghe <sven(a)stfx.eu> wrote:
> I just sent the OP this in reply to a private message ;-)
>
>
> Hi Monty,
>
> It should work on Linux. This is how I once did it (making the certificate), more than a year ago (I know that others have managed to do this too):
>
> ====
>
> sven@netbook:~/ssl$ openssl genrsa -out privkey.pem 1024
> Generating RSA private key, 1024 bit long modulus
> ..........................................................++++++
> .++++++
> e is 65537 (0x10001)
> sven@netbook:~/ssl$ openssl req -new -key privkey.pem -out certreq.csr
> You are about to be asked to enter information that will be incorporated
> into your certificate request.
> What you are about to enter is what is called a Distinguished Name or a DN.
> There are quite a few fields but you can leave some blank
> For some fields there will be a default value,
> If you enter '.', the field will be left blank.
> -----
> Country Name (2 letter code) [AU]:BE
> State or Province Name (full name) [Some-State]:
> Locality Name (eg, city) []:Hasselt
> Organization Name (eg, company) [Internet Widgits Pty Ltd]:STfx.eu
> Organizational Unit Name (eg, section) []:
> Common Name (e.g. server FQDN or YOUR name) []:Sven Van Caekenberghe
> Email Address []:sven@stfx.eu
>
> Please enter the following 'extra' attributes
> to be sent with your certificate request
> A challenge password []:
> An optional company name []:
> sven@netbook:~/ssl$ ls
> certreq.csr privkey.pem
> sven@netbook:~/ssl$ openssl x509 -req -days 3650 -in certreq.csr -signkey privkey.pem -out newcert.pem
> Signature ok
> subject=/C=BE/ST=Some-State/L=Hasselt/O=STfx.eu/CN=Sven Van Caekenberghe/emailAddress=sven(a)stfx.eu
> Getting Private key
> sven@netbook:~/ssl$ ( openssl x509 -in newcert.pem; cat privkey.pem ) > server.pem
>
>
>
> (ZnSecureServer on: 1443)
> certificate: '/home/sven/ssl/server.pem';
> logToTranscript;
> start;
> yourself.
>
> ===
>
> HTH,
>
> Let me know when you get it working.
>
> Sven
>
> > On 27 Nov 2014, at 09:23, Max Leske <maxleske(a)gmail.com> wrote:
> >
> > http://stackoverflow.com/questions/27162749/znsecureserver-on-pharo3-0-on-u…
>
>
>
>
Nov. 27, 2014
Re: [Pharo-dev] changing MC repository url display
by stepharo
Le 24/11/14 14:28, Thierry Goubier a écrit :
> Hi Esteban,
>
> this is a good change, go on. And thanks for taking care of it!
+1
Go ahead
>
> Thierry
>
> 2014-11-24 14:09 GMT+01:00 Esteban Lorenzano <estebanlm(a)gmail.com
> <mailto:estebanlm@gmail.com>>:
>
> Hi,
>
> So I have this problem⦠each time I open a MC browser I see
> something like this:
>
>
> And as you can see⦠most important part of the repositories (the
> NAME) is hidded because window is small.
> Of course, I can enlarge the screen to see the names, but that
> made me think the way the information is presented is not good
> (because the place, sthub, ss, ss3 or whatever) is less important
> than the repository name.
> So I would like to change that to something like:
>
> Pharo/Pharo40 (smalltalkhub.com <http://smalltalkhub.com>)
> Pharo/Pharo40Inbox (smalltalkhub.com <http://smalltalkhub.com>)
> Moose/Glamour (smalltalkhub.com <http://smalltalkhub.com>)
> ./mc (filetree)
> VMMaker (source.squeak.org <http://source.squeak.org>)
> ⦠etcâ¦
>
> since this is a small change that has a huge visual impact, I
> would like to discuss it before.
> So, what do you think?
>
> Esteban
>
>
Nov. 27, 2014
Re: [Pharo-dev] Stream instead of string concatenation
by phil@highoctane.be
I find myself using things like:
'Some {1} is going to {2} after {3}' seasideTranslated format: { anObject.
'crip', #crap }
String>>format is
format: collection
"Format the receiver by interpolating elements from collection, as in the
following examples:
'Today is {1}.' format: {Date today}.
'Today is {date}.' format: (Dictionary with: #date->Date today).
'In {1} you can escape \{ by prefixing it with \\' format: {'strings'}. "
^ self class new: self size streamContents: [ :result | | stream |
stream := self readStream.
[ stream atEnd ] whileFalse: [ | currentChar |
(currentChar := stream next) == ${
ifTrue: [ | expression index |
expression := stream upTo: $}.
index := Integer readFrom: expression ifFail: [ expression ].
result nextPutAll: (collection at: index) asString ]
ifFalse: [
currentChar == $\
ifTrue: [ stream atEnd ifFalse: [ result nextPut: stream next ] ]
ifFalse: [ result nextPut: currentChar ] ] ] ]
The code calls asString (which is nice) and Integer readFrom: which parses.
It also uses nextPutAll:
So a kind of mixed performance bag.
Not to mention that there is the seasideTranslated lookup.
Is there any best practice here? It is quite a common idiom I think.
Phil
On Thu, Nov 27, 2014 at 9:59 AM, stepharo <stepharo(a)free.fr> wrote:
> Sven started to write a chapter GoodPractice on PharoForTheEntreprise. If
> you want to imporve it just go.
>
> https://github.com/SquareBracketAssociates/PharoForTheEnterprise-english/
> tree/master/GoodPractices
>
> Stef
>
>
> !Some Good Coding Practices
>
> Best Smalltalk Practices by Kent Beck, Smalltalk by Example and Smalltalk
> with Style are three excellent books about coding practices. Every
> Smalltalkers should read them. Still there are some coding practices that
> programmers should be aware of.
>
> In this chapter we present some simple and good practices that make your
> code often more efficient and avoid generating unnecessary garbage.
>
> !!Avoid unnecessary string concatenations
>
> In Smalltalk, the message ==,== \mthindex{String}{,} concatenates two
> strings. It is handy but this message is really costly since it copies the
> receiver. Therefore avoid it as much as possible and especially in loop
> since it multiplies the effect.
>
> Prefer to use \ct{streamContents:} \mthindex{String}{streamContents:},
> ==nextPut:== and ==nextPutAll:== since they avoid the duplication. The
> message ==streamContents:== expects a block would argument is a stream on
> the receiver.
>
> Let us have a look at the following code snippet.
> [[[
> String streamContents: [:s |
> #('Pharo''s' 'goal' 'is' 'to' 'deliver' 'a' 'clean,' 'innovative,' 'free'
> 'open-source' 'Smalltalk' 'environment.' 'By' 'providing' 'a' 'stable'
> 'and' 'small' 'core' 'system,' 'excellent' 'dev' 'tools,' 'and'
> 'maintained' 'releases,' 'Pharo' 'is' 'an' 'attractive' 'platform' 'to'
> 'build' 'and' 'deploy' 'mission' 'critical' 'Smalltalk' 'applications.')
> do: [:each | s nextPutAll: each; nextPut: Character space].
> s contents]
> ]]]
>
> Note that we took an example with many strings to stress the effect, but
> the bench results shows already a 4 factor.
>
> [[[
> [String streamContents: [:s |
> #('Pharo''s' 'goal' 'is' 'to' 'deliver' 'a' 'clean,' 'innovative,' 'free'
> 'open-source' 'Smalltalk' 'environment.' 'By' 'providing' 'a' 'stable'
> 'and' 'small' 'core' 'system,' 'excellent' 'dev' 'tools,' 'and'
> 'maintained' 'releases,' 'Pharo' 'is' 'an' 'attractive' 'platform' 'to'
> 'build' 'and' 'deploy' 'mission' 'critical' 'Smalltalk' 'applications.')
> do: [:each | s nextPutAll: each; nextPut: Character space].
> s contents]] bench
> --> '110,000 per second.'
>
> [| s|
> s := ''.
> #('Pharo''s' 'goal' 'is' 'to' 'deliver' 'a' 'clean,' 'innovative,' 'free'
> 'open-source' 'Smalltalk' 'environment.' 'By' 'providing' 'a' 'stable'
> 'and' 'small' 'core' 'system,' 'excellent' 'dev' 'tools,' 'and'
> 'maintained' 'releases,' 'Pharo' 'is' 'an' 'attractive' 'platform' 'to'
> 'build' 'and' 'deploy' 'mission' 'critical' 'Smalltalk' 'applications.')
> do: [:each | s := s , each , Character space asString].
> s ] bench
> --> '31,500 per second.'
> ]]]
>
>
>
> Another example that may be a bit draft and fuzzy but gives an idea of the
> cost that you may gain.
>
> [[[
> String streamContents: [:s |
> Smalltalk globals allClasses do: [:each |
> s nextPutAll: each name].
> s contents]] bench
> --> '246 per second.'
>
> | s |
> s := ''.
> [Smalltalk globals allClasses
> do: [:each | s := s, each name]] bench
> --> '2.01 per second.'
> ]]]
>
>
> !!!Preallocate when possible.
> Preallocate when possible the string used with\ct{new:streamContents:}.
> For example, the following method does not take advantage that the result
> is always a 8 characters string.
>
> [[[
> Time>>print24
> "Return as 8-digit string 'hh:mm:ss', with leading zeros if needed"
> ^String streamContents:
> [ :aStream | self print24: true on: aStream ]
> ]]]
>
> This version does the same but more efficiently, since the system does not
> have to reallocate the underlying buffer.
> [[[
> Time>>print24
> "Return as 8-digit string 'hh:mm:ss', with leading zeros if needed"
> ^ String new: 8 streamContents: [ :aStream |
> self print24: true on: aStream ]
> ]]]
>
> !!! Use ==nextPut:== when possible.
> When you can, use ==nextPut:== use it instead of ==nextPutAll:==. Indeed
> ==nextPutAll:== requires that the argument is a container of elements. When
> you have already the element, no need to create an extra container.
>
> For example better use the second form.
> [[[
> stream nextPutAll: '0'
> ]]]
>
> [[[
> stream nextPut: $0
> ]]]
>
>
> !!Avoid creating temporary objects
>
> The computation of minute in Time could be written as \ct{asDuration
> minutes}. However, this solution
> creates a duration object that is only used to get the minutes.
> In addition to be slow such approach generates extra garbage which
> stresses the garbage collector.
>
> [[[
> Time>>minute
> ^ self asDuration minutes
>
> Time>>asDuration
> "Answer the duration since midnight"
> ^ Duration seconds: seconds nanoSeconds: nanos
> ]]]
>
> A much better solution is to use the encapsulation of the class Time and
> performs the computation locally as
>
> [[[
> Time>>minute
> "Answer a number that represents the number of complete minutes in the
> receiver,
> after the number of complete hours has been removed."
> ^ (seconds rem: SecondsInHour) quo: SecondsInMinute
> ]]]
>
> !! Avoid several iterations on the same collection
> It may seem obvious but it is better to iterate once than two on the same
> collection, when we can do what we want in a single pass.
>
> For example, the following code creates a first string then creates
> another one where the character ==$:== is removed.
>
> [[[
> Time>>hhmm24
> "Return a string of the form 1123 (for 11:23 am), 2154 (for 9:54 pm),
> of exactly 4 digits"
> ^(String streamContents:
> [ :aStream | self print24: true showSeconds: false on: aStream ])
> copyWithout: $:
> ]]]
>
> Better implement it as
>
>
> [[[
> Time>>hhmm24
> "Return a string of the form 1123 (for 11:23 am), 2154 (for 9:54 pm),
> of exactly 4 digits"
> ^ String new: 4 streamContents: [ :aStream |
> self hour printOn: aStream base: 10 length: 2 padded: true.
> self minute printOn: aStream base: 10 length: 2 padded: true ]
> ]]]
>
>
> have a look at:
> http://www.slideshare.net/esug/design-principlesbehindpatagonia
>
>
> Le 27/11/14 09:22, Max Leske a écrit :
>
>> On 26.11.2014, at 17:32, Ben Coman <btc(a)openInWorld.com> wrote:
>>>
>>> Yuriy Tymchuk wrote:
>>>
>>>> Hi everyone!
>>>> There is a Lint rule that suggests to use stream instead of strings
>>>> concatenation. What is the most common way, to create a string this way,
>>>> because the only thing I can come up with is:
>>>> String streamContents: [ :stream |
>>>> stream
>>>> nextPutAll: 'Hello';
>>>> nextPut: $ ;
>>>> nextPutAll: 'Worldâ]
>>>> But Iâm not sure if it is the preferred solution.
>>>> Cheers
>>>> Uko
>>>>
>>> This is typical advise, but previous discussion found it to be not
>>> necessarily true.
>>>
>>> https://www.mail-archive.com/pharo-dev@lists.pharo.org/msg08162.html
>>>
>>> Very good advice, thanks Ben!
>>
>> Perhaps the rule should be ammended/deleted.
>>>
>> Maybe a metric can be derived from Svenâs observations, e.g. âdonât apply
>> if the strings are constantsâ etc. I donât think the rule should be deleted
>> because in the general case itâs important to understand that streams can
>> be more efficient.
>>
>> cheers -ben
>>>
>>>
>>>
>>
>>
>
>
Nov. 27, 2014
Re: [Pharo-dev] class variable slots?
by stepharo
>>
>> but I do not get why a class variable is accessed as a global.
>
> It is not. You have to ask the class for the class variable:
>
> SmalltalkImage classVariableNamed: #CompilerClass.
>
> This returns the class variable âCompilerClassâ of class SmalltalkImage.
ahhhh ok
>
>
>> To me it looks plain wrong.
>> A class variable is like a shared variable between classes. In Clos
>> it was the same as an instance variable but with a class scope.
>> So could not we make that nicer.
>> I really find terrible and an attack against modularity to have them
>> managed that way.
>
> Which way?
>
> ah, I think my example was a bad one: I used SmalltalkIamge as it is
> the class that comes to my mind that uses logs
> of class variables. I do not ask the global namespace anything,
>
> e.g. make a case TT with class var T and it is
>
> TT classVariableNamed: #T
>
> The variable is *not* global. Itâs a class variable.
Ok we are safe :)
>
> Marcus
>
>
>
Nov. 27, 2014
Re: [Pharo-dev] Athens Repository (NativeBoost)
by stepharo
> Yes, that would be nice.
>
> For your fixes I waited actually for Igor to react. (I think I even
> did send him a mail after waiting for some weeks). After that, I
> decided it was better
> to add the changes to Pharo than to risk loosing you as a contributor
> because we ignore your contributions.
+1
>
> Marcus
Nov. 27, 2014
Re: [Pharo-dev] [SO] SSL exception with ZnSecureServer
by phil@highoctane.be
I have added an answer to the SO thread.
Phil
On Thu, Nov 27, 2014 at 9:54 AM, phil(a)highoctane.be <phil(a)highoctane.be>
wrote:
> I tried the procedure and it works fine on my Ubuntu 14.04 LTS and Pharo
> 3.0
>
> Little script with the steps in attach.
>
> Server started as follows:
>
> (ZnSecureServer on: 1235)
> certificate: '/home/philippeback/.ssh/server.pem';
> logToTranscript;
> start;
> yourself.
>
> [image: Inline image 1]
>
> Cool to have! The Z* things are really awesome and inspiring.
>
> Phil
>
>
> On Thu, Nov 27, 2014 at 9:29 AM, Sven Van Caekenberghe <sven(a)stfx.eu>
> wrote:
>
>> I just sent the OP this in reply to a private message ;-)
>>
>>
>> Hi Monty,
>>
>> It should work on Linux. This is how I once did it (making the
>> certificate), more than a year ago (I know that others have managed to do
>> this too):
>>
>> ====
>>
>> sven@netbook:~/ssl$ openssl genrsa -out privkey.pem 1024
>> Generating RSA private key, 1024 bit long modulus
>> ..........................................................++++++
>> .++++++
>> e is 65537 (0x10001)
>> sven@netbook:~/ssl$ openssl req -new -key privkey.pem -out certreq.csr
>> You are about to be asked to enter information that will be incorporated
>> into your certificate request.
>> What you are about to enter is what is called a Distinguished Name or a
>> DN.
>> There are quite a few fields but you can leave some blank
>> For some fields there will be a default value,
>> If you enter '.', the field will be left blank.
>> -----
>> Country Name (2 letter code) [AU]:BE
>> State or Province Name (full name) [Some-State]:
>> Locality Name (eg, city) []:Hasselt
>> Organization Name (eg, company) [Internet Widgits Pty Ltd]:STfx.eu
>> Organizational Unit Name (eg, section) []:
>> Common Name (e.g. server FQDN or YOUR name) []:Sven Van Caekenberghe
>> Email Address []:sven@stfx.eu
>>
>> Please enter the following 'extra' attributes
>> to be sent with your certificate request
>> A challenge password []:
>> An optional company name []:
>> sven@netbook:~/ssl$ ls
>> certreq.csr privkey.pem
>> sven@netbook:~/ssl$ openssl x509 -req -days 3650 -in certreq.csr
>> -signkey privkey.pem -out newcert.pem
>> Signature ok
>> subject=/C=BE/ST=Some-State/L=Hasselt/O=STfx.eu/CN=Sven Van
>> Caekenberghe/emailAddress=sven(a)stfx.eu
>> Getting Private key
>> sven@netbook:~/ssl$ ( openssl x509 -in newcert.pem; cat privkey.pem ) >
>> server.pem
>>
>>
>>
>> (ZnSecureServer on: 1443)
>> certificate: '/home/sven/ssl/server.pem';
>> logToTranscript;
>> start;
>> yourself.
>>
>> ===
>>
>> HTH,
>>
>> Let me know when you get it working.
>>
>> Sven
>>
>> > On 27 Nov 2014, at 09:23, Max Leske <maxleske(a)gmail.com> wrote:
>> >
>> >
>> http://stackoverflow.com/questions/27162749/znsecureserver-on-pharo3-0-on-u…
>>
>>
>>
>
Nov. 27, 2014
Re: [Pharo-dev] Athens Repository (NativeBoost)
by stepharo
> The fact that Athens are part of Pharo distribution don't means,
> that its repository should be abandoned and all updates should
> come directly to Pharo. That would be a huge mistake.
>
>
> That's how I've done it recently.
>
> I'll merge the changes from pharo -> athens repository.
Thanks for doing that!
>
> Doing everything in a monolithic image is a planning mess, and
> works fine only for bug fixing or small refactorings.
>
> Anything which requires sizable planning and designing, should
> have own line of development and maintenance,
> like that there's a clear separation of the responsibility for
> maintaining the project in healthy state and less bottlenecks.
>
>
> no idea⦠I guess is the same case, but I have no control over
> that area.
> Igor will know better :)
>
> Esteban
>
>
>
>
> --
> Best regards,
> Igor Stasenko.
>
>
Nov. 27, 2014