Ranges seem awkward to work with
Mike Parker via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Sep 11 20:01:43 PDT 2017
On Tuesday, 12 September 2017 at 01:13:29 UTC, Hasen Judy wrote:
> Is this is a common beginner issue? I remember using an earlier
> version of D some long time ago and I don't remember seeing
> this concept.
>
> Now, a lot of library functions seem to expect ranges as inputs
> and return ranges as output.
>
> Even parsing a csv line returns a range. And the funny thing
> is, once you loop over it, it's done. You've basically consumed
> it.
>
> For example, I was having some trouble with the api of the
> std.csv module, so to help me debug, I printed the result of
> the csv. ok, the result seems good. Now I try to use it, for
> example:
>
> auto name = row[1];
>
> And to my surprise there's a runtime error, something about
> range something something. I don't even remember what the error
> was. The thing is, it wasn't clear what was going on.
>
> The line was actually more like:
>
> auto some_var =
> some_function(row[1].some_other_library_method!template_variable);
>
> So because I was calling several library methods on the same
> line, I thought the problem might have something to do with the
> range not exactly matching what the library was expecting. I
> thought maybe row[1] also returned some range instead of a
> string and that range had something wrong with it.
>
> Well, it turned out that my earlier attempt to print the parsed
> csv row resulted in the row being "consumed" and now the row is
> an empty range(!).
>
> Is there a straight forward way to convert a Range to a list
> other than manually doing a foreach?
>
> string[] items;
> foreach(item; someRangeThing) {
> items ~= item;
> }
>
> I feel like that is a bit of an overkill.
Don't think of ranges as persistent containers. They aren't. They
are transient entities, temporary views of data. If you have a
container and want a consumable view of it that doesn't mutate
the container itself, produce a range. If you receive a range and
want to transform it from a transient entity into something
concrete, use std.array.array or a range-based container API. If
it helps, Chapter 6: Understanding Ranges from 'Learning D' is
available (in somewhat mutilated form) as an article at the
publisher's site:
https://www.packtpub.com/books/content/understanding-ranges
More information about the Digitalmars-d-learn
mailing list