[Pharo-project] Need your point of view on FSPath * and others

Stéphane Ducasse stephane.ducasse at inria.fr
Sun Feb 20 08:57:31 CET 2011

Here is a forward of colin's answer which I like.

On Fri, Feb 18, 2011 at 2:40 PM, Stéphane Ducasse
 ducasse at inria.fr> wrote:
> Colin
> I'm continuing adding comments to FS.
> 1- A question about
> FSPath class>>* aString
>        ^ self with: aString
> I would like to deprecated FSPath class>>* and use with: since this is the message
> and
> What do you think?
> I really prefer for static analysis point of view not to pollute numerical behavior with others.
> Avoiding ad-hoc polymorphism will help us to build static checker in the future.

I think that in an ideal world, each selector would have a single
"meaning" and all methods with the same selector would be polymorphic
to each other. But we're very, very far from that world, and in
practice, I don't think there's anyway a static analysis tool can rely
on two methods with the same selector being polymorphic.

With that in mind, I added the #/ and #* methods to make the
filesystem API easier to use. I think binary selectors are
under-exploited in Smalltalk, and we'd gain a lot in terms of succinct
and readable code by making better use of them.

> 2- Then I was wondering if it would not be good to have validating creation methods
> (FSPath * 'parent/child/') isRelative
>        true
> (FSPath * '/parent/child/') isAbsolute
>        false
> because the string is not checked
> FSPath * '/parejhkjhhg %% ^%$%^(%$546547675 nt??child/'

That's not how paths are meant to be used - the string arguments
should be file- or directory names, not path fragments. #* creates a
relative path (it's meant to be similar mnemonically to
./parent/child, while #/ creates an absolute path.

(FSPath * 'parent' / 'child') isRelative "true"
(FSPath / 'parent' / 'child') isAbsolute "true"

> I saw that there is
>        readFrom: aStream delimiter: aCharacter
> so I created an unchecking instance creation category and I added with: and * in it.

It's not a matter of checked and unchecked so much as parsed and
unparsed. #/ and #* provide a mini-DSL for building up paths, while
#readFrom:delimiter: parses path strings.

> 3- Then finally the following confuses me
> (FSPath with: 'parent/child/') isRelative true

That creates to a relative path to a file/directory called
'parent/child'. In bash you'd escape the slashes like this:


> (FSPath with: '/parent/child/') isRelative true

That's a relative path to '/parent/child'. In bash: /\parent\/child\/

> (FSPath with: '') isRelative false

That's an absolute path to the root of the file system. Absolute paths
have an empty first element. If you consider $/ the a separator,
'/usr/local/bin' has an empty first element, right?

> Either with: create relative path or isRelative is not consistent.
> If with: creates relative path then the last one should be true
> or isRelative should return false on the second one. ?

Ok, it's a bit of an unusual case, but I think it's important to be
able to represent paths like \/parent\/child. Their perfectly valid as
far as the filesystem is concerned, and we want to be able to work
with such oddly-named files.

> 4 - about FSPath root
> we have
> root
>        "Return the relative root path"
>        ^ self with: ''
> FSPath root
>        returns         /
> and I like that
> Now what about defining root as
> root
>        ^ self with: '/'
> It would be more consistent. Now it breaks everything. So I did not do it :)

I suppose that, strictly speaking, the most consistent way to
represent the root directory is

   ^ self withAll: #('' '')

It still ends up being a bit of a special case, though.


More information about the Pharo-project mailing list