Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
August 04, 2014 Declaring run time variables | ||||
---|---|---|---|---|
| ||||
Hello everyone, I'm trying to write a command-line application that can detect whether the input file is gzipped or not. Sounds simple enough, but I can't seem to do it properly in D (this is my first foray to the language). After checking whether the file is gzipped or not, I try to create a new instance of a class that is basically an InputRange returning each line of the input file: ``` File f = File("input_file") // detect gzip ... if (isGzip) auto fileIter = new MyFileReader!GzipIterator(f) else auto fileIter = new MyFileReader!NormalIterator(f) foreach(string line; fileIter) { // do things } ``` However I always get the compiler error `undefined identifier lineIter`. Now, my questions are: 1. What is causing the error? Is this caused by the compiler not being able to figure out what fileIter is at compile time? 2. I realize the current way of creating file handles may not be the best way to handle gzipped or non-gzipped file. Is there a better way to detect and create such file handles based on run time values? Thanks in advance :). |
August 04, 2014 Re: Declaring run time variables | ||||
---|---|---|---|---|
| ||||
Posted in reply to splatterdash | On Monday, 4 August 2014 at 22:00:18 UTC, splatterdash wrote: > ``` > File f = File("input_file") > // detect gzip ... > if (isGzip) { > auto fileIter = new MyFileReader!GzipIterator(f) } > else { > auto fileIter = new MyFileReader!NormalIterator(f) } > > foreach(string line; fileIter) { > // do things > } > ``` (Added braces for clarity.) > However I always get the compiler error `undefined identifier lineIter`. You have two independent variables called fileIter. Both are only available in their respective scopes. Declare the variable before the `if` to get one variable with a wider scope: SomeCommonBaseTypeOfThoseMyFileReaderVariants fileIter; if (isGzip) fileIter = new MyFileReader!GzipIterator(f); else fileIter = new MyFileReader!NormalIterator(f); |
August 04, 2014 Re: Declaring run time variables | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Monday, 4 August 2014 at 22:09:49 UTC, anonymous wrote:
> On Monday, 4 August 2014 at 22:00:18 UTC, splatterdash wrote:
>> ```
>> File f = File("input_file")
>> // detect gzip ...
>> if (isGzip)
> {
>> auto fileIter = new MyFileReader!GzipIterator(f)
> }
>> else
> {
>> auto fileIter = new MyFileReader!NormalIterator(f)
> }
>>
>> foreach(string line; fileIter) {
>> // do things
>> }
>> ```
>
> (Added braces for clarity.)
>
>> However I always get the compiler error `undefined identifier lineIter`.
>
> You have two independent variables called fileIter. Both are only
> available in their respective scopes. Declare the variable before
> the `if` to get one variable with a wider scope:
>
> SomeCommonBaseTypeOfThoseMyFileReaderVariants fileIter;
> if (isGzip)
> fileIter = new MyFileReader!GzipIterator(f);
> else
> fileIter = new MyFileReader!NormalIterator(f);
Indeed I do. I'm not sure which type I should use for the common base type, though. MyFileReader is a templated class, so using it plainly did not work. I also tried `InputRange!string` to no avail despite `MyFileReader` implementing the three InputRange requirement (popFront(), front, and empty).
Any ideas on what I should as the class?
|
August 04, 2014 Re: Declaring run time variables | ||||
---|---|---|---|---|
| ||||
Posted in reply to splatterdash | On Monday, 4 August 2014 at 22:18:24 UTC, splatterdash wrote: > Indeed I do. I'm not sure which type I should use for the common base type, though. MyFileReader is a templated class, so using it plainly did not work. I also tried `InputRange!string` to no avail despite `MyFileReader` implementing the three InputRange requirement (popFront(), front, and empty). > > Any ideas on what I should as the class? Let MyFileReader implement an interface that has the operations you need. That interface can be std.range.InputRange!string, or you can define your own. Note that a type is an input range when it has the input range primitives (front, popFront, empty), but it's only a std.range.InputRange!T when it implements the interface in the OOP sense: class C : InputRange!E {...}. Phobos generally doesn't use InputRange, but templatizes everything. You can go that way, too, and move the foreach loop to a templated function: void main() { File f = File("input_file") // detect gzip ... if (isGzip) doThings(new MyFileReader!GzipIterator(f)); else doThings(new MyFileReader!NormalIterator(f)); } void doThings(I)(I fileIter) { foreach(string line; fileIter) { // do things } } |
August 05, 2014 Re: Declaring run time variables | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Monday, 4 August 2014 at 22:45:15 UTC, anonymous wrote:
> On Monday, 4 August 2014 at 22:18:24 UTC, splatterdash wrote:
>> Indeed I do. I'm not sure which type I should use for the common base type, though. MyFileReader is a templated class, so using it plainly did not work. I also tried `InputRange!string` to no avail despite `MyFileReader` implementing the three InputRange requirement (popFront(), front, and empty).
>>
>> Any ideas on what I should as the class?
>
> Let MyFileReader implement an interface that has the operations
> you need. That interface can be std.range.InputRange!string, or
> you can define your own.
>
> Note that a type is an input range when it has the input range
> primitives (front, popFront, empty), but it's only a
> std.range.InputRange!T when it implements the interface in the
> OOP sense: class C : InputRange!E {...}.
>
> Phobos generally doesn't use InputRange, but templatizes
> everything. You can go that way, too, and move the foreach loop
> to a templated function:
>
> void main()
> {
> File f = File("input_file")
> // detect gzip ...
> if (isGzip)
> doThings(new MyFileReader!GzipIterator(f));
> else
> doThings(new MyFileReader!NormalIterator(f));
> }
> void doThings(I)(I fileIter)
> {
> foreach(string line; fileIter) {
> // do things
> }
> }
That does it, thanks :)!
|
Copyright © 1999-2021 by the D Language Foundation