Pregunta

In an example:

var assets = "images/"

var sounds = assets+"sounds/"

Is it more conventional to put the slash on the back of a file path?

var assets = "/images"

var sounds = assets+"/sounds"

Is there another method that is a good common practice?

¿Fue útil?

Solución

Nearly every major programming language has a library to handle the directory separators for you. You should leverage them. This will simplify your code and prevent bugs.

In my experience, the usual reason for combining strings like this is that they come from different sources. Sometimes it's different pieces from a configuration file. Sometimes it's a constant combining with a function argument. In any and all cases, when they come from different sources, you have to consider several different possible cases regarding the separators on the ends to be combined:

  • Both ends could have a separator: "images/" and "/sounds"
  • Only one has a separator: "images" and "/sounds" or "images/" and "sounds"
  • Neither has a separator: "images" and "sounds"

The fact each part comes from a different source means each source might have its own ideas about what conventions to follow, if someone gave any thought to it at all! Whatever is calling your code should not have to worry about this. Your code should handle all cases because someone will violate your convention. This will result in wasted time investigating the cause of an error and making a fix. I have had several unpleasant occasions where a coworker made an assumption about how paths should be formatted in a configuration file, meaning I had to go hunt down the code and figure out what they were expecting (or fix the code).

Most major languages provide a method to do this for you that already handles many of the cases:

There is a caveat with these. A number of these seem to assume that a leading directory separator in the second argument refers to a root path and that this means the first argument should be dropped entirely. I don't know why this is considered useful; for me, it just causes problems. I've never wanted to combine two path portions and end up with the first part being dropped. Read the documentation carefully for special cases, and if necessary, write a wrapper that does what you want with these instead of their special handling.

This additionally helps if you have any need for supporting different operating systems. These classes almost ubiquitously account for choosing the correct separator. The libraries usually have a way of normalizing paths to fit the OS conventions, as well.

In the event that your programming language does not have a readily available library, you should write a method that handles all these cases and use it liberally and across projects.

This falls into the category of "don't make assumptions" and "use tools that help you."

Otros consejos

In Java, the answer would be "neither of the above". Best practice would be to assemble pathnames using the java.io.File class; e.g.

File assets = new File("images");
File sounds = new File(assets, "sounds");

The File class also takes care of platform-specific pathname separators.

There is a separate issue of whether your pathname should start with a slash or not. But that is more to do with correctness than best practice. A pathname that starts with a slash means something different to a pathname that doesn't!!


There isn't explicit support for pathname handling in the core (ECMA) Javascript library, but (at least) Node.js provides support via the Path module.

Note that in .NET you should use the Path.Combine method.

var path = System.IO.Path.Combine("assets", "sounds");

The reason for this is that it 'knows' the correct characters to be used when constructing the folder names.

This takes away the 'problem' of pre or post fixing.

When building paths I often use a function that adds the trailing slash if it isn't already there. Then paths can be built like:

filename := fs( 'assets') + fs( 'images') + fs( 'icons') + 'some.png';

where fs() adds a trailing slash if its needed.

Folders and files differ only in one aspect: folders end with a slash where files do not. Furthermore, absolute paths begin with a / where relative paths do not. If you use this consistently concatenating paths and files together should be no problem.

var absolutepath = "/my/path/";
var relativepath = "css/";
var filename = "test.css";
var relativepathtofilename = "js/test.js";

var a = absolutepath + relativepath + filename; //Output: /my/path/css/test.css
var b = absolutepath + relativepathtofilename;  //Output: /my/path/js/test.js

Concatenating two absolute paths together makes no sense, since the second path should be relative to the first path. Concatenating two relative paths together is no problem, but might lead to undefined behavior if the program does not know where the relative path is relative to.

I think there is no magic or "common practice" on how to implement paths, but certainly string concatenation is not the way to go. You can develop your own API for dealing with cases, but it may require some effort. In particular, you should be careful about different platforms. For example, in Windows \ is the separator while in Unix-based systems / is the separator.

I'm not familiar with Javascript libraries, but I'm sure there should be libraries for handling these cases. In Java, for example, you can use the Path API to deal with platform independent path operations.

My personal preference is this:

var assets = "/images"

var sounds = assets+"/sounds"

I always use absolute paths (/images/...), it feels less prone to error, to me. It is also more fool proof to use var sounds = assets+"/sounds" because even if assets had a trailing slash and you ended up with /images//sounds, it would still resolve to /images/sounds. The one disclaimer being that it depends on your request handler. Apache seems to handle it fine (at least certain versions/configurations, see http://www.amazon.com//gp//site-directory//ref=nav_sad). With the other way you'd end up with /imagessounds, not so fool proof :) There is also the option of checking for double slashes and cleaning them up. Not an option with the other approach.

In Smalltalk it is straightforward to define the / method in String so that it works like this:

'assets' / 'sounds' => 'assets/sounds'.
'assets/' / 'sounds' => 'assets/sounds'.
'assets' / '/sounds' => 'assets/sounds'.
'assets/' / '/sounds' => 'assets/sounds'.

Here is a simple implementation of the method (you can make it better):

/ aString
    | slash first second |
    slash := Directory separator.
    first := self.
    (first endsWith: slash) ifTrue: [first := first allButLast].
    second := aString.
    (second beginsWith: slash) ifTrue: [second := second allButFirst].
    ^first , slash , second

Note: you might also want to pay better attention to border cases such as '' / '', 'x/' / '', etc., in order to determine the proper behavior.

Licenciado bajo: CC-BY-SA con atribución
scroll top