Is there a better way to get a possibly-empty array slice/range from some index to the end?
In fish array ranges are one-based and inclusive of both extremes, which, unsurprisingly, leads to problems when possibly-zero-length-ranges are required.
In particular, I'm in a situation where I split out the first arguments for my own consumption, and I want to forward the rest of them - which may be none! - to some command. If this was Python, I could do something like:
my_arg = sys.argv[1]
other_args = sys.argv[2:]
However, the straight translation of this to fish unfortunately doesn't work in edge cases; consider
set -l my_arg $argv[1]
set -l other_args $argv[2..-1]
(I kept the same indexes as, while in fish indexing is 1-based, $argv doesn't include what would be sys.argv[0])
This works fine as long as there are enough arguments; for example, if I invoke my command with arguments a b c d e I'll get $my_arg = a and $other_args = b c d e.
However, if I invoke it with just a, other_args will be surprisingly set to a as well. This comes from the fact that -1 actually gets expanded to something to the effect of (count $argv), so the statement above is equivalent to
set -l other_args $argv[2..1]
which is an inverted range from the nonexistent element 2 to the existent element 1, inclusive, which boils down to plain $argv[1].
To avoid this problem, currently I'm using this horrible workaround
set -l other_args $argv[2..(expr (count $argv) + 1)]
which ensures that the last index is one past the last, forcing the range to be a "straight" one, albeit possibly fully out of range (which returns an empty list as required).
However, I'm wondering: is there a better solution that I'm missing?
arrays slice fish
add a comment |
In fish array ranges are one-based and inclusive of both extremes, which, unsurprisingly, leads to problems when possibly-zero-length-ranges are required.
In particular, I'm in a situation where I split out the first arguments for my own consumption, and I want to forward the rest of them - which may be none! - to some command. If this was Python, I could do something like:
my_arg = sys.argv[1]
other_args = sys.argv[2:]
However, the straight translation of this to fish unfortunately doesn't work in edge cases; consider
set -l my_arg $argv[1]
set -l other_args $argv[2..-1]
(I kept the same indexes as, while in fish indexing is 1-based, $argv doesn't include what would be sys.argv[0])
This works fine as long as there are enough arguments; for example, if I invoke my command with arguments a b c d e I'll get $my_arg = a and $other_args = b c d e.
However, if I invoke it with just a, other_args will be surprisingly set to a as well. This comes from the fact that -1 actually gets expanded to something to the effect of (count $argv), so the statement above is equivalent to
set -l other_args $argv[2..1]
which is an inverted range from the nonexistent element 2 to the existent element 1, inclusive, which boils down to plain $argv[1].
To avoid this problem, currently I'm using this horrible workaround
set -l other_args $argv[2..(expr (count $argv) + 1)]
which ensures that the last index is one past the last, forcing the range to be a "straight" one, albeit possibly fully out of range (which returns an empty list as required).
However, I'm wondering: is there a better solution that I'm missing?
arrays slice fish
add a comment |
In fish array ranges are one-based and inclusive of both extremes, which, unsurprisingly, leads to problems when possibly-zero-length-ranges are required.
In particular, I'm in a situation where I split out the first arguments for my own consumption, and I want to forward the rest of them - which may be none! - to some command. If this was Python, I could do something like:
my_arg = sys.argv[1]
other_args = sys.argv[2:]
However, the straight translation of this to fish unfortunately doesn't work in edge cases; consider
set -l my_arg $argv[1]
set -l other_args $argv[2..-1]
(I kept the same indexes as, while in fish indexing is 1-based, $argv doesn't include what would be sys.argv[0])
This works fine as long as there are enough arguments; for example, if I invoke my command with arguments a b c d e I'll get $my_arg = a and $other_args = b c d e.
However, if I invoke it with just a, other_args will be surprisingly set to a as well. This comes from the fact that -1 actually gets expanded to something to the effect of (count $argv), so the statement above is equivalent to
set -l other_args $argv[2..1]
which is an inverted range from the nonexistent element 2 to the existent element 1, inclusive, which boils down to plain $argv[1].
To avoid this problem, currently I'm using this horrible workaround
set -l other_args $argv[2..(expr (count $argv) + 1)]
which ensures that the last index is one past the last, forcing the range to be a "straight" one, albeit possibly fully out of range (which returns an empty list as required).
However, I'm wondering: is there a better solution that I'm missing?
arrays slice fish
In fish array ranges are one-based and inclusive of both extremes, which, unsurprisingly, leads to problems when possibly-zero-length-ranges are required.
In particular, I'm in a situation where I split out the first arguments for my own consumption, and I want to forward the rest of them - which may be none! - to some command. If this was Python, I could do something like:
my_arg = sys.argv[1]
other_args = sys.argv[2:]
However, the straight translation of this to fish unfortunately doesn't work in edge cases; consider
set -l my_arg $argv[1]
set -l other_args $argv[2..-1]
(I kept the same indexes as, while in fish indexing is 1-based, $argv doesn't include what would be sys.argv[0])
This works fine as long as there are enough arguments; for example, if I invoke my command with arguments a b c d e I'll get $my_arg = a and $other_args = b c d e.
However, if I invoke it with just a, other_args will be surprisingly set to a as well. This comes from the fact that -1 actually gets expanded to something to the effect of (count $argv), so the statement above is equivalent to
set -l other_args $argv[2..1]
which is an inverted range from the nonexistent element 2 to the existent element 1, inclusive, which boils down to plain $argv[1].
To avoid this problem, currently I'm using this horrible workaround
set -l other_args $argv[2..(expr (count $argv) + 1)]
which ensures that the last index is one past the last, forcing the range to be a "straight" one, albeit possibly fully out of range (which returns an empty list as required).
However, I'm wondering: is there a better solution that I'm missing?
arrays slice fish
arrays slice fish
asked Jan 2 at 10:18
Matteo ItaliaMatteo Italia
102k15148248
102k15148248
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
However, I'm wondering: is there a better solution that I'm missing?
Upgrade to 3.0. This was a bug in 2.7 that is fixed there.
The way this works now is that, if only one of the indices in a range is negative, it'll always be interpreted as the larger of the two, so with a negative end, iteration is forced to go forward.
If the index isn't actually larger, this results in no elements instead, which is precisely what you want here.
That's great! Unfortunately I'm not sure I'll be able to upgrade to fish 3 on all the machines where this script is used, so for the moment I'll have to keep the workaround, however it's nice to know it has been fixed.
– Matteo Italia
Jan 2 at 10:43
An alternative workaround is to check if argv has 2 elements before using it:set -q argv[2]; and set -l other_args $argv[2..-1]
– faho
Jan 2 at 10:45
Eh I think it's worse, as you have to repeat twice the starting index (so it's easier for it to get out of sync). I'll just keep theexprkludge.
– Matteo Italia
Jan 2 at 10:56
1
Theexprkludge starts an external process, and will only work on fish >=2.7 (because that was the first release to allow invalid indices). Checking works on fish back to at least 2.2.0.
– faho
Jan 2 at 11:06
Starting an external process in this particular case isn't much of a problem, but some more past compatibility is welcome; I'll adopt your solution.
– Matteo Italia
Jan 2 at 13:16
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54004543%2fis-there-a-better-way-to-get-a-possibly-empty-array-slice-range-from-some-index%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
However, I'm wondering: is there a better solution that I'm missing?
Upgrade to 3.0. This was a bug in 2.7 that is fixed there.
The way this works now is that, if only one of the indices in a range is negative, it'll always be interpreted as the larger of the two, so with a negative end, iteration is forced to go forward.
If the index isn't actually larger, this results in no elements instead, which is precisely what you want here.
That's great! Unfortunately I'm not sure I'll be able to upgrade to fish 3 on all the machines where this script is used, so for the moment I'll have to keep the workaround, however it's nice to know it has been fixed.
– Matteo Italia
Jan 2 at 10:43
An alternative workaround is to check if argv has 2 elements before using it:set -q argv[2]; and set -l other_args $argv[2..-1]
– faho
Jan 2 at 10:45
Eh I think it's worse, as you have to repeat twice the starting index (so it's easier for it to get out of sync). I'll just keep theexprkludge.
– Matteo Italia
Jan 2 at 10:56
1
Theexprkludge starts an external process, and will only work on fish >=2.7 (because that was the first release to allow invalid indices). Checking works on fish back to at least 2.2.0.
– faho
Jan 2 at 11:06
Starting an external process in this particular case isn't much of a problem, but some more past compatibility is welcome; I'll adopt your solution.
– Matteo Italia
Jan 2 at 13:16
add a comment |
However, I'm wondering: is there a better solution that I'm missing?
Upgrade to 3.0. This was a bug in 2.7 that is fixed there.
The way this works now is that, if only one of the indices in a range is negative, it'll always be interpreted as the larger of the two, so with a negative end, iteration is forced to go forward.
If the index isn't actually larger, this results in no elements instead, which is precisely what you want here.
That's great! Unfortunately I'm not sure I'll be able to upgrade to fish 3 on all the machines where this script is used, so for the moment I'll have to keep the workaround, however it's nice to know it has been fixed.
– Matteo Italia
Jan 2 at 10:43
An alternative workaround is to check if argv has 2 elements before using it:set -q argv[2]; and set -l other_args $argv[2..-1]
– faho
Jan 2 at 10:45
Eh I think it's worse, as you have to repeat twice the starting index (so it's easier for it to get out of sync). I'll just keep theexprkludge.
– Matteo Italia
Jan 2 at 10:56
1
Theexprkludge starts an external process, and will only work on fish >=2.7 (because that was the first release to allow invalid indices). Checking works on fish back to at least 2.2.0.
– faho
Jan 2 at 11:06
Starting an external process in this particular case isn't much of a problem, but some more past compatibility is welcome; I'll adopt your solution.
– Matteo Italia
Jan 2 at 13:16
add a comment |
However, I'm wondering: is there a better solution that I'm missing?
Upgrade to 3.0. This was a bug in 2.7 that is fixed there.
The way this works now is that, if only one of the indices in a range is negative, it'll always be interpreted as the larger of the two, so with a negative end, iteration is forced to go forward.
If the index isn't actually larger, this results in no elements instead, which is precisely what you want here.
However, I'm wondering: is there a better solution that I'm missing?
Upgrade to 3.0. This was a bug in 2.7 that is fixed there.
The way this works now is that, if only one of the indices in a range is negative, it'll always be interpreted as the larger of the two, so with a negative end, iteration is forced to go forward.
If the index isn't actually larger, this results in no elements instead, which is precisely what you want here.
answered Jan 2 at 10:30
fahofaho
5,6111526
5,6111526
That's great! Unfortunately I'm not sure I'll be able to upgrade to fish 3 on all the machines where this script is used, so for the moment I'll have to keep the workaround, however it's nice to know it has been fixed.
– Matteo Italia
Jan 2 at 10:43
An alternative workaround is to check if argv has 2 elements before using it:set -q argv[2]; and set -l other_args $argv[2..-1]
– faho
Jan 2 at 10:45
Eh I think it's worse, as you have to repeat twice the starting index (so it's easier for it to get out of sync). I'll just keep theexprkludge.
– Matteo Italia
Jan 2 at 10:56
1
Theexprkludge starts an external process, and will only work on fish >=2.7 (because that was the first release to allow invalid indices). Checking works on fish back to at least 2.2.0.
– faho
Jan 2 at 11:06
Starting an external process in this particular case isn't much of a problem, but some more past compatibility is welcome; I'll adopt your solution.
– Matteo Italia
Jan 2 at 13:16
add a comment |
That's great! Unfortunately I'm not sure I'll be able to upgrade to fish 3 on all the machines where this script is used, so for the moment I'll have to keep the workaround, however it's nice to know it has been fixed.
– Matteo Italia
Jan 2 at 10:43
An alternative workaround is to check if argv has 2 elements before using it:set -q argv[2]; and set -l other_args $argv[2..-1]
– faho
Jan 2 at 10:45
Eh I think it's worse, as you have to repeat twice the starting index (so it's easier for it to get out of sync). I'll just keep theexprkludge.
– Matteo Italia
Jan 2 at 10:56
1
Theexprkludge starts an external process, and will only work on fish >=2.7 (because that was the first release to allow invalid indices). Checking works on fish back to at least 2.2.0.
– faho
Jan 2 at 11:06
Starting an external process in this particular case isn't much of a problem, but some more past compatibility is welcome; I'll adopt your solution.
– Matteo Italia
Jan 2 at 13:16
That's great! Unfortunately I'm not sure I'll be able to upgrade to fish 3 on all the machines where this script is used, so for the moment I'll have to keep the workaround, however it's nice to know it has been fixed.
– Matteo Italia
Jan 2 at 10:43
That's great! Unfortunately I'm not sure I'll be able to upgrade to fish 3 on all the machines where this script is used, so for the moment I'll have to keep the workaround, however it's nice to know it has been fixed.
– Matteo Italia
Jan 2 at 10:43
An alternative workaround is to check if argv has 2 elements before using it:
set -q argv[2]; and set -l other_args $argv[2..-1]– faho
Jan 2 at 10:45
An alternative workaround is to check if argv has 2 elements before using it:
set -q argv[2]; and set -l other_args $argv[2..-1]– faho
Jan 2 at 10:45
Eh I think it's worse, as you have to repeat twice the starting index (so it's easier for it to get out of sync). I'll just keep the
expr kludge.– Matteo Italia
Jan 2 at 10:56
Eh I think it's worse, as you have to repeat twice the starting index (so it's easier for it to get out of sync). I'll just keep the
expr kludge.– Matteo Italia
Jan 2 at 10:56
1
1
The
expr kludge starts an external process, and will only work on fish >=2.7 (because that was the first release to allow invalid indices). Checking works on fish back to at least 2.2.0.– faho
Jan 2 at 11:06
The
expr kludge starts an external process, and will only work on fish >=2.7 (because that was the first release to allow invalid indices). Checking works on fish back to at least 2.2.0.– faho
Jan 2 at 11:06
Starting an external process in this particular case isn't much of a problem, but some more past compatibility is welcome; I'll adopt your solution.
– Matteo Italia
Jan 2 at 13:16
Starting an external process in this particular case isn't much of a problem, but some more past compatibility is welcome; I'll adopt your solution.
– Matteo Italia
Jan 2 at 13:16
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54004543%2fis-there-a-better-way-to-get-a-possibly-empty-array-slice-range-from-some-index%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown