www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - problem with byLine

reply =?ISO-8859-1?Q?Christian_K=F6stlin?= <christian.koestlin gmail.com> writes:
Hi,

i wanted to output an ascii-file line by line, but reversed.
the idea was to open the file, use byLine to read it line-by-line, make 
this range an array, and retro this array.

But when i convert byLine to an array, the result is already trash.

Please see this snippet.

import std.stdio;
import std.array;

int main(string[] args) {
   if (args.length != 2) {
     throw new Exception("Usage: " ~ args[0] ~ " file1");
   }

   auto f = File(args[1], "r");
   auto i = array(f.byLine());
   foreach (l; i) {
     writeln(l);
   }
   return 0;
}

Any idea why this happens?

regards

christian köstlin
May 14 2012
parent reply simendsjo <simendsjo gmail.com> writes:
On Mon, 14 May 2012 10:41:54 +0200, Christian K=C3=B6stlin  =

<christian.koestlin gmail.com> wrote:

 Hi,

 i wanted to output an ascii-file line by line, but reversed.
 the idea was to open the file, use byLine to read it line-by-line, mak=
e =
 this range an array, and retro this array.

 But when i convert byLine to an array, the result is already trash.

 Please see this snippet.

 import std.stdio;
 import std.array;

 int main(string[] args) {
    if (args.length !=3D 2) {
      throw new Exception("Usage: " ~ args[0] ~ " file1");
    }

    auto f =3D File(args[1], "r");
    auto i =3D array(f.byLine());
    foreach (l; i) {
      writeln(l);
    }
    return 0;
 }

 Any idea why this happens?

 regards

 christian k=C3=B6stlin
I believe byLine reuses the internal buffer. Try duping the lines: auto i =3D f.byLine().map!"a.idup"().array();
May 14 2012
next sibling parent =?UTF-8?B?Q2hyaXN0aWFuIEvDtnN0bGlu?= <christian.koestlin gmail.com> writes:
On 05/14/2012 11:00 AM, simendsjo wrote:
 I believe byLine reuses the internal buffer. Try duping the lines:
 auto i = f.byLine().map!"a.idup"().array();
Thanks a lot ... that's it! regards christian
May 14 2012
prev sibling parent reply "dcoder" <dcoder nowhere.com> writes:
On Monday, 14 May 2012 at 09:00:14 UTC, simendsjo wrote:
 On Mon, 14 May 2012 10:41:54 +0200, Christian Köstlin 
 <christian.koestlin gmail.com> wrote:

 Hi,

 i wanted to output an ascii-file line by line, but reversed.
 the idea was to open the file, use byLine to read it 
 line-by-line, make this range an array, and retro this array.

 But when i convert byLine to an array, the result is already 
 trash.

 Please see this snippet.

 import std.stdio;
 import std.array;

 int main(string[] args) {
   if (args.length != 2) {
     throw new Exception("Usage: " ~ args[0] ~ " file1");
   }

   auto f = File(args[1], "r");
   auto i = array(f.byLine());
   foreach (l; i) {
     writeln(l);
   }
   return 0;
 }

 Any idea why this happens?

 regards

 christian köstlin
I believe byLine reuses the internal buffer. Try duping the lines:
   auto i = f.byLine().map!"a.idup"().array();
Can someone please explain to me the last line? I'm trying to learn D, by playing with code and reading this forum. I'm a slow learner. :) Anyways, I looked at std.stdio code and noticed that byLine resturns a struct ByLine, but where does the .map come from? Thanks!
May 15 2012
parent reply Matt Soucy <msoucy csh.rit.edu> writes:
On 05/15/2012 10:42 AM, dcoder wrote:
 On Monday, 14 May 2012 at 09:00:14 UTC, simendsjo wrote:
 On Mon, 14 May 2012 10:41:54 +0200, Christian Köstlin
 <christian.koestlin gmail.com> wrote:

 Hi,

 i wanted to output an ascii-file line by line, but reversed.
 the idea was to open the file, use byLine to read it line-by-line,
 make this range an array, and retro this array.

 But when i convert byLine to an array, the result is already trash.

 Please see this snippet.

 import std.stdio;
 import std.array;

 int main(string[] args) {
 if (args.length != 2) {
 throw new Exception("Usage: " ~ args[0] ~ " file1");
 }

 auto f = File(args[1], "r");
 auto i = array(f.byLine());
 foreach (l; i) {
 writeln(l);
 }
 return 0;
 }

 Any idea why this happens?

 regards

 christian köstlin
I believe byLine reuses the internal buffer. Try duping the lines: auto i = f.byLine().map!"a.idup"().array();
Can someone please explain to me the last line? I'm trying to learn D, by playing with code and reading this forum. I'm a slow learner. :) Anyways, I looked at std.stdio code and noticed that byLine resturns a struct ByLine, but where does the .map come from? Thanks!
It comes from std.algorithm. What that line does is: f.byLine() // Get by lines, exactly as you know already .map!"a.idup"() // Iterate over the byLine, and make a Range of immutable strings with the same contents as each line. .array() // Convert it from a range to an array of strings This is achieved through templates accepting strings at compile time to be somewhat like lambda functions, and UFCS.
May 15 2012
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 05/15/2012 09:03 AM, Matt Soucy wrote:

 I believe byLine reuses the internal buffer. Try duping the lines:
 auto i = f.byLine().map!"a.idup"().array();
Can someone please explain to me the last line? I'm trying to learn D, by playing with code and reading this forum. I'm a slow learner. :) Anyways, I looked at std.stdio code and noticed that byLine resturns a struct ByLine, but where does the .map come from? Thanks!
It comes from std.algorithm. What that line does is: f.byLine() // Get by lines, exactly as you know already
Just to clarify: what byLine() returns is a lazy range. Nothing is read from the file just by that line.
 .map!"a.idup"() // Iterate over the byLine, and make a Range of
 immutable strings with the same contents as each line.
And even map() is lazy: It returns a lazy range that will apply .idup() to the lines that it takes from ByLine.
 .array() // Convert it from a range to an array of strings
And that's the eager one that consumes the lazy range that map() returns. Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
May 15 2012
prev sibling parent reply "dcoder" <dcoder nowhere.com> writes:
On Tuesday, 15 May 2012 at 16:03:16 UTC, Matt Soucy wrote:
 I'm trying to learn D, by playing with code and reading this 
 forum. I'm
 a slow learner. :)

 Anyways, I looked at std.stdio code and noticed that byLine 
 resturns a
 struct ByLine, but where does the .map come from? Thanks!
It comes from std.algorithm. What that line does is: f.byLine() // Get by lines, exactly as you know already .map!"a.idup"() // Iterate over the byLine, and make a Range of immutable strings with the same contents as each line. .array() // Convert it from a range to an array of strings This is achieved through templates accepting strings at compile time to be somewhat like lambda functions, and UFCS.
Okay thanks alot Matt and Ali, that helps alot, but I still don't get the dot in ".map" from the line above. Doesn't the dot mean that .map is a member or a member function of the return value of byLine()? Which, in this case is struct ByLine? thanks.
May 15 2012
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 05/15/2012 11:54 AM, dcoder wrote:
 On Tuesday, 15 May 2012 at 16:03:16 UTC, Matt Soucy wrote:
 I'm trying to learn D, by playing with code and reading this forum. I'm
 a slow learner. :)

 Anyways, I looked at std.stdio code and noticed that byLine resturns a
 struct ByLine, but where does the .map come from? Thanks!
It comes from std.algorithm. What that line does is: f.byLine() // Get by lines, exactly as you know already .map!"a.idup"() // Iterate over the byLine, and make a Range of immutable strings with the same contents as each line. .array() // Convert it from a range to an array of strings This is achieved through templates accepting strings at compile time to be somewhat like lambda functions, and UFCS.
Okay thanks alot Matt and Ali, that helps alot, but I still don't get the dot in ".map" from the line above. Doesn't the dot mean that .map is a member or a member function of the return value of byLine()? Which, in this case is struct ByLine? thanks.
Matt has already answered that: UFCS. :) Very briefly, UFCS makes the compiler apply this logic: "if such a member function does not exist, then look for a regular function that has the same name and that can take the object as its first parameter." For example, let's say that you have the following type and the regular function: struct S {} void foo(S s, int i, double d) { // ... } Then, if there is this call in your code, S s; s.foo(42, 1.5); Since S does not have a foo() member function, the compiler then tries the following call and compiles it happily: foo(s, 42, 1.5); Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
May 15 2012
prev sibling parent "Chris Cain" <clcain uncg.edu> writes:
On Tuesday, 15 May 2012 at 18:54:51 UTC, dcoder wrote:
 Okay thanks alot Matt and Ali, that helps alot, but I still 
 don't
 get the dot in ".map" from the line above.  Doesn't the dot mean
 that .map is a member or a member function of the return value 
 of
 byLine()?  Which, in this case is struct ByLine?

 thanks.
A newer feature of D, UFCS (or Uniform Function Call Syntax) makes it so that you can use the dot syntax to mean either a member or member function OR it rewrites the call using the thing before the dot as the first parameter. Let me show you what I mean: struct S { int memberFunc() { return 0; } } int normFunc(S firstParam) { return 1; } S s; s.memberFunc(); // Calls the member function in S s.normFunc(); // Rewritten to normFunc(s); So in the examples they gave above, this is actually what is executed: f.byLine().map!"a.idup"().array(); array(map!"a.idup"(f.byLine())); So, as you can see f has the byLine member function, but the ByLine struct does not have a map function, so it's rewritten like that. Also, the Range returned by map does not have an array function, so it's rewritten again as the first parameter. As you can see, it would normally have to be read backwards (and with a bunch of parentheses to match), which can be confusing... while: f.byLine().map!"a.idup"().array(); Is more natural to read (by most) ... you're taking the lines, using the a.idup function on each, and then making an array from those elements.
May 15 2012