digitalmars.D.learn - How to avoid code duplication?
- Suliman (33/33) Mar 31 2015 The situation is next:
- Suliman (4/4) Mar 31 2015 Maybe there is way to access of element of archive in the same
- Rikki Cattermole (3/33) Mar 31 2015 Use InputRange!string aka an input range which gives you elements. It
- Suliman (2/2) Mar 31 2015 Rikki, could you explain? I did not understand where it can help
- Rikki Cattermole (73/74) Mar 31 2015 Here is some example code. While I've only implemented one
The situation is next: I have got the function that get arrays of lognames and logfullname: void loginsert(string [] lognames, string [] logfullname) { if(logfullname[i].endsWith("txt")) { auto file = File(logfullname[i], "r"); foreach (line; file.byLine) { // long manupulation with strings } } } But now need add supporting passing to function not only txt files, but also zip archives. The problem that now I see only one way to do adding zip -- add block: if(logfullname[i].endsWith("zip")) And in it do everything with unpacking content of archive like: foreach(ArchiveMember am; zip.directory) { string file = cast(string)zip.expand(am); foreach (line; file.lineSplitter()) { } } and put inside it some same content that I am doing in "long manupulation with strings". Maybe there is any better way? But I really can't understand it because auto file = File(logfullname[i], "r"); can't read unpacked content of archive.
Mar 31 2015
Maybe there is way to access of element of archive in the same way as to txt file? I looked, but it's seems that constructor accept only path to file. But I can't understand how to set path to unpacked element of archive.
Mar 31 2015
On 1/04/2015 6:15 p.m., Suliman wrote:The situation is next: I have got the function that get arrays of lognames and logfullname: void loginsert(string [] lognames, string [] logfullname) { if(logfullname[i].endsWith("txt")) { auto file = File(logfullname[i], "r"); foreach (line; file.byLine) { // long manupulation with strings } } } But now need add supporting passing to function not only txt files, but also zip archives. The problem that now I see only one way to do adding zip -- add block: if(logfullname[i].endsWith("zip")) And in it do everything with unpacking content of archive like: foreach(ArchiveMember am; zip.directory) { string file = cast(string)zip.expand(am); foreach (line; file.lineSplitter()) { } } and put inside it some same content that I am doing in "long manupulation with strings". Maybe there is any better way? But I really can't understand it because auto file = File(logfullname[i], "r"); can't read unpacked content of archive.Use InputRange!string aka an input range which gives you elements. It can wrap up the behavior for getting the values.
Mar 31 2015
Rikki, could you explain? I did not understand where it can help me
Mar 31 2015
On 1/04/2015 7:19 p.m., Suliman wrote:Rikki, could you explain? I did not understand where it can help meHere is some example code. While I've only implemented one InputRange!string instance. You would probably have one, for just zip's and another raw text files. Keep in mind it returns only a single line from standard input. In other words, let the range handle reading a line from a file. import std.range; import std.stdio; class Range : InputRange!string { private { string buffer; } this() { popFront; } property { string front() { return buffer; } bool empty() { return false; } } void popFront() { buffer = readln(); } string moveFront() { string ret = front(); popFront(); return ret; } int opApply(int delegate(string) del) { int result; while(!empty()) { result = del(moveFront()); if (result) break; } return result; } int opApply(int delegate(size_t, string) del) { int result; size_t offset; while(!empty()) { result = del(offset, moveFront()); if (result) break; offset++; } return result; } } void myfunc(InputRange!string input) { foreach(line; input) { writeln("GOT [line]: ", line); } } void main() { InputRange!string theRange = new Range(); myfunc(theRange); }
Mar 31 2015