Re: std.path.buildPath

2017-06-12 Thread Russel Winder via Digitalmars-d-learn
On Sun, 2017-06-04 at 21:32 +0200, Jacob Carlborg via Digitalmars-d-
learn wrote:
> On 2017-06-04 19:05, Patrick Schluter wrote:
> 
> > buildPath("/usr/bin", "/usr/bin/gcc")
> > 
> > /usr/bin/usr/bin/gcc is obviously wrong.
> 
> Says who? It might be exactly what I want. The case that came up is 
> inside DStep. The user provides a set of files C header to be
> translated 
> to D modules. The user also provides a flag to indicate where to
> place 
> the resulting files. I wanted to be able to keep the existing
> directory 
> structure of the header files in the new target location. Example:

Says Guido et al. it seems, Python has in os.path and pathlib exactly
this behaviour.

> dstep -o result /usr/include/libxml2/libxml/*.h
> 
> The internals of DStep will do something like:
> 
> buildPath("result", "/usr/include/libxml2/libxml");
> 
> Which currently results in "/usr/include/libxml2/libxml". The end
> result 
> is that DStep will try to write a file to
> "/usr/include/libxml2/libxml", 
> which the user most likely will not have access to (without using
> sudo). 
> I expected the result of buildPath to be 
> "result/usr/include/libxml2/libxml".

Sadly Python tells us otherwise just as D does.

It is perhaps worth noting in passing that D path support seems very
like os.path and Python folk are giving that up in favour of pathlib.
Java/Kotlin/Groovy have also gone the same way. The implication is that
D needs better path support than it currently has to keep up with the
evolutions in other languages.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: std.path.buildPath

2017-06-12 Thread Russel Winder via Digitalmars-d-learn
On Sun, 2017-06-11 at 13:21 +, Ryan Frame via Digitalmars-d-learn
wrote:
> On Sunday, 4 June 2017 at 18:15:36 UTC, Russel Winder wrote:
> > On Sun, 2017-06-04 at 17:56 +0200, Jacob Carlborg via 
> > Digitalmars-d- learn wrote:
> > > On 2017-06-04 07:44, Jesse Phillips wrote:
> > > 
> > > > What is your expected behavior? Throw an exception? You can't
> > > > really
> > > > append an absolute path to another.
> > > 
> > > Of course you can. I expect buildPath("/foo", "/bar") to 
> > > result in "/foo/bar". That's how Ruby behaves.
> > 
> > And Python, Groovy, Java, Kotlin, Ceylon, C++, …
> 
> Python 3.5.1 on my machine:
> 
>  >>> os.path.join("/asdf", "/bcd")
>  '/bcd'
>  >>> os.path.join("asdf", "/bcd")
>  '/bcd'

###  you are absolutely right, and it is clearly stated in the
documentation that this is the expected behaviour. Clearly, I have
never tried doing that in 20 years of playing with Python. And it has
never come up in 12 years of running Python workshops!

This behaviour is reinforced by pathlib which is the modern way of
doing paths in Python, replacing os.path:

import pathlib

p = pathlib.Path()
p = p.joinpath('/', 'usr', '/local', '/bin')
print(p)

result /bin.

So given Python is one of the targets for D, consistency of behaviour
implies D is currently doing the right thing.
 
-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: std.path.buildPath

2017-06-11 Thread Ryan Frame via Digitalmars-d-learn

On Sunday, 4 June 2017 at 18:15:36 UTC, Russel Winder wrote:
On Sun, 2017-06-04 at 17:56 +0200, Jacob Carlborg via 
Digitalmars-d- learn wrote:

On 2017-06-04 07:44, Jesse Phillips wrote:

> What is your expected behavior? Throw an exception? You can't
> really
> append an absolute path to another.

Of course you can. I expect buildPath("/foo", "/bar") to 
result in "/foo/bar". That's how Ruby behaves.


And Python, Groovy, Java, Kotlin, Ceylon, C++, …


Python 3.5.1 on my machine:

>>> os.path.join("/asdf", "/bcd")
'/bcd'
>>> os.path.join("asdf", "/bcd")
'/bcd'


Re: std.path.buildPath

2017-06-04 Thread Jacob Carlborg via Digitalmars-d-learn

On 2017-06-04 19:05, Patrick Schluter wrote:


buildPath("/usr/bin", "/usr/bin/gcc")

/usr/bin/usr/bin/gcc is obviously wrong.


Says who? It might be exactly what I want. The case that came up is 
inside DStep. The user provides a set of files C header to be translated 
to D modules. The user also provides a flag to indicate where to place 
the resulting files. I wanted to be able to keep the existing directory 
structure of the header files in the new target location. Example:


dstep -o result /usr/include/libxml2/libxml/*.h

The internals of DStep will do something like:

buildPath("result", "/usr/include/libxml2/libxml");

Which currently results in "/usr/include/libxml2/libxml". The end result 
is that DStep will try to write a file to "/usr/include/libxml2/libxml", 
which the user most likely will not have access to (without using sudo). 
I expected the result of buildPath to be 
"result/usr/include/libxml2/libxml".


--
/Jacob Carlborg


Re: std.path.buildPath

2017-06-04 Thread Russel Winder via Digitalmars-d-learn
On Sun, 2017-06-04 at 17:56 +0200, Jacob Carlborg via Digitalmars-d-
learn wrote:
> On 2017-06-04 07:44, Jesse Phillips wrote:
> 
> > What is your expected behavior? Throw an exception? You can't
> > really
> > append an absolute path to another.
> 
> Of course you can. I expect buildPath("/foo", "/bar") to result in 
> "/foo/bar". That's how Ruby behaves.

And Python, Groovy, Java, Kotlin, Ceylon, C++, …

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: std.path.buildPath

2017-06-04 Thread Patrick Schluter via Digitalmars-d-learn

On Sunday, 4 June 2017 at 15:56:58 UTC, Jacob Carlborg wrote:

On 2017-06-04 07:44, Jesse Phillips wrote:

What is your expected behavior? Throw an exception? You can't 
really

append an absolute path to another.


Of course you can. I expect buildPath("/foo", "/bar") to result 
in "/foo/bar". That's how Ruby behaves.


buildPath("/usr/bin", "/usr/bin/gcc")

/usr/bin/usr/bin/gcc is obviously wrong. I think the semantic is 
not as illogical as it seem at first glance.


Re: std.path.buildPath

2017-06-04 Thread Jacob Carlborg via Digitalmars-d-learn

On 2017-06-04 07:44, Jesse Phillips wrote:


What is your expected behavior? Throw an exception? You can't really
append an absolute path to another.


Of course you can. I expect buildPath("/foo", "/bar") to result in 
"/foo/bar". That's how Ruby behaves.


--
/Jacob Carlborg


Re: std.path.buildPath

2017-06-03 Thread Jesse Phillips via Digitalmars-d-learn

On Saturday, 3 June 2017 at 14:12:03 UTC, Russel Winder wrote:

From the manual page on std.path.buildPath:

writeln(buildPath("foo", "bar", "baz")); // "foo/bar/baz"
writeln(buildPath("/foo/", "bar/baz")); // "/foo/bar/baz"
writeln(buildPath("/foo", "/bar")); // "/bar"

I have no idea what drugs the person who chose that last one to 
be correct semantics was on at the time, but it was some 
seriously bad stuff.


"If any of the path segments are absolute (as defined by 
isAbsolute), the preceding segments will be dropped."


I cannot find any excuse for this to be even remotely 
reasonable.


What is your expected behavior? Throw an exception? You can't 
really append an absolute path to another.


Re: std.path.buildPath

2017-06-03 Thread David Nadlinger via Digitalmars-d-learn

On Saturday, 3 June 2017 at 14:12:03 UTC, Russel Winder wrote:
I have no idea what drugs the person who chose that last one to 
be correct semantics was on at the time, but it was some 
seriously bad stuff.


Of all people, I certainly didn't expect you to stray so far from 
the tone appropriate here. Please keep it civil.


I cannot find any excuse for this to be even remotely 
reasonable.


I suspect the original author had applications in mind where you 
want to resolve user-specified file system paths that might be 
relative or absolute. One could just use buildPath to prepend the 
root path if necessary. (Whether this is useful or just 
unnecessarily error-prone is another question, of course.)


 — David


Re: std.path.buildPath

2017-06-03 Thread Jacob Carlborg via Digitalmars-d-learn

On 2017-06-03 16:12, Russel Winder via Digitalmars-d-learn wrote:

From the manual page on std.path.buildPath:

writeln(buildPath("foo", "bar", "baz")); // "foo/bar/baz"
writeln(buildPath("/foo/", "bar/baz")); // "/foo/bar/baz"
writeln(buildPath("/foo", "/bar")); // "/bar"

I have no idea what drugs the person who chose that last one to be
correct semantics was on at the time, but it was some seriously bad
stuff.

"If any of the path segments are absolute (as defined by isAbsolute),
the preceding segments will be dropped."

I cannot find any excuse for this to be even remotely reasonable.


Unfortunately it's been like this since forever. I mean, I checked the 
git history, it's been like this for as long as we have history, 
including when it was called "join".


--
/Jacob Carlborg


std.path.buildPath

2017-06-03 Thread Russel Winder via Digitalmars-d-learn
From the manual page on std.path.buildPath:

writeln(buildPath("foo", "bar", "baz")); // "foo/bar/baz"
writeln(buildPath("/foo/", "bar/baz")); // "/foo/bar/baz"
writeln(buildPath("/foo", "/bar")); // "/bar"

I have no idea what drugs the person who chose that last one to be
correct semantics was on at the time, but it was some seriously bad
stuff.

"If any of the path segments are absolute (as defined by isAbsolute),
the preceding segments will be dropped."

I cannot find any excuse for this to be even remotely reasonable.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: std.path.buildPath() and string enumeration

2012-05-30 Thread Artur Skawina
On 05/30/12 20:34, nrgyzer wrote:
> Hi,
> 
> I've the following enumeration:
> 
> enum path : string {
> 
>   log1 = "/var/log1",
>   log2 = "/var/log2"
> 
> }
> 
> Now... when I try to do the following:
> 
> string subDirectory = "example";
> 
> string newPath = buildPath(path.log1, subDirectory);
> 
> I get the following errors:
> 
> Error: template std.path.buildPath does not match any function template
> declaration
> Error: template std.path.buildPath(C) if (isSomeChar!(C)) cannot deduce
> template function from argument types !()(path,string)
> Error: template std.path.buildPath does not match any function template
> declaration
> Error: template std.path.buildPath(C) if (isSomeChar!(C)) cannot deduce
> template function from argument types !()(path,string)
> 
> Is this a bug in std.path.buildPath() or is there anything I'm doing wrong?
> 

A bug, as an enum member is supposed to implicitly convert to its base type. [1]

You might be able to work-around it like this

   template _path() {
  enum : string {
log1 = "/var/log1",
log2 = "/var/log2"
  }
   }
   alias _path!() path;

artur

[1] Actually, D's "typesafe variadic functions" don't play well with certain
other features too, eg

   void f(A...)(A a) {}
   void f()(string[] a...) {}
   f("a", "b"); // expecting the second overload to be called is reasonable,
// but this isn't what's going to happen.



Re: std.path.buildPath() and string enumeration

2012-05-30 Thread bearophile

A better solution is to use:

struct Path {
enum : string {
log1 = "/var/log1",
log2 = "/var/log2"
}
}


Or even just:

struct Path {
enum string log1 = "/var/log1",
log2 = "/var/log2";
}

(In D structs, classes and enums start with an upper case).

Bye,
bearophile


Re: std.path.buildPath() and string enumeration

2012-05-30 Thread nrgyzer
== Auszug aus bearophile (bearophileh...@lycos.com)'s Artikel
> nrgyzer:
> > Is this a bug in std.path.buildPath() or is there anything I'm
> > doing wrong?
> The signature of buildPath is:
> immutable(C)[] buildPath(C)(const(C[])[] paths...);
> But your inputs aren't of the same type. Named enum create their
> own type. You give buildPath a type string and a type path, that
> is not a string.
> There are various solutions, this compiles, but it's not very
> safe:
> buildPath(cast(string)path.log1, subDirectory);
> Another solution is to not use a named enum:
> enum : string {
>  path_log1 = "/var/log1",
>  path_log2 = "/var/log2"
> }
> buildPath(path_log1, subDirectory)
> In bugzilla I have asked for an enum property that returns the
> raw value&type of an enum.
> Bye,
> bearophile

Alright, thanks... but I want to do the following:

foreach(c; __traits(allMembers, path))
 if (!exists(mixin("path." ~ c))) mkdirRecurse(mixin("path." ~ c));

When I use a named enum, I can't use the source above... so I've to cast in the
buildPath()-method to my path enumeration or is there any other chance to
realize the foreach-loop?


Re: std.path.buildPath() and string enumeration

2012-05-30 Thread bearophile

nrgyzer:

Is this a bug in std.path.buildPath() or is there anything I'm 
doing wrong?


The signature of buildPath is:

immutable(C)[] buildPath(C)(const(C[])[] paths...);

But your inputs aren't of the same type. Named enum create their 
own type. You give buildPath a type string and a type path, that 
is not a string.


There are various solutions, this compiles, but it's not very 
safe:


buildPath(cast(string)path.log1, subDirectory);

Another solution is to not use a named enum:

enum : string {
path_log1 = "/var/log1",
path_log2 = "/var/log2"
}

buildPath(path_log1, subDirectory)

In bugzilla I have asked for an enum property that returns the 
raw value&type of an enum.


Bye,
bearophile


std.path.buildPath() and string enumeration

2012-05-30 Thread nrgyzer
Hi,

I've the following enumeration:

enum path : string {

  log1 = "/var/log1",
  log2 = "/var/log2"

}

Now... when I try to do the following:

string subDirectory = "example";

string newPath = buildPath(path.log1, subDirectory);

I get the following errors:

Error: template std.path.buildPath does not match any function template
declaration
Error: template std.path.buildPath(C) if (isSomeChar!(C)) cannot deduce
template function from argument types !()(path,string)
Error: template std.path.buildPath does not match any function template
declaration
Error: template std.path.buildPath(C) if (isSomeChar!(C)) cannot deduce
template function from argument types !()(path,string)

Is this a bug in std.path.buildPath() or is there anything I'm doing wrong?