Pharo-users
By thread
pharo-users@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
May 2016
- 84 participants
- 472 messages
Re: [Pharo-users] (no subject)
by Ben Coman
On Tue, May 10, 2016 at 8:52 PM, Franklin Mike
<mike1corporation(a)gmail.com> wrote:
> Hi !
>
> I'm new on pharo and I realy like its vision. To learn more about the system
> I decide to write a package that handle Webcam. The package should be able
> to :
>
> - start webcam
> - take photo
> - record a video.
>
> The wonderfull thing is that I don't know where to start, Every advice is
> welcome.
I guess you will need to interface to some library, so for Pharo 5
have a play with its new UFFI interface.
A quick google around shows opencv to be a common base for FFI...
http://opencvlover.blogspot.com.au/2011/07/accesing-camera-using-opencv.html
but I also found this...
http://itseez.com/tags/openvx/
Note that NativeBoost was an FFI implementation for Pharo 4.
cheers -ben
May 10, 2016
Re: [Pharo-users] Semaphore wait and signal
by Ben Coman
On Tue, May 10, 2016 at 6:31 PM, Vince Refiti <vinref(a)gmail.com> wrote:
> Hello
>
> I am playing around with Semaphore, and wrote the following:
>
> | coll count sem |
> coll := Array withAll: (1 to: 100).
> count := 0.
> sem := Semaphore new.
> coll do: [ :each |
> count := count + 1.
> (count >= 5)
> ifTrue: [
> Transcript show: 'waiting...'; cr.
> sem wait ].
>
> [ [ 2 seconds asDelay wait.
> Transcript show: each printString, ' ', count printString; cr ]
> ensure: [
> count := count -1.
> sem signal ] ] fork ]
>
> The output is:
[snipped]
> I was expecting 'waiting...' to alternate with the 'each-count' lines. Also
> the entire statement paused for 2 seconds, spat out some lines, then waited
> a little longer, and then finished.
>
> Can someone please explain this pattern?
>
> Thanks, Vince
Hi Vince,
General things to be aware of...
* Transcript is not perturbing your result.
* Playground code is executed in the context of the main UI-process. Thus...
* An infinite loop will lock the UI.
* A sem wait will lock the UI.
* Processes at the same priority are scheduled cooperatively.
* Processes at different priority are pre-emptively scheduled.
I refactored your example to better highlight program flow...
| coll count sem |
Transcript clear.
coll := Array withAll: (1 to: 99).
count := 0.
sem := Semaphore new.
coll do:
[ :each |
count := count + 1.
Transcript crShow: each printString; tab; tab; show: count printString, '+'.
(count >= 5) ifTrue:
[ sem isSignaled
ifTrue: [ Transcript tab; show: ' nowait'.
sem wait ]
ifFalse: [ Transcript tab; show: ' wait'.
sem wait.
Transcript crShow: each printString; tab;
tab; show: count printString; tab; show: ' postwait, excessSignals ' ,
sem excessSignals printString. ]
].
[ Transcript crShow: ' ', each printString; tab; tab; show: count
printString; tab; show: ' delay'.
2 seconds asDelay wait.
count := count -1.
Transcript crShow: ' ', each printString; tab ; tab; show: count
printString, '-'; tab; show: ' signal'.
sem signal.
] fork.
]
You will need to add...
Semaphore>>excessSignals
^excessSignals
For counts 1, 2, 3 & 4, forked processes -1 to -4 are queued to run,
but don't run until the UI-process suspended by the wait at each=5,
count=5, which is why the "waiting..." tag appears first.
When the UI-process waits, processes -1 to -4 run in turn and
immediately delay for two seconds. After this, they queued to run.
Process-1 signals the UI-process to be queued to run. But processes
-2 to -4 run first, signalling sem an extra three times.
When the UI-process resumes, each=5, count=1 and sem has three
excessSignals. Completing the do: adds process -5 to the run queue.
Then counts 2, 3, & 4 queues processes -6, -7 & -8 to run. Counts 5,
6 & 7 consume the excessSignals without suspending, queing processes
-9, -10 & -11 to run.
At count=8, the UI-process suspends at the wait, and process -5 runs.
This signals the UI-process to be queued to run. Processes -6 to -11
run, signalling sem an extra six times.
When the UI-process resumes, each=12, count=1 and sem has six
excessSignals. Completing the do: adds process -12 to the run queue.
Then counts 2, 3, & 4 queues processes -13, -14 & -15 to run. Counts
5, 6, 7, 8, 9, 10 consume the excessSignals without suspending, queing
processes -16, -17, -18, -19, -20, -21 to run.
At count=11, the UI-process suspends at the wait, and process -12
runs. This signals the UI-process to be queued to run. Processes -13
to -21 run, signalling sem an extra nine times.
ecetera...
btw, The delay doesn't make much difference to how the forked
processes interact with the main UI-process, since all forked
processes execute before the UI-process resumed. It just interleaves
the delay/signal tags rather than grouping them.
1 1+
2 2+
3 3+
4 4+
5 5+ wait
1 5 delay
2 5 delay
3 5 delay
4 5 delay
1 4- signal
2 3- signal
3 2- signal
4 1- signal
5 1 postwait, excessSignals 3
6 2+
7 3+
8 4+
9 5+ nowait
10 6+ nowait
11 7+ nowait
12 8+ wait
5 8 delay
6 8 delay
7 8 delay
8 8 delay
9 8 delay
10 8 delay
11 8 delay
5 7- signal
6 6- signal
7 5- signal
8 4- signal
9 3- signal
10 2- signal
11 1- signal
12 1 postwait, excessSignals 6
13 2+
14 3+
15 4+
16 5+ nowait
17 6+ nowait
18 7+ nowait
19 8+ nowait
20 9+ nowait
21 10+ nowait
22 11+ wait
12 11 delay
13 11 delay
14 11 delay
15 11 delay
16 11 delay
17 11 delay
18 11 delay
19 11 delay
20 11 delay
21 11 delay
12 10- signal
13 9- signal
14 8- signal
15 7- signal
16 6- signal
17 5- signal
18 4- signal
19 3- signal
20 2- signal
21 1- signal
22 1 postwait, excessSignals 9
23 2+
24 3+
25 4+
26 5+ nowait
27 6+ nowait
28 7+ nowait
29 8+ nowait
30 9+ nowait
31 10+ nowait
32 11+ nowait
33 12+ nowait
34 13+ nowait
35 14+ wait
22 14 delay
23 14 delay
24 14 delay
25 14 delay
26 14 delay
27 14 delay
28 14 delay
29 14 delay
30 14 delay
31 14 delay
32 14 delay
33 14 delay
34 14 delay
22 13- signal
23 12- signal
24 11- signal
25 10- signal
26 9- signal
27 8- signal
28 7- signal
29 6- signal
30 5- signal
31 4- signal
32 3- signal
33 2- signal
34 1- signal
35 1 postwait, excessSignals 12
36 2+
37 3+
38 4+
39 5+ nowait
40 6+ nowait
41 7+ nowait
42 8+ nowait
43 9+ nowait
44 10+ nowait
45 11+ nowait
46 12+ nowait
47 13+ nowait
48 14+ nowait
49 15+ nowait
50 16+ nowait
51 17+ wait
35 17 delay
36 17 delay
37 17 delay
38 17 delay
39 17 delay
40 17 delay
41 17 delay
42 17 delay
43 17 delay
44 17 delay
45 17 delay
46 17 delay
47 17 delay
48 17 delay
49 17 delay
50 17 delay
35 16- signal
36 15- signal
37 14- signal
38 13- signal
39 12- signal
40 11- signal
41 10- signal
42 9- signal
43 8- signal
44 7- signal
45 6- signal
46 5- signal
47 4- signal
48 3- signal
49 2- signal
50 1- signal
51 1 postwait, excessSignals 15
52 2+
53 3+
54 4+
55 5+ nowait
56 6+ nowait
57 7+ nowait
58 8+ nowait
59 9+ nowait
60 10+ nowait
61 11+ nowait
62 12+ nowait
63 13+ nowait
64 14+ nowait
65 15+ nowait
66 16+ nowait
67 17+ nowait
68 18+ nowait
69 19+ nowait
70 20+ wait
51 20 delay
52 20 delay
53 20 delay
54 20 delay
55 20 delay
56 20 delay
57 20 delay
58 20 delay
59 20 delay
60 20 delay
61 20 delay
62 20 delay
63 20 delay
64 20 delay
65 20 delay
66 20 delay
67 20 delay
68 20 delay
69 20 delay
51 19- signal
52 18- signal
53 17- signal
54 16- signal
55 15- signal
56 14- signal
57 13- signal
58 12- signal
59 11- signal
60 10- signal
61 9- signal
62 8- signal
63 7- signal
64 6- signal
65 5- signal
66 4- signal
67 3- signal
68 2- signal
69 1- signal
70 1 postwait, excessSignals 18
71 2+
72 3+
73 4+
74 5+ nowait
75 6+ nowait
76 7+ nowait
77 8+ nowait
78 9+ nowait
79 10+ nowait
80 11+ nowait
81 12+ nowait
82 13+ nowait
83 14+ nowait
84 15+ nowait
85 16+ nowait
86 17+ nowait
87 18+ nowait
88 19+ nowait
89 20+ nowait
90 21+ nowait
91 22+ nowait
92 23+ wait
70 23 delay
71 23 delay
72 23 delay
73 23 delay
74 23 delay
75 23 delay
76 23 delay
77 23 delay
78 23 delay
79 23 delay
80 23 delay
81 23 delay
82 23 delay
83 23 delay
84 23 delay
85 23 delay
86 23 delay
87 23 delay
88 23 delay
89 23 delay
90 23 delay
91 23 delay
70 22- signal
71 21- signal
72 20- signal
73 19- signal
74 18- signal
75 17- signal
76 16- signal
77 15- signal
78 14- signal
79 13- signal
80 12- signal
81 11- signal
82 10- signal
83 9- signal
84 8- signal
85 7- signal
86 6- signal
87 5- signal
88 4- signal
89 3- signal
90 2- signal
91 1- signal
92 1 postwait, excessSignals 21
93 2+
94 3+
95 4+
96 5+ nowait
97 6+ nowait
98 7+ nowait
99 8+ nowait
92 8 delay
93 8 delay
94 8 delay
95 8 delay
96 8 delay
97 8 delay
98 8 delay
99 8 delay
92 7- signal
93 6- signal
94 5- signal
95 4- signal
96 3- signal
97 2- signal
98 1- signal
99 0- signal
May 10, 2016
Re: [Pharo-users] Semaphore wait and signal
by phil@highoctane.be
Transcript output logic is wicked, flush or not. Especially if you Halt now.
Check for stepGlobal senders and implmenters and see it in all its glory
with flags and all.
You can then understand why things are weird.
Some World doOneCycle peppered around may confuse things a bit more.
Use a log file and tail -f it if you are on OSX or Linux.
It will at least be in the order you issue things.
Phil
On Tue, May 10, 2016 at 1:15 PM, Johan Fabry <jfabry(a)dcc.uchile.cl> wrote:
> Hi Vince,
>
> some of your problem may be in the Transcript buffering some of its
> output. It is best to add a ; flush to the end of all your printing, e.g.
> Transcript show: 'waiting...'; cr ; flush.
>
> HTH
>
> On May 10, 2016, at 07:31, Vince Refiti <vinref(a)gmail.com> wrote:
>
> Hello
>
> I am playing around with Semaphore, and wrote the following:
>
> | coll count sem |
> coll := Array withAll: (1 to: 100).
> count := 0.
> sem := Semaphore new.
> coll do: [ :each |
> count := count + 1.
> (count >= 5)
> ifTrue: [
> Transcript show: 'waiting...'; cr.
> sem wait ].
>
> [ [ 2 seconds asDelay wait.
> Transcript show: each printString, ' ', count printString; cr ]
> ensure: [
> count := count -1.
> sem signal ] ] fork ]
>
> The output is:
>
> waiting...
> 1 End of statement list encountered ->5
> 2 4
> 3 3
> 4 2
> waiting...
> waiting...
> waiting...
> waiting...
> 5 8
> 6 7
> 7 6
> 8 5
> 9 4
> 10 3
> 11 2
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 12 11
> 13 10
> 14 9
> 15 8
> 16 7
> 17 6
> 18 5
> 19 4
> 20 3
> 21 2
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 22 14
> 23 13
> 24 12
> 25 11
> 26 10
> 27 9
> 28 8
> 29 7
> 30 6
> 31 5
> 32 4
> 33 3
> 34 2
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 35 17
> 36 16
> 37 15
> 38 14
> 39 13
> 40 12
> 41 11
> 42 10
> 43 9
> 44 8
> 45 7
> 46 6
> 47 5
> 48 4
> 49 3
> 50 2
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 51 20
> 52 19
> 53 18
> 54 17
> 55 16
> 56 15
> 57 14
> 58 13
> 59 12
> 60 11
> 61 10
> 62 9
> 63 8
> 64 7
> 65 6
> 66 5
> 67 4
> 68 3
> 69 2
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 70 23
> waiting...
> 71 23
> 72 22
> 73 21
> 74 20
> 75 19
> 76 18
> 77 17
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 78 23
> 79 22
> 80 21
> 81 20
> 82 19
> 83 18
> 84 17
> 85 16
> 86 15
> 87 14
> 88 13
> 89 12
> 90 11
> 91 10
> 92 9
> 93 8
> 94 7
> 95 6
> 96 5
> 97 4
> 98 3
> 99 2
> 100 1
>
> I was expecting 'waiting...' to alternate with the 'each-count' lines.
> Also the entire statement paused for 2 seconds, spat out some lines, then
> waited a little longer, and then finished.
>
> Can someone please explain this pattern?
>
> Thanks, Vince
>
>
>
>
> ---> Save our in-boxes! http://emailcharter.org <---
>
> Johan Fabry - http://pleiad.cl/~jfabry
> PLEIAD and RyCh labs - Computer Science Department (DCC) - University
> of Chile
>
>
May 10, 2016
(no subject)
by Franklin Mike
Hi !
I'm new on pharo and I realy like its vision. To learn more about the
system I decide to write a package that handle Webcam. The package should
be able to :
- start webcam
- take photo
- record a video.
The wonderfull thing is that I don't know where to start, Every advice is
welcome.
Thanks!
.
May 10, 2016
Re: [Pharo-users] Semaphore wait and signal
by Johan Fabry
Hi Vince,
some of your problem may be in the Transcript buffering some of its output. It is best to add a ; flush to the end of all your printing, e.g. Transcript show: 'waiting...'; cr ; flush.
HTH
> On May 10, 2016, at 07:31, Vince Refiti <vinref(a)gmail.com> wrote:
>
> Hello
>
> I am playing around with Semaphore, and wrote the following:
>
> | coll count sem |
> coll := Array withAll: (1 to: 100).
> count := 0.
> sem := Semaphore new.
> coll do: [ :each |
> count := count + 1.
> (count >= 5)
> ifTrue: [
> Transcript show: 'waiting...'; cr.
> sem wait ].
>
> [ [ 2 seconds asDelay wait.
> Transcript show: each printString, ' ', count printString; cr ] ensure: [
> count := count -1.
> sem signal ] ] fork ]
>
> The output is:
>
> waiting...
> 1 End of statement list encountered ->5
> 2 4
> 3 3
> 4 2
> waiting...
> waiting...
> waiting...
> waiting...
> 5 8
> 6 7
> 7 6
> 8 5
> 9 4
> 10 3
> 11 2
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 12 11
> 13 10
> 14 9
> 15 8
> 16 7
> 17 6
> 18 5
> 19 4
> 20 3
> 21 2
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 22 14
> 23 13
> 24 12
> 25 11
> 26 10
> 27 9
> 28 8
> 29 7
> 30 6
> 31 5
> 32 4
> 33 3
> 34 2
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 35 17
> 36 16
> 37 15
> 38 14
> 39 13
> 40 12
> 41 11
> 42 10
> 43 9
> 44 8
> 45 7
> 46 6
> 47 5
> 48 4
> 49 3
> 50 2
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 51 20
> 52 19
> 53 18
> 54 17
> 55 16
> 56 15
> 57 14
> 58 13
> 59 12
> 60 11
> 61 10
> 62 9
> 63 8
> 64 7
> 65 6
> 66 5
> 67 4
> 68 3
> 69 2
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 70 23
> waiting...
> 71 23
> 72 22
> 73 21
> 74 20
> 75 19
> 76 18
> 77 17
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> waiting...
> 78 23
> 79 22
> 80 21
> 81 20
> 82 19
> 83 18
> 84 17
> 85 16
> 86 15
> 87 14
> 88 13
> 89 12
> 90 11
> 91 10
> 92 9
> 93 8
> 94 7
> 95 6
> 96 5
> 97 4
> 98 3
> 99 2
> 100 1
>
> I was expecting 'waiting...' to alternate with the 'each-count' lines. Also the entire statement paused for 2 seconds, spat out some lines, then waited a little longer, and then finished.
>
> Can someone please explain this pattern?
>
> Thanks, Vince
---> Save our in-boxes! http://emailcharter.org <---
Johan Fabry - http://pleiad.cl/~jfabry
PLEIAD and RyCh labs - Computer Science Department (DCC) - University of Chile
May 10, 2016
Semaphore wait and signal
by Vince Refiti
Hello
I am playing around with Semaphore, and wrote the following:
| coll count sem |
coll := Array withAll: (1 to: 100).
count := 0.
sem := Semaphore new.
coll do: [ :each |
count := count + 1.
(count >= 5)
ifTrue: [
Transcript show: 'waiting...'; cr.
sem wait ].
[ [ 2 seconds asDelay wait.
Transcript show: each printString, ' ', count printString; cr ]
ensure: [
count := count -1.
sem signal ] ] fork ]
The output is:
waiting...
1 End of statement list encountered ->5
2 4
3 3
4 2
waiting...
waiting...
waiting...
waiting...
5 8
6 7
7 6
8 5
9 4
10 3
11 2
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
12 11
13 10
14 9
15 8
16 7
17 6
18 5
19 4
20 3
21 2
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
22 14
23 13
24 12
25 11
26 10
27 9
28 8
29 7
30 6
31 5
32 4
33 3
34 2
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
35 17
36 16
37 15
38 14
39 13
40 12
41 11
42 10
43 9
44 8
45 7
46 6
47 5
48 4
49 3
50 2
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
51 20
52 19
53 18
54 17
55 16
56 15
57 14
58 13
59 12
60 11
61 10
62 9
63 8
64 7
65 6
66 5
67 4
68 3
69 2
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
70 23
waiting...
71 23
72 22
73 21
74 20
75 19
76 18
77 17
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
78 23
79 22
80 21
81 20
82 19
83 18
84 17
85 16
86 15
87 14
88 13
89 12
90 11
91 10
92 9
93 8
94 7
95 6
96 5
97 4
98 3
99 2
100 1
I was expecting 'waiting...' to alternate with the 'each-count' lines. Also
the entire statement paused for 2 seconds, spat out some lines, then waited
a little longer, and then finished.
Can someone please explain this pattern?
Thanks, Vince
May 10, 2016
Re: [Pharo-users] How to construct a multi-part file reference
by Sven Van Caekenberghe
> On 07 May 2016, at 12:08, Udo Schneider <udo.schneider(a)homeaddress.de> wrote:
>
> Hi Sven,
>
> > I always had the impression that Path is not meant for public use,
> > just part of the implementation. Should it not be part of the -Public
> > package then ?
> I'm a bit schizophrenic on this one :-)
The whole FileSystem design is very cool, but sometimes a bit confusing. The first step is of course to fully understand the current design and the ideas behind it. Only then, maybe, we can start to think about what needs to be changed. Right now, I feel I am no ready to do that.
> My "first self" argues that Path as a part of the FileSystem API should indeed remain/be private. Especially because most of us still thing of paths as strings. And manipulating them detached from a filesystem poses some risks (mentioned below). In addition the class comment (IMHO rightly) states: "I'm a private and abstract filesystem path, independent of the string representation used to describe paths on a specific filesystem".
>
> My "second self" argues that a Path could denote so much more than an identifier in filesystem space. Just think of a navigation path in websites (breadcrumbs). In this context Path would be a generalized way to deal of structuring an abstract space by mean of string identifiers. And a "FileSystemPath" would be a (private - see above) subclass adding the filesystem behavior (like detecting absolute filesystem paths).
>
> > Maybe there are still other ways to parse a Windows path while
> > running on a Mac or Linux ?
> I'm not sure I'm getting this one.
>
> Path works the same on all platforms. You might just have to manually specify a delimiter if you want to parse a string. This IMHO is a good thing - you should know the format of strings you're getting :-)
> I've seen code like this:
>
> "Path Splitting for Windows and *nix"
> pathParts := pathString substrings: '/\'.
>
> This works /most/ of the time. It just fails when considering that e.g. "\" is a valid character in *nix filenames ...
>
> '/home/udos/Hello\World' substrings: '/\'. "#('home' 'udos' 'Hello' 'World')"
>
> but
>
> "Not specifying delimiter here - $/ is default then"
> Path from: '/home/udos/Hello\World'. "Path / 'home' / 'udos' / 'Hello\World'"
>
> And considering that some platforms use totally different path delimiters (e.g. ":" on Mac OS, "." on RISC/OS) it's IMHO cleaner to only split on one Character (like Path>>#from:delimiter:) and assign the responsibility of knowing which delimiter to use to the programmer.
>
> However ignoring "minor" platforms and issues with delimiters in names there is no big difference between String>>#substrings: and Path>>#from:delimiter: at first. But the getting back a Path is IMHO much more intention revealing than a collection of strings. Especially because you're getting back an AbsolutePath or RelativePath which is even more intention revealing and something you may completely miss when splitting strings.
>
>
> absoluteArray := '/home/root/file' substrings: '/'. "#('home' 'root' 'file')"
> relativeArray := ('home/root/file' substrings: '/'). "#('home' 'root' 'file')"
> "The distinction between absolute and relative is lost here!"
>
> absoluteArray = relativeArray. "true"
> "Both paths may have referenced the same file - but also may not!!!!"
>
> absolutePath := Path from: '/home/root/file' delimiter: $/. "Path / 'home' / 'root' / 'file'".
> absolutePath class. "AbsolutePath"
> relativePath := Path from: 'home/root/file' delimiter: $/. "Path * 'home' / 'root' / 'file'"
> relativePath class. "RelativePath".
> "The distinction between absolute and relative paths is kept.
> In #printString and class"
>
> absolutePath = relativePath. "false"
> "No danger to confuse absolute and relative paths here"
>
>
>
> Or did I get you completely wrong?
>
> CU,
>
> Udo
>
>
>
>
> On 07/05/16 10:57, Sven Van Caekenberghe wrote:
>> Hi Udo,
>>
>> That is a very good explanation, thank you.
>>
>> I always had the impression that Path is not meant for public use, just part of the implementation. Should it not be part of the -Public package then ?
>>
>> Maybe there are still other ways to parse a Windows path while running on a Mac or Linux ?
>>
>> Sven
>>
>>> On 07 May 2016, at 10:46, Udo Schneider <udo.schneider(a)homeaddress.de> wrote:
>>>
>>> Hi Johan,
>>>
>>> I remember running into similar problems because I didn't understand the FileSystem philosophy ... and dealing with strings and concatenating them is so much easier, right? :-)
>>>
>>> After reading the chapter on FileSystem several times over and over again the IMHO most important part of it to get the grasp of FileSystem is on page 13 (http://pharobooks.gforge.inria.fr/PharoByExampleTwo-Eng/latest/FileSystem.p…)
>>>
>>> "
>>> FileReference = FileSystem + Path
>>> Paths and filesystems are the lowest level of the FileSystem API. A FileReference combines a path and a filesystem into a single object which provides a simpler protocol for working with files as we show in the previous section. References implement the path protocol with methods like /, parent and resolve:.
>>> "
>>>
>>> So in your example â/home/jfabryâ and âtest/code/foo.txtâ are just (relative) path strings. They do not reference anything outside of the context of a filesystem. The hard part for me to understand was the fact that a path may not be unique. The same path might reference different files in different filesystems.
>>> This is especially strange coming from a *nix background where there is only one filesystem.
>>> But even on Windows one could argue that the OS nowadays only knows one filesystem: You can reference any file via a UNC path ... drives, shares, partitions, URIs and other filesystems are simply aliases into the UNC space.
>>> The nice thing of the FileSystem API is it's ability to transparently use files in-Memory, archives, FTP, WebDav, S3 ... . All from within Pharo with the same consistent API. E.g. if you have the FileSystemNetwork (http://smalltalkhub.com/#!/~UdoSchneider/FileSystemNetwork) installed you can do something like:
>>>
>>>
>>>
>>> "Obtain a FTP FileSystem"
>>> fs := FileSystem ftp: 'ftp://ftp.2600.com'.
>>>
>>> "Get working directory"
>>> wd := fs workingDirectory .
>>>
>>> "Print the following expression!"
>>> (wd / 'pub' / 'publications' / 'n0way') children.
>>> (wd / 'pub' / 'publications' / 'n0way' / 'README') contents.
>>>
>>> "Open a FileList on the FileSystem"
>>> FileList openOn: wd.
>>>
>>> "Remember to close if you are finished!"
>>> fs close.
>>>
>>>
>>>
>>>
>>> So to make a long story short: Both your strings contain paths. So we have to convert them into Paths and somehow combine them with a FileSystem to get a valid FileReference:
>>>
>>>
>>>
>>> "I changed the second string to demonstrate dealing with different delimiters"
>>> dirString := '/home/jfabry'.
>>> fileString := 'test\code\foo.txt'.
>>>
>>> "Convert path strings to Paths"
>>> dirPath := Path from: dirString delimiter: $/.
>>> filePath := Path from: fileString delimiter: $\.
>>> "Please note the Paths do not reference anything. We have no FileSystem context yet"
>>>
>>> "The FileSystem our Paths will be resolved within"
>>> diskFs := FileSystem disk.
>>>
>>> "FileReference for the root directory in the FS"
>>> rootRef := diskFs root.
>>>
>>> "Resolve our Paths in the Context of the Reference"
>>> dirRef := rootRef resolve: dirPath.
>>> fileRef := dirRef resolve: filePath. "File @ /home/jfabry/test/code/foo.txt"
>>>
>>> "Please note the fileRef printString. 'File' denotes the FileSystem - not the fact that this is a file! Then you have the path after the at sign"
>>>
>>>
>>>
>>>
>>>
>>> I hope this helps.
>>>
>>> Final advice: In Pharo you should *never never never* assume that a Path is "enough" to reference a file. You will always need the context (it's FileSystem) as well. And that's exactly what a FileReference (see above) is. So if you only have a Path it's questionable to assume that you can simply combine it with a DiskFileSystem to get a valid reference. What if the Path references a file in a ZIP in-Memory archive? Trying to access the Path on disk will yield no result. So always always always store/pass a FileReference if possible!!!!
>>> I did run into that issue in the past with archive/net FileSystems where some dev tools at one point extracted the Path from the FileReference and passed them arround. Down the stack some other methods needed the file contents. Because only the Path was passed they assumed they could retrieve the contents by simply combining it with a DiskFileSystem ... and boom!
>>>
>>>
>>> CU,
>>>
>>> Udo
>>>
>>>
>>> On 07/05/16 00:33, Johan Fabry wrote:
>>>> Hi all,
>>>>
>>>> I have a question about the filesystem that I could not resolve using the documentation. The problem is as follows: I have a file reference that is 2 separate strings that I need to join into one complete file ref but I donât know how because I donât know what the platformâs file separator is.
>>>>
>>>> For example, on a unix-like OS I get â/home/jfabryâ as one part and âtest/code/foo.txtâ as the other part, and I need to construct a FileReference to â/home/jfabry/test/code/foo.txtâ.On M$ I guess this would be 'C:\users\jfabry' and âtest\code\foo.txtâ, so I need to construct FileReference to 'C:\users\jfabry\test\code\foo.txtâ
>>>>
>>>> And the bingo question is: what do I do if I both strings use different kinds of separators?
>>>>
>>>> TIA,
>>>>
>>>> ---> Save our in-boxes! http://emailcharter.org <---
>>>>
>>>> Johan Fabry - http://pleiad.cl/~jfabry
>>>> PLEIAD and RyCh labs - Computer Science Department (DCC) - University of Chile
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>>
>>
>
>
>
May 9, 2016
Re: [Pharo-users] How to construct a multi-part file reference
by Sven Van Caekenberghe
> On 08 May 2016, at 16:53, Nicolai Hess <nicolaihess(a)gmail.com> wrote:
>
>
>
> 2016-05-07 0:33 GMT+02:00 Johan Fabry <jfabry(a)dcc.uchile.cl>:
> Hi all,
>
> I have a question about the filesystem that I could not resolve using the documentation. The problem is as follows: I have a file reference that is 2 separate strings that I need to join into one complete file ref but I donât know how because I donât know what the platformâs file separator is.
>
> For example, on a unix-like OS I get â/home/jfabryâ as one part and âtest/code/foo.txtâ as the other part, and I need to construct a FileReference to â/home/jfabry/test/code/foo.txtâ.On M$ I guess this would be 'C:\users\jfabry' and âtest\code\foo.txtâ, so I need to construct FileReference to 'C:\users\jfabry\test\code\foo.txtâ
>
> And the bingo question is: what do I do if I both strings use different kinds of separators?
>
> I think
>
> â/home/jfabryâ asFileReference resolve: âtest/code/foo.txtâ
>
> works on both platform, with both separators, no?
That seems to be the correct way to use the high level API.
> TIA,
>
> ---> Save our in-boxes! http://emailcharter.org <---
>
> Johan Fabry - http://pleiad.cl/~jfabry
> PLEIAD and RyCh labs - Computer Science Department (DCC) - University of Chile
>
>
>
May 9, 2016
Re: [Pharo-users] How to construct a multi-part file reference
by Johan Fabry
Hi Nicolai,
I donât know if it works with both separators, but itâs simple and works on MacOS at least, so thatâs good enough for me now. Thanks for pointing it out to me !
> On May 8, 2016, at 11:53, Nicolai Hess <nicolaihess(a)gmail.com> wrote:
>
>
>
> 2016-05-07 0:33 GMT+02:00 Johan Fabry <jfabry(a)dcc.uchile.cl <mailto:jfabry@dcc.uchile.cl>>:
> Hi all,
>
> I have a question about the filesystem that I could not resolve using the documentation. The problem is as follows: I have a file reference that is 2 separate strings that I need to join into one complete file ref but I donât know how because I donât know what the platformâs file separator is.
>
> For example, on a unix-like OS I get â/home/jfabryâ as one part and âtest/code/foo.txtâ as the other part, and I need to construct a FileReference to â/home/jfabry/test/code/foo.txtâ.On M$ I guess this would be 'C:\users\jfabry' and âtest\code\foo.txtâ, so I need to construct FileReference to 'C:\users\jfabry\test\code\foo.txtâ
>
> And the bingo question is: what do I do if I both strings use different kinds of separators?
>
> I think
>
> â/home/jfabryâ asFileReference resolve: âtest/code/foo.txtâ
>
> works on both platform, with both separators, no?
>
>
>
>
> TIA,
>
> ---> Save our in-boxes! http://emailcharter.org <http://emailcharter.org/> <---
>
> Johan Fabry - http://pleiad.cl/~jfabry <http://pleiad.cl/~jfabry>
> PLEIAD and RyCh labs - Computer Science Department (DCC) - University of Chile
>
>
>
---> Save our in-boxes! http://emailcharter.org <---
Johan Fabry - http://pleiad.cl/~jfabry
PLEIAD and RyCh labs - Computer Science Department (DCC) - University of Chile
May 8, 2016
Re: [Pharo-users] How to construct a multi-part file reference
by Johan Fabry
Hi Udo,
thatâs a very detailed explanation, thanks for taking the time to write it!
> On May 7, 2016, at 05:46, Udo Schneider <Udo.Schneider(a)homeaddress.de> wrote:
>
> Hi Johan,
>
> I remember running into similar problems because I didn't understand the FileSystem philosophy ... and dealing with strings and concatenating them is so much easier, right? :-)
>
> After reading the chapter on FileSystem several times over and over again the IMHO most important part of it to get the grasp of FileSystem is on page 13 (http://pharobooks.gforge.inria.fr/PharoByExampleTwo-Eng/latest/FileSystem.p…)
>
> "
> FileReference = FileSystem + Path
> Paths and filesystems are the lowest level of the FileSystem API. A FileReference combines a path and a filesystem into a single object which provides a simpler protocol for working with files as we show in the previous section. References implement the path protocol with methods like /, parent and resolve:.
> "
>
> So in your example â/home/jfabryâ and âtest/code/foo.txtâ are just (relative) path strings. They do not reference anything outside of the context of a filesystem. The hard part for me to understand was the fact that a path may not be unique. The same path might reference different files in different filesystems.
> This is especially strange coming from a *nix background where there is only one filesystem.
> But even on Windows one could argue that the OS nowadays only knows one filesystem: You can reference any file via a UNC path ... drives, shares, partitions, URIs and other filesystems are simply aliases into the UNC space.
> The nice thing of the FileSystem API is it's ability to transparently use files in-Memory, archives, FTP, WebDav, S3 ... . All from within Pharo with the same consistent API. E.g. if you have the FileSystemNetwork (http://smalltalkhub.com/#!/~UdoSchneider/FileSystemNetwork) installed you can do something like:
>
>
>
> "Obtain a FTP FileSystem"
> fs := FileSystem ftp: 'ftp://ftp.2600.com'.
>
> "Get working directory"
> wd := fs workingDirectory .
>
> "Print the following expression!"
> (wd / 'pub' / 'publications' / 'n0way') children.
> (wd / 'pub' / 'publications' / 'n0way' / 'README') contents.
>
> "Open a FileList on the FileSystem"
> FileList openOn: wd.
>
> "Remember to close if you are finished!"
> fs close.
>
>
>
>
> So to make a long story short: Both your strings contain paths. So we have to convert them into Paths and somehow combine them with a FileSystem to get a valid FileReference:
>
>
>
> "I changed the second string to demonstrate dealing with different delimiters"
> dirString := '/home/jfabry'.
> fileString := 'test\code\foo.txt'.
>
> "Convert path strings to Paths"
> dirPath := Path from: dirString delimiter: $/.
> filePath := Path from: fileString delimiter: $\.
> "Please note the Paths do not reference anything. We have no FileSystem context yet"
>
> "The FileSystem our Paths will be resolved within"
> diskFs := FileSystem disk.
>
> "FileReference for the root directory in the FS"
> rootRef := diskFs root.
>
> "Resolve our Paths in the Context of the Reference"
> dirRef := rootRef resolve: dirPath.
> fileRef := dirRef resolve: filePath. "File @ /home/jfabry/test/code/foo.txt"
>
> "Please note the fileRef printString. 'File' denotes the FileSystem - not the fact that this is a file! Then you have the path after the at sign"
>
>
>
>
>
> I hope this helps.
>
> Final advice: In Pharo you should *never never never* assume that a Path is "enough" to reference a file. You will always need the context (it's FileSystem) as well. And that's exactly what a FileReference (see above) is. So if you only have a Path it's questionable to assume that you can simply combine it with a DiskFileSystem to get a valid reference. What if the Path references a file in a ZIP in-Memory archive? Trying to access the Path on disk will yield no result. So always always always store/pass a FileReference if possible!!!!
> I did run into that issue in the past with archive/net FileSystems where some dev tools at one point extracted the Path from the FileReference and passed them arround. Down the stack some other methods needed the file contents. Because only the Path was passed they assumed they could retrieve the contents by simply combining it with a DiskFileSystem ... and boom!
>
>
> CU,
>
> Udo
>
>
> On 07/05/16 00:33, Johan Fabry wrote:
>> Hi all,
>>
>> I have a question about the filesystem that I could not resolve using the documentation. The problem is as follows: I have a file reference that is 2 separate strings that I need to join into one complete file ref but I donât know how because I donât know what the platformâs file separator is.
>>
>> For example, on a unix-like OS I get â/home/jfabryâ as one part and âtest/code/foo.txtâ as the other part, and I need to construct a FileReference to â/home/jfabry/test/code/foo.txtâ.On M$ I guess this would be 'C:\users\jfabry' and âtest\code\foo.txtâ, so I need to construct FileReference to 'C:\users\jfabry\test\code\foo.txtâ
>>
>> And the bingo question is: what do I do if I both strings use different kinds of separators?
>>
>> TIA,
>>
>> ---> Save our in-boxes! http://emailcharter.org <---
>>
>> Johan Fabry - http://pleiad.cl/~jfabry
>> PLEIAD and RyCh labs - Computer Science Department (DCC) - University of Chile
>>
>>
>>
>
>
>
>
---> Save our in-boxes! http://emailcharter.org <---
Johan Fabry - http://pleiad.cl/~jfabry
PLEIAD and RyCh labs - Computer Science Department (DCC) - University of Chile
May 8, 2016