www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.array oddness

reply "earthfront" <earthfront+dlangforum gmail.com> writes:
Hello!
I was attempting project euler problem 22 and seeing something
weird going on with the array function in std.array.
I made the following code to demonstrate.

Given names.txt:
------------------
"MARY","PATRICIA","LINDA","BARBARA","ELIZABETH"
------------------

and code:
------------------
import std.array,std.stdio;

void main()
{
       { // Correct
           auto names = File("names.txt","r")
               .byLine!(char,char)(KeepTerminator.no,',');

           foreach(char[] name; names ){ writeln( name ); }
       }
       { // Converting to "array" borks the thing
           auto names = File("names.txt","r")
               .byLine!(char,char)(KeepTerminator.no,',')
               .array;

           foreach( char[] name; names){ writeln( name ); }
       }
}
------------------

I get the following output:
------------------
➜ euler rdmd ./stdArrayBug.d
"MARY"
"PATRICIA"
"LINDA"
"BARBARA"
"ELIZABETH"


"ELIZA
"ELIZABETH
"ELIZAB
"ELIZABET
"ELIZABETH"
------------------

Am I using array incorrectly?
I searched bugzilla and didn't see anything pertaining to this
issue.
Should I file a bug?

DMD64 D Compiler v2.066.1
Ubuntu Linux

Thanks!
Dec 12 2014
parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sat, 13 Dec 2014 05:15:08 +0000
earthfront via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 Am I using array incorrectly?
no, you are using `.byLine` incorrectly. ;-) `.byLine` reuses it's internal buffer for each line, so you have to copy that buffer. like this: import std.array, std.stdio; void main () { // Converting to "array" borks the thing import std.algorithm : map; auto names =3D File("names.txt") .byLine!(char,char)(KeepTerminator.no, ',') .map!"a.idup" .array; foreach (name; names) writeln(name); }
Dec 12 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
ketmar:

 no, you are using `.byLine` incorrectly. ;-) `.byLine` reuses 
 it's
 internal buffer for each line, so you have to copy that buffer.
A simple solution is to use byLineCopy (that unfortunately should have been the default behavior since the beginning). Bye, bearophile
Dec 13 2014
parent ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sat, 13 Dec 2014 10:01:49 +0000
bearophile via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 no, you are using `.byLine` incorrectly. ;-) `.byLine` reuses=20
 it's
 internal buffer for each line, so you have to copy that buffer.
=20 A simple solution is to use byLineCopy (that unfortunately should=20 have been the default behavior since the beginning).
that thing is not documented on dlang.org (i assume that it's from upcoming 2.067).
Dec 13 2014
prev sibling next sibling parent reply "thedeemon" <dlang thedeemon.com> writes:
On Saturday, 13 December 2014 at 06:40:41 UTC, ketmar via 
Digitalmars-d-learn wrote:
 .map!"a.idup"
That can be just .map!idup.
Dec 13 2014
parent ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sat, 13 Dec 2014 12:07:27 +0000
thedeemon via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 On Saturday, 13 December 2014 at 06:40:41 UTC, ketmar via=20
 Digitalmars-d-learn wrote:
 .map!"a.idup"
=20 That can be just .map!idup.
it depends of compiler version, as `idup` was a property some time ago. better be safe than sorry.
Dec 13 2014
prev sibling parent reply "earthfront" <earthfront+dlangforum gmail.com> writes:
On Saturday, 13 December 2014 at 06:40:41 UTC, ketmar via 
Digitalmars-d-learn wrote:
     auto names = File("names.txt")
         .byLine!(char,char)(KeepTerminator.no, ',')
         .map!"a.idup"
         .array;
Awesome. "map!idup" does the trick. I had looked at the "byLine" doc before posting, in particular, this line: "Note: Each front will not persist after popFront is called, so the caller must copy its contents (e.g. by calling to!string) if retention is needed." This explains the behavior though I didn't get it then. It's talking about the "range" methods. Following the component based stuff from Walter's article can be brain-bendy. And in this case, requires careful reading of the docs. But I like it. Thanks!
Dec 13 2014
parent ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sun, 14 Dec 2014 05:15:43 +0000
earthfront via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 On Saturday, 13 December 2014 at 06:40:41 UTC, ketmar via=20
 Digitalmars-d-learn wrote:
     auto names =3D File("names.txt")
         .byLine!(char,char)(KeepTerminator.no, ',')
         .map!"a.idup"
         .array;
=20 Awesome. "map!idup" does the trick. =20 I had looked at the "byLine" doc before posting, in particular,=20 this line: "Note: Each front will not persist after popFront is called, so the=20 caller must copy its contents (e.g. by calling to!string) if=20 retention is needed." =20 This explains the behavior though I didn't get it then. It's=20 talking about the "range" methods. Following the component based stuff from Walter's article can be=20 brain-bendy. And in this case, requires careful reading of the=20 docs. But I like it.
it's a matter of time to become used with that "ranges" stuff. but then you will start seeing ranges everywhere. ;-)
Dec 14 2014