Is there a better way to get a possibly-empty array slice/range from some index to the end?












1















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?










share|improve this question



























    1















    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?










    share|improve this question

























      1












      1








      1








      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?










      share|improve this question














      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 2 at 10:18









      Matteo ItaliaMatteo Italia

      102k15148248




      102k15148248
























          1 Answer
          1






          active

          oldest

          votes


















          3















          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.






          share|improve this answer
























          • 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 the expr kludge.

            – Matteo Italia
            Jan 2 at 10:56






          • 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













          • 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











          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
          });


          }
          });














          draft saved

          draft discarded


















          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









          3















          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.






          share|improve this answer
























          • 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 the expr kludge.

            – Matteo Italia
            Jan 2 at 10:56






          • 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













          • 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
















          3















          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.






          share|improve this answer
























          • 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 the expr kludge.

            – Matteo Italia
            Jan 2 at 10:56






          • 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













          • 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














          3












          3








          3








          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.






          share|improve this answer














          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          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 the expr kludge.

            – Matteo Italia
            Jan 2 at 10:56






          • 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













          • 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











          • 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






          • 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













          • 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




















          draft saved

          draft discarded




















































          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Mossoró

          Error while reading .h5 file using the rhdf5 package in R

          Pushsharp Apns notification error: 'InvalidToken'