Re: New to D: parse a binary file
scottrick Wrote: T[] rawRead(T)(T[] buffer); I understand that T is generic type, but I am not sure of the meaning of the (T) after the method name. That T is defining the symbol to represent the generic type. It can have more than one and D provides other things like aliases... Another way to write that function (I may get something wrong here but give it a shot) is: template(T) { T[] rawRead(T[] buffer); }
Re: New to D: parse a binary file
Thanks, your post was very helpful. Two more questions (probably related): Where is the function 'format' defined? Also, what is that 'unittest' block? It compiles fine as is, but if I refer to format outside of unittest, it will not compile. Also, if I compile and run your example, it doesn't do anything, since main() is empty? Thanks again,
Re: New to D: parse a binary file
scottrick: Where is the function 'format' defined? You need to add at the top of the module: import std.conv: format; Or: import std.conv; Also, what is that 'unittest' block? It compiles fine as is, but if I refer to format outside of unittest, it will not compile. Also, if I compile and run your example, it doesn't do anything, since main() is empty? It's an block of unit tests :-) Currently in your program they are not even compiled, so the format is not used. To run the unit tests you need to compile with -unittest compiler switch (with DMD). See also: http://www.digitalmars.com/d/2.0/unittest.html Bye, bearophile
Re: New to D: parse a binary file
Am 06.02.2011 19:38, schrieb Jesse Phillips: scottrick Wrote: T[] rawRead(T)(T[] buffer); I understand that T is generic type, but I am not sure of the meaning of the (T) after the method name. That T is defining the symbol to represent the generic type. It can have more than one and D provides other things like aliases... Another way to write that function (I may get something wrong here but give it a shot) is: template(T) { T[] rawRead(T[] buffer); } I think you meant template(T) rawRead{ T[] rawRead(T[] buffer); } 'template' defines a namespace which is normally accessed like templ!(parameters).member; templ!(parameters).memberfunc(parameters); Because the template and it's member are called identically this member is accessed autoatically (the eponymous-trick). If it's a function you call it like that: templfunc!(compiletimeparam)(param); The compile time parameters can left out, if these can be derived from the normal parameters' type. templfun(param); Voilla! You have a completely transparent templated func. Mafi
Re: New to D: parse a binary file
On 02/05/2011 06:26 PM, scottrick wrote: Hi, I am new to D. I am trying to write a binary file parser for a project of mine and I thought it would be fun to try and learn a new language at the same time. So I chose D! :D I have been struggling however and have not been able to find very many good examples, so I am posting this message. I think I'm supposed to be using std.stdio, but I'm not 100% sure. Could somebody post a short example of how to parse a couple of characters and ints or whatever from a file? Or how to read, say, the next however many bytes into a struct? Also, looking at the documentation, I am confused by this method signature: T[] rawRead(T)(T[] buffer); I understand that T is generic type, but I am not sure of the meaning of the (T) after the method name. Thanks, Below a pair of examples that should make all this clearer: a templated hand-written naive map func, and a template struct type (would be nearly the same for a class). Just run it. Additional explanations on demand. import File=std.file; import std.array; Out[] map (In, Out) (In[] source, Out delegate (In) f) { // (0) Out[] target; foreach (element; source) target ~= f(element); return target; } struct StoreStack (T) { T[] items; string logFileName; this (string logFileName, T[] items=[]) { this.items = items; this.logFileName = logFileName; // create/reset log file File.write(logFileName, ); } string toString () { static form = StoreStack(\%s\, %s); return format(form, this.logFileName, this.items); } void put (T item) { this.items ~= item; string message = format(put item: %s\n, item); File.append(logFileName, message); } T take () { T item = this.items[$-1]; this.items = this.items[0..$-1]; string message = format(took item: %s\n, item); File.append(logFileName, message); return item; } } unittest { // map string hex (uint i) { return format(0x%03X, i); } uint[] decs = [1, 3, 9, 27, 81, 243, 729]; auto hexes = map!(uint,string)(decs, hex); // auto hexes = map(decs, hex); // (1) writefln (decs: %s\n--\nhexes: %s, decs, hexes); writeln(); // StoreStack auto store = StoreStack!(int)(test_log); // auto store = StoreStack!int(test_log); // (2) store.put(3); store.put(2); store.put(3); auto i = store.take(); writefln(store: %s, store); writefln(log:\n%s, File.readText(test_log)); } void main() {} (0) The func must be declared as delegate (instead of simple func pointer) because: the actual func hex beeing defined in a block, the compiler turns it into a delegate. Detail. (1) Here, the compiler is able to infer the template parameters (types): no need to specify them. (2) When there is a single template parameter, the syntax allows omitting () around it. Denis -- _ vita es estrany spir.wikidot.com
Re: New to D: parse a binary file
spir: Out[] map (In, Out) (In[] source, Out delegate (In) f) { // (0) ... string hex (uint i) { return format(0x%03X, i); } uint[] decs = [1, 3, 9, 27, 81, 243, 729]; auto hexes = map!(uint,string)(decs, hex); ... (0) The func must be declared as delegate (instead of simple func pointer) because: the actual func hex beeing defined in a block, the compiler turns it into a delegate. Detail. See also: void foo(In, Out)(Out function(In) f) {} void main() { static int bar(int i) { return 0; } foo(bar); } Bye, bearophile