Thread overview
std.csv.csvReader operating on File.byLine()
Oct 07, 2012
Rene Zwanenburg
Oct 07, 2012
Ali Çehreli
Oct 07, 2012
Rene Zwanenburg
Oct 07, 2012
Ali Çehreli
Oct 07, 2012
Dmitry Olshansky
Oct 07, 2012
Rene Zwanenburg
October 07, 2012
Hi,

To my understanding, The csv reader in std.csv is able to operate on any kind of input range. However I can only get it to work on strings. Please take a look at the following line of code. Did I make some mistake?

auto reader = csvReader!(Tuple!(int, int, float))(someFile.byLine());

When I try to compile that, the compiler output is:

main.d(24): Error: template std.csv.csvReader does not match any function template declaration
C:\D\dmd2\windows\bin\..\..\src\phobos\std\csv.d(283): Error: template std.csv.csvReader cannot deduce template function from argument types !(Tuple!(int,int,float))(ByLine!(char,char))
main.d(24): Error: template instance csvReader!(Tuple!(int,int,float)) errors instantiating template

As a workaround I could use readText, but that's dirty and won't work for large csv files.
October 07, 2012
On 10/07/2012 11:21 AM, Rene Zwanenburg wrote:
> Hi,
>
> To my understanding, The csv reader in std.csv is able to operate on any
> kind of input range.

The error message took me to the definition of the function. The template constraints require that the element type of the range must be a dchar:

// ...
  if(isInputRange!Range && is(ElementType!Range == dchar)
// ...

In your case, the element type of byLine() is a string. (I think.)

> However I can only get it to work on strings.
> Please take a look at the following line of code. Did I make some mistake?
>
> auto reader = csvReader!(Tuple!(int, int, float))(someFile.byLine());
>
> When I try to compile that, the compiler output is:
>
> main.d(24): Error: template std.csv.csvReader does not match any
> function template declaration
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\csv.d(283): Error: template
> std.csv.csvReader cannot deduce template function from argument types
> !(Tuple!(int,int,float))(ByLine!(char,char))
> main.d(24): Error: template instance csvReader!(Tuple!(int,int,float))
> errors instantiating template
>
> As a workaround I could use readText, but that's dirty and won't work
> for large csv files.

If deneme.txt contains this:

1,2,3.5
6,7,8.5

This works:

import std.stdio;
import std.csv;
import std.typecons;

void main()
{
    auto someFile = File("deneme.txt");

    foreach (line; someFile.byLine()) {
        auto reader = csvReader!(Tuple!(int, int, float))(line);
        foreach (record; reader) {
            writeln(record);
        }
    }
}

Ali

October 07, 2012
Ah yes, I understand. Thanks.

For the sake of cleanliness (and Walter's article on component programming ;) ), is there a way to treat a file as an InputRange of characters? I think this is quite a common use case.

On Sunday, 7 October 2012 at 19:32:12 UTC, Ali Çehreli wrote:
> On 10/07/2012 11:21 AM, Rene Zwanenburg wrote:
> > Hi,
> >
> > To my understanding, The csv reader in std.csv is able to
> operate on any
> > kind of input range.
>
> The error message took me to the definition of the function. The template constraints require that the element type of the range must be a dchar:
>
> // ...
>   if(isInputRange!Range && is(ElementType!Range == dchar)
> // ...
>
> In your case, the element type of byLine() is a string. (I think.)
>
> > However I can only get it to work on strings.
> > Please take a look at the following line of code. Did I make
> some mistake?
> >
> > auto reader = csvReader!(Tuple!(int, int,
> float))(someFile.byLine());
> >
> > When I try to compile that, the compiler output is:
> >
> > main.d(24): Error: template std.csv.csvReader does not match
> any
> > function template declaration
> > C:\D\dmd2\windows\bin\..\..\src\phobos\std\csv.d(283): Error:
> template
> > std.csv.csvReader cannot deduce template function from
> argument types
> > !(Tuple!(int,int,float))(ByLine!(char,char))
> > main.d(24): Error: template instance
> csvReader!(Tuple!(int,int,float))
> > errors instantiating template
> >
> > As a workaround I could use readText, but that's dirty and
> won't work
> > for large csv files.
>
> If deneme.txt contains this:
>
> 1,2,3.5
> 6,7,8.5
>
> This works:
>
> import std.stdio;
> import std.csv;
> import std.typecons;
>
> void main()
> {
>     auto someFile = File("deneme.txt");
>
>     foreach (line; someFile.byLine()) {
>         auto reader = csvReader!(Tuple!(int, int, float))(line);
>         foreach (record; reader) {
>             writeln(record);
>         }
>     }
> }
>
> Ali


October 07, 2012
On 10/07/2012 02:42 PM, Rene Zwanenburg wrote:

> For the sake of cleanliness (and Walter's article on component
> programming ;) ), is there a way to treat a file as an InputRange of
> characters? I think this is quite a common use case.

I've just discovered the undocumented byRecord:

Again, assuming that deneme.txt contains:

1,2,3.5
6,7,8.5

import std.stdio;

void main()
{
    auto someFile = File("deneme.txt");

    writeln(someFile.byRecord!(int, int, float)("%s,%s,%s"));
}

And there is std.algorithm.joiner:

    writeln(someFile.byLine.joiner);

There must be something more straightforward though. :)

Ali

October 07, 2012
On 08-Oct-12 01:42, Rene Zwanenburg wrote:
> Ah yes, I understand. Thanks.
>
> For the sake of cleanliness (and Walter's article on component
> programming ;) ), is there a way to treat a file as an InputRange of
> characters? I think this is quite a common use case.
>

IRC something along the lines of:

foreach(dchar ch; LockingTextReader(file))
{
...
}


-- 
Dmitry Olshansky
October 07, 2012
On Sunday, 7 October 2012 at 22:31:05 UTC, Dmitry Olshansky wrote:
> On 08-Oct-12 01:42, Rene Zwanenburg wrote:
>> Ah yes, I understand. Thanks.
>>
>> For the sake of cleanliness (and Walter's article on component
>> programming ;) ), is there a way to treat a file as an InputRange of
>> characters? I think this is quite a common use case.
>>
>
> IRC something along the lines of:
>
> foreach(dchar ch; LockingTextReader(file))
> {
> ...
> }

LockingTextReader is exactly what I was looking for. Thanks.