www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Split range that has no length or slice?

reply Spacen Jasset <spacen razemail.com> writes:
I can't seem to find a way of splitting a range of characters 
into lines unless the range has a length or can be sliced? This 
presumably is because i is a range of chunks, which cannot have a 
length or a slice. I do not see how to get anything else from the 
File object at the moment.

import std.stdio;
import std.string;

void printFile(Range)(Range i)
{
     foreach (l; lineSplitter(i)) {
         writefln("%d\n", l);
     }
}

auto range(File f)
{
     const size_t someArbitrary = 4096;
     return f.byChunk(someArbitrary);
}

void main()
{
     File f = File("/etc/passwd");

     printFile(f.range());
     // std.string.lineSplitter(Flag keepTerm = KeepTerminator.no, 
Range)(Range r) if (hasSlicing!Range && hasLength!Range || 
isSomeString!Range)
     // test.d(21): Error: template instance 
test.printFile!(ByChunk) error instantiating
}
Nov 09 2015
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
File has a .byLine and .byLineCopy method you could use to just 
get lines from it.
Nov 09 2015
parent reply Spacen Jasset <spacen razemail.com> writes:
On Monday, 9 November 2015 at 14:58:19 UTC, Adam D. Ruppe wrote:
 File has a .byLine and .byLineCopy method you could use to just 
 get lines from it.
Ah yes. but unfortunately I don't want to do that. I want to pass a range into my print function. i.e. Sometimes it may not be a File, it might be from a string. Looks like it's not possible without adaptor code. I would suggest File should have a range function on it to return a range, for that matter byLine and byChunk probably shouldn't even be associated with file at all IMHO.
Nov 09 2015
parent reply Alex Parrill <initrd.gz gmail.com> writes:
On Monday, 9 November 2015 at 15:23:21 UTC, Spacen Jasset wrote:
 On Monday, 9 November 2015 at 14:58:19 UTC, Adam D. Ruppe wrote:
 File has a .byLine and .byLineCopy method you could use to 
 just get lines from it.
Ah yes. but unfortunately I don't want to do that. I want to pass a range into my print function. i.e. Sometimes it may not be a File, it might be from a string. Looks like it's not possible without adaptor code. I would suggest File should have a range function on it to return a range, for that matter byLine and byChunk probably shouldn't even be associated with file at all IMHO.
The `.byLine` and `.byLineCopy` functions return ranges. Use those.
Nov 09 2015
parent reply Alex Parrill <initrd.gz gmail.com> writes:
On Monday, 9 November 2015 at 17:56:14 UTC, Alex Parrill wrote:
 On Monday, 9 November 2015 at 15:23:21 UTC, Spacen Jasset wrote:
 On Monday, 9 November 2015 at 14:58:19 UTC, Adam D. Ruppe 
 wrote:
 File has a .byLine and .byLineCopy method you could use to 
 just get lines from it.
Ah yes. but unfortunately I don't want to do that. I want to pass a range into my print function. i.e. Sometimes it may not be a File, it might be from a string. Looks like it's not possible without adaptor code. I would suggest File should have a range function on it to return a range, for that matter byLine and byChunk probably shouldn't even be associated with file at all IMHO.
The `.byLine` and `.byLineCopy` functions return ranges. Use those.
Scratch that, just read your post. Ideally, something like `file.byChunk(4096).joiner.splitter('\n')` would work. The issue is that the byChunk ranges aren't forward or sliceable ranges (which makes sense). Theoretically, it should be possible to implement `splitter` with a plain input range, but it would require that the sub-range that `splitter.front` returns be invalidated when calling `splitter.popFront`.
Nov 09 2015
parent Spacen Jasset <spacen razemail.com> writes:
On Monday, 9 November 2015 at 18:04:23 UTC, Alex Parrill wrote:
 On Monday, 9 November 2015 at 17:56:14 UTC, Alex Parrill wrote:
 On Monday, 9 November 2015 at 15:23:21 UTC, Spacen Jasset 
 wrote:
 On Monday, 9 November 2015 at 14:58:19 UTC, Adam D. Ruppe 
 wrote:
 File has a .byLine and .byLineCopy method you could use to 
 just get lines from it.
Ah yes. but unfortunately I don't want to do that. I want to pass a range into my print function. i.e. Sometimes it may not be a File, it might be from a string. Looks like it's not possible without adaptor code. I would suggest File should have a range function on it to return a range, for that matter byLine and byChunk probably shouldn't even be associated with file at all IMHO.
The `.byLine` and `.byLineCopy` functions return ranges. Use those.
Scratch that, just read your post. Ideally, something like `file.byChunk(4096).joiner.splitter('\n')` would work. The issue is that the byChunk ranges aren't forward or sliceable ranges (which makes sense). Theoretically, it should be possible to implement `splitter` with a plain input range, but it would require that the sub-range that `splitter.front` returns be invalidated when calling `splitter.popFront`.
I don't yet understand the D ranges unfortunately. I can raise a bug about this if people generally agree its currently not a good situation. I don't see that The `.byLine` and `.byLineCopy` functions should be on the File object either. They are surely part of range algorithms, or string functions like std.string.lineSplitter
Nov 09 2015