Pharo-dev
By thread
pharo-dev@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- August
- 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
- 3 participants
- 144615 messages
Re: [Pharo-dev] slow Pharo downloading and Travis
by Stephane Ducasse
We opened a new ticket.
On Tue, Sep 26, 2017 at 8:45 PM, Gabriel Cotelli <g.cotelli(a)gmail.com> wrote:
> I'm willing to do some other specific tests if needed. Just let me know.
>
> On Tue, Sep 26, 2017 at 3:36 PM, Stephane Ducasse <stepharo.self(a)gmail.com>
> wrote:
>>
>> Thanks Gabriel I forwarded this to christophe.
>>
>> On Tue, Sep 26, 2017 at 12:01 AM, Gabriel Cotelli <g.cotelli(a)gmail.com>
>> wrote:
>> > Still really slow from Argentina.
>> >
>> > In case it helps
>> >
>> > traceroute files.pharo.org
>> > traceroute to files.pharo.org (128.93.162.72), 30 hops max, 60 byte
>> > packets
>> > 1 192.168.1.1 (192.168.1.1) 0.574 ms 0.968 ms 1.538 ms
>> > 2 192.168.0.1 (192.168.0.1) 2.048 ms 2.499 ms 2.847 ms
>> > 3 10.33.32.1 (10.33.32.1) 12.264 ms 14.160 ms 14.336 ms
>> > 4 10.242.2.161 (10.242.2.161) 14.522 ms 14.643 ms 16.497 ms
>> > 5 telecentro.baires3.bai.seabone.net (195.22.220.33) 18.936 ms
>> > 19.575 ms
>> > 18.843 ms
>> > 6 ae0.baires3.bai.seabone.net (195.22.220.32) 19.554 ms 10.675 ms
>> > 13.028 ms
>> > 7 et10-1-0.miami15.mia.seabone.net (89.221.41.175) 246.284 ms
>> > et9-3-0.miami15.mia.seabone.net (195.22.199.179) 246.214 ms
>> > et4-3-0.miami15.mia.seabone.net (195.22.199.177) 246.137 ms
>> > 8 gtt.miami15.mia.seabone.net (89.221.41.197) 245.909 ms 245.924 ms
>> > 245.870 ms
>> > 9 xe-3-1-2.cr0-par7.ip4.gtt.net (141.136.109.18) 251.632 ms 274.447
>> > ms
>> > 250.097 ms
>> > 10 renater-gw-ix1.gtt.net (77.67.123.206) 281.025 ms 259.509 ms
>> > 261.717
>> > ms
>> > 11 * * *
>> > 12 inria-rocquencourt-te1-4-inria-rtr-021.noc.renater.fr
>> > (193.51.184.177)
>> > 271.263 ms 307.011 ms 306.876 ms
>> > 13 * * *
>> > 14 * * *
>> > 15 * * *
>> > 16 * * *
>> > 17 * * *
>> > 18 * * *
>> > 19 * * *
>> > 20 * * *
>> > 21 * * *
>> > 22 * * *
>> > 23 * * *
>> > 24 * * *
>> > 25 * * *
>> > 26 * * *
>> > 27 * * *
>> > 28 * * *
>> > 29 * * *
>> > 30 * * *
>> >
>> > httping -g http://files.pharo.org/get-files/61/pharo64.zip -c 20
>> > PING files.pharo.org:80 (/get-files/61/pharo64.zip):
>> > connected to 128.93.162.72:80 (256 bytes), seq=0 time=625,90 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=1 time=842,02 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=2 time=638,83 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=3 time=637,63 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=4 time=637,85 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=5 time=580,27 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=6 time=1207,98 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=7 time=638,13 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=8 time=637,74 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=9 time=582,59 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=10 time=658,11 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=11 time=673,84 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=12 time=584,44 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=13 time=691,84 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=14 time=637,20 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=15 time=861,84 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=16 time=619,45 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=17 time=638,03 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=18 time=638,11 ms
>> > connected to 128.93.162.72:80 (256 bytes), seq=19 time=741,01 ms
>> > --- http://files.pharo.org/get-files/61/pharo64.zip ping statistics ---
>> > 20 connects, 20 ok, 0,00% failed, time 33781ms
>> > round-trip min/avg/max = 580,3/688,6/1208,0 ms
>> >
>> >
>> > On Thu, Sep 21, 2017 at 12:13 PM, Ben Coman <btc(a)openinworld.com> wrote:
>> >>
>> >> Still seems a bit slow...
>> >> http://files.pharo.org/get-files/70/pharo64.zip
>> >> 16MB ==> 10 minutes (and actually it stalled after 3.4MB downloaded)
>> >> Local speed test: 40Mb/s down, 20Mb/s up
>> >>
>> >> but then I'm a long way across the internet, the cause could be
>> >> anywhere...
>> >> $ traceroute files.pharo.org
>> >> traceroute to files.pharo.org (128.93.162.72), 30 hops max, 60 byte
>> >> packets
>> >> 1 192.168.43.1 (192.168.43.1) 2.040 ms 2.403 ms 4.222 ms
>> >> 2 * * *
>> >> 3 * * *
>> >> 4 Bundle-Ether14.wel-edge901.perth.telstra.net (139.130.16.49)
>> >> 67.741
>> >> ms 67.739 ms 67.730 ms
>> >> 5 bundle-ether6.wel-core3.perth.telstra.net (203.50.6.214) 67.696 ms
>> >> 67.697 ms 67.697 ms
>> >> 6 bundle-ether7.fli-core1.adelaide.telstra.net (203.50.11.18) 95.723
>> >> ms
>> >> 91.753 ms 100.574 ms
>> >> 7 bundle-ether9.win-core10.melbourne.telstra.net (203.50.11.91)
>> >> 106.550
>> >> ms 108.849 ms 108.851 ms
>> >> 8 bundle-ether12.ken-core10.sydney.telstra.net (203.50.11.122)
>> >> 117.770
>> >> ms 117.767 ms 117.751 ms
>> >> 9 bundle-ether1.pad-gw11.sydney.telstra.net (203.50.6.61) 117.720 ms
>> >> 103.603 ms 102.171 ms
>> >> 10 bundle-ether1.sydp-core04.sydney.reach.com (203.50.13.90) 93.276
>> >> ms
>> >> 95.822 ms 102.577 ms
>> >> 11 i-52.tlot-core02.bx.telstraglobal.net (202.84.137.101) 330.128 ms
>> >> 321.231 ms 322.522 ms
>> >> 12 i-0-4-0-10.tlot-core01.bi.telstraglobal.net (202.84.253.21)
>> >> 321.187
>> >> ms i-0-2-0-10.tlot-core01.bi.telstraglobal.net (202.40.149.181)
>> >> 321.181 ms
>> >> i-0-2-0-9.tlot-core01.bi.telstraglobal.net (202.40.149.177) 308.786 ms
>> >> 13 gtt-peer.tlot02.pr.telstraglobal.net (134.159.63.182) 273.784 ms
>> >> 283.530 ms 281.079 ms
>> >> 14 xe-1-2-0.cr0-par7.ip4.gtt.net (89.149.185.53) 466.648 ms 479.910
>> >> ms
>> >> 481.254 ms
>> >> 15 renater-gw-ix1.gtt.net (77.67.123.206) 479.900 ms 479.882 ms
>> >> 478.641 ms
>> >> 16 * * *
>> >> 17 inria-rocquencourt-te1-4-inria-rtr-021.noc.renater.fr
>> >> (193.51.184.177)
>> >> 436.776 ms 479.819 ms 478.907 ms
>> >> 18 * * *
>> >> 19 * * *
>> >>
>> >> $ httping -h files.pharo.org
>> >> PING files.pharo.org:80 (http://files.pharo.org:80/)
>> >> connected to 128.93.162.72:80 (169 bytes), seq=0 time=970.27 ms
>> >> connected to 128.93.162.72:80 (169 bytes), seq=1 time=928.26 ms
>> >> connected to 128.93.162.72:80 (169 bytes), seq=2 time=860.06 ms
>> >> connected to 128.93.162.72:80 (169 bytes), seq=3 time=976.04 ms
>> >> connected to 128.93.162.72:80 (169 bytes), seq=4 time=1238.72 ms
>> >> connected to 128.93.162.72:80 (169 bytes), seq=5 time=1239.65 ms
>> >> connected to 128.93.162.72:80 (169 bytes), seq=6 time=918.06 ms
>> >>
>> >>
>> >> cheers -ben
>> >>
>> >> On Thu, Sep 21, 2017 at 5:43 PM, Marcus Denker <marcus.denker(a)inria.fr>
>> >> wrote:
>> >>>
>> >>>
>> >>> > On 18 Sep 2017, at 08:37, Marcus Denker <marcus.denker(a)inria.fr>
>> >>> > wrote:
>> >>> >
>> >>> >
>> >>> >> On 16 Sep 2017, at 09:40, Stephane Ducasse
>> >>> >> <stepharo.self(a)gmail.com>
>> >>> >> wrote:
>> >>> >>
>> >>> >> Hi marcus
>> >>> >>
>> >>> >> I do not see why they could not find it.
>> >>> >> Can you tell me how you ask because we should reask?
>> >>> >>
>> >>> >>
>> >>> >
>> >>> > I spend a ticket and they wanted to close it last week. I have told
>> >>> > them to not close it
>> >>> >
>> >>> The problems seems to be fixed now.
>> >>>
>> >>> If someone sees any slowness -> send me a mail.
>> >>>
>> >>> Marcus
>> >>>
>> >>>
>> >>
>> >
>>
>
Sept. 28, 2017
Re: [Pharo-dev] Epicea wishlist
by Stephane Ducasse
Tx Martin.
On Thu, Sep 28, 2017 at 4:33 PM, Martin Dias <tinchodias(a)gmail.com> wrote:
> Stef, ok I add your request in the issue tracker:
>
> https://pharo.fogbugz.com/f/cases/20474/Epicea-Keep-filter-across-session-i…
>
> It's kind of funny because the filters were kept across seassions and I
> *intentionally* added the filter cleaning when session selection changes.
> IMO it was misleading to keep them as you want, but also I understand your
> point... I think moving the filters widget to other place in the window can
> do it.
>
> MartÃn
>
> On Thu, Sep 7, 2017 at 3:15 AM, Stephane Ducasse <stepharo.self(a)gmail.com>
> wrote:
>>
>> Hi martin
>>
>> I'm missing two features:
>>
>> - keep the filter across session because this is boring to have to
>> redo them all over.
>> - a search for entities accross session.
>> - a search inside a session
>> For example I was looking for all the changes I did to the UI part of
>> my application but I was doing many development
>> loading different unrelated package and saving after.
>>
>> Right now you can restrict to view changes but only if you have a
>> first entity of the package for example so you have to look first is
>> there an entity of this package.
>>
>> Stef
>>
>
Sept. 28, 2017
Re: [Pharo-dev] Call for little tasks for GCI
by phil@highoctane.be
What about
LD_LIBRARY_PATH=<sqlite3place>;$LD_LIBRARYPATH ./pharo-ui some.image
Phil
On Thu, Sep 28, 2017 at 7:41 PM, Jigyasa Grover <grover.jigyasa1(a)gmail.com>
wrote:
> Hello hernanmd,
>
> Please check out the link to the repository
> (github.com/jigyasa-grover/GCI-2017-with-Pharo) it should work for you, I
> added you as a collaborator.
>
> For more details on the contest and type of tasks to be created, please
> refer:
> 1. Resources in the repository
> 2. Invitation Letter
> (http://forum.world.st/Let-s-prepare-for-Google-Code-In-
> 2017-with-Pharo-Consortium-td4966890.html)
>
> Looking forward to significant contributions from your side !
>
> Best Regrads
> Jigyasa Grover
>
>
>
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html
>
>
Sept. 28, 2017
Re: [Pharo-dev] Call for little tasks for GCI
by Jigyasa Grover
Hello hernanmd,
Please check out the link to the repository
(github.com/jigyasa-grover/GCI-2017-with-Pharo) it should work for you, I
added you as a collaborator.
For more details on the contest and type of tasks to be created, please
refer:
1. Resources in the repository
2. Invitation Letter
(http://forum.world.st/Let-s-prepare-for-Google-Code-In-2017-with-Pharo-Cons…)
Looking forward to significant contributions from your side !
Best Regrads
Jigyasa Grover
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html
Sept. 28, 2017
Re: [Pharo-dev] String Interpolation
by Sven Van Caekenberghe
> On 28 Sep 2017, at 18:50, Nicolas Cellier <nicolas.cellier.aka.nice(a)gmail.com> wrote:
>
>
>
> 2017-09-28 16:20 GMT+02:00 Sven Van Caekenberghe <sven(a)stfx.eu>:
> Hi,
>
> I got into a little office discussion about string interpolation as it is done in different programming languages.
>
> In Pharo we have String>>#format: which is pretty nice. It works as follows:
>
> | x y |
> x := 123.
> y := #foo.
> 'x={1} and y={2}' format: { x. y }.
>
> It is also possible to use a dictionary with keys, like this:
>
> | x y |
> x := 123.
> y := #foo.
> 'x={x} and y={y}' format: { #x->x. #y->y } asDictionary.
>
> But this is not true string interpolation as described in [ https://en.wikipedia.org/wiki/String_interpolation ]. The idea is to write the value generating expressions directly inside the strings.
>
> Since in Pharo we add features not by extending the syntax but by adding messages I wondered if it could be done for string interpolation. The goal is to make the following work:
>
> | x y |
> x := 123.
> y := #foo.
> 'It seems x equals {x} and y equals {y} while Pi is still {Float pi}' interpolate.
>
> => 'It seems x equals 123 and y equals foo while Pi is still 3.141592653589793'
>
> Here is the implementation I came up with:
>
> String>>#interpolate
> "Format the receiver by interpolating the evaluation of expressions
> in between curly brackets in the context of the sender as in the following 3 oneline examples.
> 'Today is {Date today}' interpolate.
> | x | x := 123. 'x equals {x} and pi equals {Float pi}' interpolate.
> 'In {#strings} you can escape \{ by prefixing it with \\' interpolate."
>
> | senderContext |
> senderContext := thisContext sender.
> ^ self class new: self size streamContents: [ :out | | stream |
> stream := self readStream.
> [ stream atEnd ] whileFalse: [ | currentChar |
> (currentChar := stream next) == ${
> ifTrue: [ | expression result |
> expression := stream upTo: $}.
> result := Compiler new
> evaluate: expression in: senderContext to: nil notifying: nil ifFail: [ ^ nil ] logged: false.
> out nextPutAll: result asString ]
> ifFalse: [
> currentChar == $\
> ifTrue: [ stream atEnd ifFalse: [ out nextPut: stream next ] ]
> ifFalse: [ out nextPut: currentChar ] ] ] ]
>
> It is a hack that could certainly be improved. And there is of course an obvious security problem.
>
> Thoughts ?
>
> Sven
>
>
> Nice!
> The only objection I see is that it may fail in blocks if they don't know that they have to refer to outer context, especially once we have clean blocks
Yes, there are probably some edge cases. Error handling is tricky too.
> | outer |
> outer := 'foobar'.
> ^#( 1 2 3 ) collect: [:x | 'loop on value {x} in {outer}' interpolate]
That example works for me in a Playground. How does it fail for you ?
Sept. 28, 2017
Re: [Pharo-dev] String Interpolation
by Nicolas Cellier
2017-09-28 16:20 GMT+02:00 Sven Van Caekenberghe <sven(a)stfx.eu>:
> Hi,
>
> I got into a little office discussion about string interpolation as it is
> done in different programming languages.
>
> In Pharo we have String>>#format: which is pretty nice. It works as
> follows:
>
> | x y |
> x := 123.
> y := #foo.
> 'x={1} and y={2}' format: { x. y }.
>
> It is also possible to use a dictionary with keys, like this:
>
> | x y |
> x := 123.
> y := #foo.
> 'x={x} and y={y}' format: { #x->x. #y->y } asDictionary.
>
> But this is not true string interpolation as described in [
> https://en.wikipedia.org/wiki/String_interpolation ]. The idea is to
> write the value generating expressions directly inside the strings.
>
> Since in Pharo we add features not by extending the syntax but by adding
> messages I wondered if it could be done for string interpolation. The goal
> is to make the following work:
>
> | x y |
> x := 123.
> y := #foo.
> 'It seems x equals {x} and y equals {y} while Pi is still {Float pi}'
> interpolate.
>
> => 'It seems x equals 123 and y equals foo while Pi is still
> 3.141592653589793'
>
> Here is the implementation I came up with:
>
> String>>#interpolate
> "Format the receiver by interpolating the evaluation of expressions
> in between curly brackets in the context of the sender as in the
> following 3 oneline examples.
> 'Today is {Date today}' interpolate.
> | x | x := 123. 'x equals {x} and pi equals {Float pi}' interpolate.
> 'In {#strings} you can escape \{ by prefixing it with \\' interpolate."
>
> | senderContext |
> senderContext := thisContext sender.
> ^ self class new: self size streamContents: [ :out | | stream |
> stream := self readStream.
> [ stream atEnd ] whileFalse: [ | currentChar |
> (currentChar := stream next) == ${
> ifTrue: [ | expression result |
> expression := stream upTo: $}.
> result := Compiler new
> evaluate: expression in: senderContext to: nil notifying:
> nil ifFail: [ ^ nil ] logged: false.
> out nextPutAll: result asString ]
> ifFalse: [
> currentChar == $\
> ifTrue: [ stream atEnd ifFalse: [ out nextPut: stream next ]
> ]
> ifFalse: [ out nextPut: currentChar ] ] ] ]
>
> It is a hack that could certainly be improved. And there is of course an
> obvious security problem.
>
> Thoughts ?
>
> Sven
>
>
Nice!
The only objection I see is that it may fail in blocks if they don't know
that they have to refer to outer context, especially once we have clean
blocks
| outer |
outer := 'foobar'.
^#( 1 2 3 ) collect: [:x | 'loop on value {x} in {outer}' interpolate]
Sept. 28, 2017
Re: [Pharo-dev] [Ann] Class meta annotations
by Denis Kudriashov
2017-09-28 18:17 GMT+02:00 Denis Kudriashov <dionisiydk(a)gmail.com>:
> 2017-09-25 17:57 GMT+02:00 Denis Kudriashov <dionisiydk(a)gmail.com>:
>
>> 2017-09-25 17:38 GMT+02:00 Stephane Ducasse <stepharo.self(a)gmail.com>:
>>
>>> I agree with guille. We should just called them class annotations.
>>>
>>> Denis what is a declared instance (is it an object returned by the
>>> method having the annotation)
>>> but can we find a better name.
>>>
>>
>> My idea that the method with pragma #classMetaAnnotation is the
>> declaration of annotation. Internally this declaration creates instance of
>> specified annotation which cached by system. And users access all these
>> declared instances for reflection purposes.
>>
>>
> Maybe #registeredInstances would be better?
>
So I rename these messages too. I think it's better.
>
>> Also annotation has inst var declarationSelector.
>>
>
>>
>>> may be effectiveInstances?
>>>
>>
>> I don't like this name. I not understand "effective" in that context.
>>
>>
>>>
>>>
>>> On Mon, Sep 25, 2017 at 5:09 PM, Guillermo Polito <
>>> guillermopolito(a)gmail.com> wrote:
>>>
>>>> Why calling them meta-annotation and not just annotation? Annotations
>>>> are in general already meta :)
>>>>
>>>> On Mon, Sep 25, 2017 at 5:01 PM, Denis Kudriashov <dionisiydk(a)gmail.com
>>>> > wrote:
>>>>
>>>>> Hi.
>>>>>
>>>>> I glad to present one class package which introduces reusable
>>>>> mechanism for first class annotations.
>>>>>
>>>>> The project can be found on github https://github.com/dion
>>>>> isiydk/ClassMetaAnnotation.
>>>>> And I tried to describe why it is needed in my blog
>>>>> http://dionisiydk.blogspot.fr/2017/09/class-meta-annotations.html.
>>>>>
>>>>> And here is overview:
>>>>>
>>>>> Every annotation should be subclass of ClassMetaAnnotation. To attach
>>>>> it to class you create new class side method which will return an instance
>>>>> of the annotation. Method should be marked with pragma #classMetaAnnotation:
>>>>>
>>>>>
>>>>> MyClass class>>specialAnnotation
>>>>>
>>>>> <classMetaAnnotation>
>>>>>
>>>>> ^MySpecialAnnotation new
>>>>>
>>>>>
>>>>> To query annotations from system there are two methods:
>>>>>
>>>>> 1) You can ask concrete annotation class for all declared instances:
>>>>>
>>>>> MySpecialAnnotation declaredInstances
>>>>>
>>>>> 2) You can ask given class for all attached annotations:
>>>>>
>>>>> MyClass metaAnnotations
>>>>>
>>>>> Every annotation includes information about annotated class and the
>>>>> selector of declaring method.
>>>>> All annotations are cached. So it is cheap to query them. There are
>>>>> extra messages to enumerate annotations using block.
>>>>>
>>>>> Now let's discuss it. I think it can be good addition for the Pharo 7.
>>>>> Especially that it is very small code.
>>>>>
>>>>> Also I would like to thank Marcus who helps me realize this concept in
>>>>> Commander and Calypso which I start simplify with this library.
>>>>>
>>>>> Best regards,
>>>>> Denis
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>>
>>>>
>>>>
>>>> Guille Polito
>>>>
>>>> Research Engineer
>>>>
>>>> Centre de Recherche en Informatique, Signal et Automatique de Lille
>>>>
>>>> CRIStAL - UMR 9189
>>>>
>>>> French National Center for Scientific Research - *http://www.cnrs.fr
>>>> <http://www.cnrs.fr>*
>>>>
>>>>
>>>> *Web:* *http://guillep.github.io* <http://guillep.github.io>
>>>>
>>>> *Phone: *+33 06 52 70 66 13 <+33%206%2052%2070%2066%2013>
>>>>
>>>
>>>
>>
>
Sept. 28, 2017
Re: [Pharo-dev] String Interpolation
by Sven Van Caekenberghe
> On 28 Sep 2017, at 18:08, Ron Teitelbaum <ron(a)usmedrec.com> wrote:
>
> Sorry, I tried to have them included at one point on squeak but I was talked down.
>
> I use them a lot! They work with other things besides strings.
In Pharo we have #join: and #split:
$| join: #('Foo' 'Bar').
=> 'Foo|Bar'
$| split: 'Foo|Bar'.
=> an OrderedCollection('Foo' 'Bar')
Not 100% the same, but quite close. Handy indeed.
> Collection >> explode: aDelimiter
> "explode the collection into a collection of collections broken by aDelimiter"
> "(#(#(1 2) #(3 4)) mergeDelimited: Character tab ) explode: Character tab = an OrderedCollection(#(1 2) #(3 4))
> 'abcdef' explode: 'cd' = an OrderedCollection('ab' 'ef')"
> | resultCollection starting aDelimiterPosition aDelimiterSize |
> self ifEmpty: [^self].
> resultCollection := OrderedCollection new.
> aDelimiterSize := aDelimiter isCollection ifTrue: [aDelimiter size] ifFalse: [1].
> starting := 1.
> [aDelimiterPosition := aDelimiter isCollection ifTrue: [self indexOfSubCollection: aDelimiter startingAt: starting] ifFalse: [self indexOf: aDelimiter startingAt: starting ifAbsent: [0]].
> aDelimiterPosition > 0] whileTrue: [
> resultCollection add: (self copyFrom: starting to: aDelimiterPosition - 1).
> starting := aDelimiterPosition + aDelimiterSize.
> ].
> resultCollection add: (self copyFrom: starting to: self size).
> ^resultCollection
>
> Collection >> mergeDelimited: anObject
> "return to reciever a collection with each element concatenated to remove imbeded collections"
> "#(#(1 2) #(3 4)) mergeDelimited: Character tab = #(1 2 Character tab 3 4), #('ab' 'cd') mergeDelimited: Character cr = 'ab
> cd' "
> | returnCollection aSeperator |
> self ifEmpty: [^self].
> aSeperator := anObject isCollection ifTrue: [anObject] ifFalse: [Array with: anObject].
> returnCollection := self first species new.
> self copy from: 1 to: self size -1 do: [:a |
> a ifNotNil: [
> returnCollection := returnCollection, a, aSeperator
> ].
> ].
> ^returnCollection, self last
>
> On Thu, Sep 28, 2017 at 11:25 AM, Sven Van Caekenberghe <sven(a)stfx.eu> wrote:
>
>
> > On 28 Sep 2017, at 17:13, Thierry Goubier <thierry.goubier(a)gmail.com> wrote:
> >
> >
> >
> > 2017-09-28 17:08 GMT+02:00 Sven Van Caekenberghe <sven(a)stfx.eu>:
> >
> >
> > > On 28 Sep 2017, at 16:58, phil(a)highoctane.be wrote:
> > >
> > > I stand corrected.
> > >
> > > Nuclear style feature then.
> > >
> > > 'Let me get out of here {Smalltalk snapshot:false andQuit: true}. BOOM' interpolate
> > >
> > > Feels like
> > >
> > > STR='sudo reboot'; $(STR)
> > >
> > > in bash when one is sudoer.
> >
> > Yeah, but it is always the original programmer who writes the template (including the 'Smalltalk snapshot:false andQuit: true' and the 'sudo reboot' in you examples), you would not do that for any good reason.
> >
> > Typically, you would write something like
> >
> > 'My name is {firstname} {lastname}' interpolate.
> >
> > in a method of an object with firstname and lastname as instance variables. To access the binding, #evaluate: is used. Though a malicious person could enter 'Smalltalk snapshot:false andQuit: true' as name, it is not that expression that gets evaluated. So in that respect there is no risk.
> >
> > The risk would be when the template string itself would be (partially) based on used input.
> >
> > which is easy to overlook:
> >
> > aString interpolate
> >
> > People are on average a bit more carefull when they use #compile: or #evaluate:.
> >
> > Thierry
>
> 100% correct, hence my warning.
>
> > > Phil
> > >
> > > On Thu, Sep 28, 2017 at 4:43 PM, Sven Van Caekenberghe <sven(a)stfx.eu> wrote:
> > >
> > >
> > > > On 28 Sep 2017, at 16:27, phil(a)highoctane.be wrote:
> > > >
> > > > We also have http://norbert.hartl.name/blog/2013/10/03/mustache-templates-for-smalltalk/
> > > >
> > > > Phil
> > >
> > > Yes, Mustache is a cool templating engine, but it is similar to #format: not to #interpolate. With true string interpolation, you do not provide a context, you just write the expressions inline. Compare the following two:
> > >
> > > 'Today is {1} format: { Date today }.
> > >
> > > 'Today is { Date today }' interpolate.
> > >
> > > > On Thu, Sep 28, 2017 at 4:20 PM, Sven Van Caekenberghe <sven(a)stfx.eu> wrote:
> > > > Hi,
> > > >
> > > > I got into a little office discussion about string interpolation as it is done in different programming languages.
> > > >
> > > > In Pharo we have String>>#format: which is pretty nice. It works as follows:
> > > >
> > > > | x y |
> > > > x := 123.
> > > > y := #foo.
> > > > 'x={1} and y={2}' format: { x. y }.
> > > >
> > > > It is also possible to use a dictionary with keys, like this:
> > > >
> > > > | x y |
> > > > x := 123.
> > > > y := #foo.
> > > > 'x={x} and y={y}' format: { #x->x. #y->y } asDictionary.
> > > >
> > > > But this is not true string interpolation as described in [ https://en.wikipedia.org/wiki/String_interpolation ]. The idea is to write the value generating expressions directly inside the strings.
> > > >
> > > > Since in Pharo we add features not by extending the syntax but by adding messages I wondered if it could be done for string interpolation. The goal is to make the following work:
> > > >
> > > > | x y |
> > > > x := 123.
> > > > y := #foo.
> > > > 'It seems x equals {x} and y equals {y} while Pi is still {Float pi}' interpolate.
> > > >
> > > > => 'It seems x equals 123 and y equals foo while Pi is still 3.141592653589793'
> > > >
> > > > Here is the implementation I came up with:
> > > >
> > > > String>>#interpolate
> > > > "Format the receiver by interpolating the evaluation of expressions
> > > > in between curly brackets in the context of the sender as in the following 3 oneline examples.
> > > > 'Today is {Date today}' interpolate.
> > > > | x | x := 123. 'x equals {x} and pi equals {Float pi}' interpolate.
> > > > 'In {#strings} you can escape \{ by prefixing it with \\' interpolate."
> > > >
> > > > | senderContext |
> > > > senderContext := thisContext sender.
> > > > ^ self class new: self size streamContents: [ :out | | stream |
> > > > stream := self readStream.
> > > > [ stream atEnd ] whileFalse: [ | currentChar |
> > > > (currentChar := stream next) == ${
> > > > ifTrue: [ | expression result |
> > > > expression := stream upTo: $}.
> > > > result := Compiler new
> > > > evaluate: expression in: senderContext to: nil notifying: nil ifFail: [ ^ nil ] logged: false.
> > > > out nextPutAll: result asString ]
> > > > ifFalse: [
> > > > currentChar == $\
> > > > ifTrue: [ stream atEnd ifFalse: [ out nextPut: stream next ] ]
> > > > ifFalse: [ out nextPut: currentChar ] ] ] ]
> > > >
> > > > It is a hack that could certainly be improved. And there is of course an obvious security problem.
> > > >
> > > > Thoughts ?
> > > >
> > > > Sven
> > > >
> > > >
> > > >
> > >
> > >
> > >
>
>
>
>
Sept. 28, 2017
Re: [Pharo-dev] [Ann] Class meta annotations
by Denis Kudriashov
2017-09-25 17:57 GMT+02:00 Denis Kudriashov <dionisiydk(a)gmail.com>:
> 2017-09-25 17:38 GMT+02:00 Stephane Ducasse <stepharo.self(a)gmail.com>:
>
>> I agree with guille. We should just called them class annotations.
>>
>> Denis what is a declared instance (is it an object returned by the method
>> having the annotation)
>> but can we find a better name.
>>
>
> My idea that the method with pragma #classMetaAnnotation is the
> declaration of annotation. Internally this declaration creates instance of
> specified annotation which cached by system. And users access all these
> declared instances for reflection purposes.
>
>
Maybe #registeredInstances would be better?
> Also annotation has inst var declarationSelector.
>
>
>> may be effectiveInstances?
>>
>
> I don't like this name. I not understand "effective" in that context.
>
>
>>
>>
>> On Mon, Sep 25, 2017 at 5:09 PM, Guillermo Polito <
>> guillermopolito(a)gmail.com> wrote:
>>
>>> Why calling them meta-annotation and not just annotation? Annotations
>>> are in general already meta :)
>>>
>>> On Mon, Sep 25, 2017 at 5:01 PM, Denis Kudriashov <dionisiydk(a)gmail.com>
>>> wrote:
>>>
>>>> Hi.
>>>>
>>>> I glad to present one class package which introduces reusable mechanism
>>>> for first class annotations.
>>>>
>>>> The project can be found on github https://github.com/dion
>>>> isiydk/ClassMetaAnnotation.
>>>> And I tried to describe why it is needed in my blog
>>>> http://dionisiydk.blogspot.fr/2017/09/class-meta-annotations.html.
>>>>
>>>> And here is overview:
>>>>
>>>> Every annotation should be subclass of ClassMetaAnnotation. To attach
>>>> it to class you create new class side method which will return an instance
>>>> of the annotation. Method should be marked with pragma #classMetaAnnotation:
>>>>
>>>>
>>>> MyClass class>>specialAnnotation
>>>>
>>>> <classMetaAnnotation>
>>>>
>>>> ^MySpecialAnnotation new
>>>>
>>>>
>>>> To query annotations from system there are two methods:
>>>>
>>>> 1) You can ask concrete annotation class for all declared instances:
>>>>
>>>> MySpecialAnnotation declaredInstances
>>>>
>>>> 2) You can ask given class for all attached annotations:
>>>>
>>>> MyClass metaAnnotations
>>>>
>>>> Every annotation includes information about annotated class and the
>>>> selector of declaring method.
>>>> All annotations are cached. So it is cheap to query them. There are
>>>> extra messages to enumerate annotations using block.
>>>>
>>>> Now let's discuss it. I think it can be good addition for the Pharo 7.
>>>> Especially that it is very small code.
>>>>
>>>> Also I would like to thank Marcus who helps me realize this concept in
>>>> Commander and Calypso which I start simplify with this library.
>>>>
>>>> Best regards,
>>>> Denis
>>>>
>>>
>>>
>>>
>>> --
>>>
>>>
>>>
>>> Guille Polito
>>>
>>> Research Engineer
>>>
>>> Centre de Recherche en Informatique, Signal et Automatique de Lille
>>>
>>> CRIStAL - UMR 9189
>>>
>>> French National Center for Scientific Research - *http://www.cnrs.fr
>>> <http://www.cnrs.fr>*
>>>
>>>
>>> *Web:* *http://guillep.github.io* <http://guillep.github.io>
>>>
>>> *Phone: *+33 06 52 70 66 13 <+33%206%2052%2070%2066%2013>
>>>
>>
>>
>
Sept. 28, 2017
Re: [Pharo-dev] String Interpolation
by Ron Teitelbaum
Sorry, I tried to have them included at one point on squeak but I was
talked down.
I use them a lot! They work with other things besides strings.
Collection >> explode: aDelimiter
"explode the collection into a collection of collections broken by
aDelimiter"
"(#(#(1 2) #(3 4)) mergeDelimited: Character tab ) explode: Character tab =
an OrderedCollection(#(1 2) #(3 4))
'abcdef' explode: 'cd' = an OrderedCollection('ab' 'ef')"
| resultCollection starting aDelimiterPosition aDelimiterSize |
self ifEmpty: [^self].
resultCollection := OrderedCollection new.
aDelimiterSize := aDelimiter isCollection ifTrue: [aDelimiter size]
ifFalse: [1].
starting := 1.
[aDelimiterPosition := aDelimiter isCollection ifTrue: [self
indexOfSubCollection: aDelimiter startingAt: starting] ifFalse: [self
indexOf: aDelimiter startingAt: starting ifAbsent: [0]].
aDelimiterPosition > 0] whileTrue: [
resultCollection add: (self copyFrom: starting to: aDelimiterPosition - 1).
starting := aDelimiterPosition + aDelimiterSize.
].
resultCollection add: (self copyFrom: starting to: self size).
^resultCollection
Collection >> mergeDelimited: anObject
"return to reciever a collection with each element concatenated to remove
imbeded collections"
"#(#(1 2) #(3 4)) mergeDelimited: Character tab = #(1 2 Character tab 3
4), #('ab' 'cd') mergeDelimited: Character cr = 'ab
cd' "
| returnCollection aSeperator |
self ifEmpty: [^self].
aSeperator := anObject isCollection ifTrue: [anObject] ifFalse: [Array
with: anObject].
returnCollection := self first species new.
self copy from: 1 to: self size -1 do: [:a |
a ifNotNil: [
returnCollection := returnCollection, a, aSeperator
].
].
^returnCollection, self last
On Thu, Sep 28, 2017 at 11:25 AM, Sven Van Caekenberghe <sven(a)stfx.eu>
wrote:
>
>
> > On 28 Sep 2017, at 17:13, Thierry Goubier <thierry.goubier(a)gmail.com>
> wrote:
> >
> >
> >
> > 2017-09-28 17:08 GMT+02:00 Sven Van Caekenberghe <sven(a)stfx.eu>:
> >
> >
> > > On 28 Sep 2017, at 16:58, phil(a)highoctane.be wrote:
> > >
> > > I stand corrected.
> > >
> > > Nuclear style feature then.
> > >
> > > 'Let me get out of here {Smalltalk snapshot:false andQuit: true}.
> BOOM' interpolate
> > >
> > > Feels like
> > >
> > > STR='sudo reboot'; $(STR)
> > >
> > > in bash when one is sudoer.
> >
> > Yeah, but it is always the original programmer who writes the template
> (including the 'Smalltalk snapshot:false andQuit: true' and the 'sudo
> reboot' in you examples), you would not do that for any good reason.
> >
> > Typically, you would write something like
> >
> > 'My name is {firstname} {lastname}' interpolate.
> >
> > in a method of an object with firstname and lastname as instance
> variables. To access the binding, #evaluate: is used. Though a malicious
> person could enter 'Smalltalk snapshot:false andQuit: true' as name, it is
> not that expression that gets evaluated. So in that respect there is no
> risk.
> >
> > The risk would be when the template string itself would be (partially)
> based on used input.
> >
> > which is easy to overlook:
> >
> > aString interpolate
> >
> > People are on average a bit more carefull when they use #compile: or
> #evaluate:.
> >
> > Thierry
>
> 100% correct, hence my warning.
>
> > > Phil
> > >
> > > On Thu, Sep 28, 2017 at 4:43 PM, Sven Van Caekenberghe <sven(a)stfx.eu>
> wrote:
> > >
> > >
> > > > On 28 Sep 2017, at 16:27, phil(a)highoctane.be wrote:
> > > >
> > > > We also have http://norbert.hartl.name/blog/2013/10/03/mustache-
> templates-for-smalltalk/
> > > >
> > > > Phil
> > >
> > > Yes, Mustache is a cool templating engine, but it is similar to
> #format: not to #interpolate. With true string interpolation, you do not
> provide a context, you just write the expressions inline. Compare the
> following two:
> > >
> > > 'Today is {1} format: { Date today }.
> > >
> > > 'Today is { Date today }' interpolate.
> > >
> > > > On Thu, Sep 28, 2017 at 4:20 PM, Sven Van Caekenberghe <sven(a)stfx.eu>
> wrote:
> > > > Hi,
> > > >
> > > > I got into a little office discussion about string interpolation as
> it is done in different programming languages.
> > > >
> > > > In Pharo we have String>>#format: which is pretty nice. It works as
> follows:
> > > >
> > > > | x y |
> > > > x := 123.
> > > > y := #foo.
> > > > 'x={1} and y={2}' format: { x. y }.
> > > >
> > > > It is also possible to use a dictionary with keys, like this:
> > > >
> > > > | x y |
> > > > x := 123.
> > > > y := #foo.
> > > > 'x={x} and y={y}' format: { #x->x. #y->y } asDictionary.
> > > >
> > > > But this is not true string interpolation as described in [
> https://en.wikipedia.org/wiki/String_interpolation ]. The idea is to
> write the value generating expressions directly inside the strings.
> > > >
> > > > Since in Pharo we add features not by extending the syntax but by
> adding messages I wondered if it could be done for string interpolation.
> The goal is to make the following work:
> > > >
> > > > | x y |
> > > > x := 123.
> > > > y := #foo.
> > > > 'It seems x equals {x} and y equals {y} while Pi is still {Float
> pi}' interpolate.
> > > >
> > > > => 'It seems x equals 123 and y equals foo while Pi is still
> 3.141592653589793'
> > > >
> > > > Here is the implementation I came up with:
> > > >
> > > > String>>#interpolate
> > > > "Format the receiver by interpolating the evaluation of expressions
> > > > in between curly brackets in the context of the sender as in the
> following 3 oneline examples.
> > > > 'Today is {Date today}' interpolate.
> > > > | x | x := 123. 'x equals {x} and pi equals {Float pi}'
> interpolate.
> > > > 'In {#strings} you can escape \{ by prefixing it with \\'
> interpolate."
> > > >
> > > > | senderContext |
> > > > senderContext := thisContext sender.
> > > > ^ self class new: self size streamContents: [ :out | | stream |
> > > > stream := self readStream.
> > > > [ stream atEnd ] whileFalse: [ | currentChar |
> > > > (currentChar := stream next) == ${
> > > > ifTrue: [ | expression result |
> > > > expression := stream upTo: $}.
> > > > result := Compiler new
> > > > evaluate: expression in: senderContext to: nil
> notifying: nil ifFail: [ ^ nil ] logged: false.
> > > > out nextPutAll: result asString ]
> > > > ifFalse: [
> > > > currentChar == $\
> > > > ifTrue: [ stream atEnd ifFalse: [ out nextPut: stream
> next ] ]
> > > > ifFalse: [ out nextPut: currentChar ] ] ] ]
> > > >
> > > > It is a hack that could certainly be improved. And there is of
> course an obvious security problem.
> > > >
> > > > Thoughts ?
> > > >
> > > > Sven
> > > >
> > > >
> > > >
> > >
> > >
> > >
>
>
>
>
Sept. 28, 2017