Skip to content

refactor: reduce repeated code in which()#659

Merged
freitagbr merged 1 commit intomasterfrom
refactor-which
Mar 4, 2017
Merged

refactor: reduce repeated code in which()#659
freitagbr merged 1 commit intomasterfrom
refactor-which

Conversation

@nfischer
Copy link
Copy Markdown
Member

Use path.delimiter instead of explicit conditional. Try to reuse
repeated code blocks. Remove logical negation at the end
of the function to improve readability.

Blocked on #655

Fixes #656

src/which.js Outdated
} else {
return p.split(':');
}
return p.split(path.delimiter);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or a good ol' ternary statement:

return p ? p.split(path.delimiter) : [];

src/which.js Outdated
}

// Search for command in PATH
pathArray.forEach(function (dir) {
Copy link
Copy Markdown
Contributor

@freitagbr freitagbr Feb 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, we're looping through the path array, and setting where under certain conditions, then returning from the forEach callback. On the next call, we check if which was set, and if it was, we don't continue. Finally, at the end of checkPath, we return where if it was set. To me, it seems like a regular for loop would be a better choice here, because we could return where from the function immediately.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I agree. Index-based for loops kind of suck in JS, but it's probably still better than this exit-early-if-we-found-it approach. I will adjust.

src/which.js Outdated

return where;
// Command not found anywhere?
return null;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... Maybe an empty string should be returned here? All of the other paths return strings, and '' is falsy like null is.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null is better here because it won't get wrapped by ShellString. The empty string would get wrapped, and ShellString('') is actually truthy, unlike ''.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that makes sense.

@nfischer
Copy link
Copy Markdown
Member Author

@freitagbr PTAL. Significantly refactored things, hopefully this is a cleaner approach, with less code duplication.

src/which.js Outdated
// This is the value to return if we haven't found any matches
noMatches: options.all ? [] : null,
value: [],
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is better than it was before, but this is still a little complicated. On the one hand, this generalizes the two options more clearly, but on the other hand, dealing with one-off objects is a bit messy.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll take away some of the abstraction

src/which.js Outdated
return;
}
// Otherwise, see if it exists without the extension
var newAttempt = attempt + ext;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit confusing. We're checking if it exists "without the extension", but then we add the extension?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'll see if I can make that better. The basic idea is this:

  1. Handle the case where they call which('node.exe')
  2. If they instead did which('node'), then check for node.exe, node.bat, node.cmd, etc.

@nfischer
Copy link
Copy Markdown
Member Author

@freitagbr please see if this next set of changes improves clarity

src/which.js Outdated
} else {
// Assume it's Unix-like
var match = attempt.match(/\.[^<>:"/\|?*.]+$/);
if (match && pathExtArray.search(match[0]) >= 0) { // this is Windows-only
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think indexOf should be used here, instead of search.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this was a mistake. Array.prototype.search isn't even defined... indexOf is what I was looking for. Thanks

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Use path.delimiter instead of explicit conditional. Try to reuse
repeated code blocks.

Fixes #656
@nfischer
Copy link
Copy Markdown
Member Author

@freitagbr PTAL

@freitagbr
Copy link
Copy Markdown
Contributor

Ok, this is much better. LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants