Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RuneIterator provides no way to determine if moveNext() fails due to reaching the end of the string or if the string iterated upon is empty #10594

Open
DartBot opened this issue May 11, 2013 · 6 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. core-n library-core P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug

Comments

@DartBot
Copy link

DartBot commented May 11, 2013

This issue was originally filed by bord...@gmail.com


I've been trying to use RuneIterator as the basis for a small parsing library. However the main impediment I've run into is determining throughout the parser whether r.moveNext() return false because the string i'm parsing is empty or if it returns false due to hitting end of string. My main source of frustration is that RuneIterator.rawindex is null is both cases which seems a bit odd. I would assume that in the end of string case the RuneIterator.rawindex would remain at (String.length - 1) or increment to String.length if moveNext() == false.

main() {
  RuneIterator r = "a".runes.iterator;
 
  print (r.current); // null
  print (r.rawIndex); // null
  
  while(r.moveNext()) {
    print (r.current); // 97
    print (r.rawIndex); // 0
  }
                            
  print (r.current); // null
  print (r.rawIndex); // null
  print (r.moveNext()); // false
  
  RuneIterator empty = "".runes.iterator;
  
  print (empty.current); // null
  print (empty.rawIndex); // null
  print (empty.moveNext()); // false
}

@DartBot
Copy link
Author

DartBot commented May 11, 2013

This comment was originally written by bordol...@gmail.com


Another oddity is the spec for iterator, which requires that Iterator.current return null if empty.moveNext() returns false. Conceptually it seems like the api would be easier to grok, if Iterator was defined such that current always returns null until moveNext() is called at least once returning true, and that current retains its last value if moveNext() returns false.

Changing the Iterator spec as such, would then allow RuneIterator.rawIndex to always return the last value up to String.length -1;

@DartBot
Copy link
Author

DartBot commented May 11, 2013

This comment was originally written by bordo...@gmail.com


I also think, that rawIndex should be defined to return -1, if moveNext() has not yet been called. Consider the following example:

part of restlib.parsing_test;

main() {
  String parse(RuneIterator itr) {
    int startIndex = itr.rawIndex; // startIndex is null
    while(itr.moveNext() && itr.current != "d".runes.single) {
      // keep reading characters
    }
    if (itr.rawIndex > startIndex) { // oops comparing int to null,
                                     // noSuchMethodException for example 2
      return itr.string.substring(startIndex + 1, itr.rawIndex);
    } else {
      return "";
    }
  };
  
  RuneIterator itr1 = "abcd".runes.iterator;
  itr1.moveNext();
  print ("result: ${parse(itr1)}");
  
  RuneIterator itr2 = "abcd".runes.iterator;
  print ("result: ${parse(itr2)}"); // crashes
}

@DartBot
Copy link
Author

DartBot commented May 13, 2013

This comment was originally written by bordol...@gmail.com


I ended up writing my own StringIterator class. I retained the behavior of honoring the null contract for Iterator.current, but changed the rawIndex field to always return an int between -1 and string.length. This would be my recommendation for dart as well to avoid the need for lots of special null handling when interacting with RuneIterator.

@DartBot
Copy link
Author

DartBot commented May 13, 2013

@lrhn
Copy link
Member

lrhn commented May 15, 2013

Removed Type-Defect label.
Added Type-Enhancement, Area-Library, Library-Core, Triaged labels.

@floitschG
Copy link
Contributor

Fwiw, this is a contentious issue and being actively discussed.

@DartBot DartBot added Type-Enhancement area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-core labels May 16, 2013
@kevmoo kevmoo added P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug and removed triaged labels Feb 29, 2016
@lrhn lrhn added the core-m label Aug 11, 2017
@floitschG floitschG added core-2 and removed core-m labels Aug 29, 2017
@floitschG floitschG added core-n and removed core-2 labels Sep 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. core-n library-core P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

4 participants