Hi Brad,
thank you for the suggestion with the workaround. Unfortunately I have a heterogeneous tuple... is there any way to iterate over a heterogeneous tuple? With the homogeneous I had no problem but if I try the same with the heterogeneous I get a compile error.
My intent was to create a ConsoleLogger that is able to take any arguments (primitives, classes, records ...). Then simply redirect the arguments to writeln() which then (if I did not understand anything wrong) uses the writeThis(w:Writer) procedure of classes to print them. Later I wanted to replace the ConsoleLogger with a FileLogger that is able to do log rotating etc... of course hoping that using the writeThis(...) method will help saving some work :) I didn't want to override the proc +(s: string, myObject: object) method (and the other way around ... myObject: object, s: string) in all my classes.
Would there be any way to hold a reference to that args tuple? So that I could create a class LogMessage which holds only the reference to the args... Here is an example but of course with known compile errors because I couldn't find how it could be done or if it even possible yet:
1 class Logger {
2 proc log(msg : LogMessage) {}
3 }
4
5 class LogMessage {
6 // hold reference here... type "args ...k?" is of course invalid, but would it be possible to hold a reference?
7 // I've never seen a declaration of a tuple where the types are not known.
8 var args : args ...k?;
9 }
10
11 class ConsoleLogger : Logger {
12 var lock$ : sync bool = false;
13
14 proc log(msg : LogMessage) {
15 lock$;
16 write("---", here.id, "--- --> ");
17 // tuple doesn't seem to have a predefined method for range, domain or anything?
18 // iterating over it is only allowed if homogeneous, isn't it?
19 for i in msg.args {
20 write(i);
21 }
22 writeln();
23 lock$ = false;
24 }
25 }
2 proc log(msg : LogMessage) {}
3 }
4
5 class LogMessage {
6 // hold reference here... type "args ...k?" is of course invalid, but would it be possible to hold a reference?
7 // I've never seen a declaration of a tuple where the types are not known.
8 var args : args ...k?;
9 }
10
11 class ConsoleLogger : Logger {
12 var lock$ : sync bool = false;
13
14 proc log(msg : LogMessage) {
15 lock$;
16 write("---", here.id, "--- --> ");
17 // tuple doesn't seem to have a predefined method for range, domain or anything?
18 // iterating over it is only allowed if homogeneous, isn't it?
19 for i in msg.args {
20 write(i);
21 }
22 writeln();
23 lock$ = false;
24 }
25 }
Best regards,
Marco
Gesendet: Mittwoch, 04. Februar 2015 um 19:49 Uhr
Von: "Brad Chamberlain" <[email protected]>
An: "Public Chapel Bugs list" <[email protected]>
Cc: "Marco Postigo" <[email protected]>
Betreff: Re: [Chapel-bugs] Shadowing a procedure with variable number of arguments
Von: "Brad Chamberlain" <[email protected]>
An: "Public Chapel Bugs list" <[email protected]>
Cc: "Marco Postigo" <[email protected]>
Betreff: Re: [Chapel-bugs] Shadowing a procedure with variable number of arguments
Hi Marco -- [I accidentally forgot to include the chapel-bugs mailing list on my response to Marco yesterday. Re-sending here to keep the archives accurate.] Thanks for boiling this down to a simple case. It does appear that this is a bug, and one that I don't believe we were aware of previously (in a quick look, I didn't find any references to it). I'm not aware of any reason that Chapel should not support this offhand, so plan to file this in our testing system unless you have any objections to my capturing your test case. Experimenting briefly, I found that it is possible to dynamically dispatch on a tuple type, which suggests the following possible workaround for the time being: -------- class Logger { // // BLC: Avoid reliance on dynamic dispatch for the varargs call by // only defining it in the parent class. The 'args' argument // is a tuple that bundles up the varargs, so pass that tuple // along to a helper function. // proc log(args...?k) { log_help(args); } // // BLC: Make a helper function that accepts a homogeneous tuple // (though it could probably be heterogeneous as well?). // proc log_help(args) where isHomogeneousTuple(args) { writeln("Logger#log ..."); } } class ConsoleLogger : Logger { var lock$ : sync bool = false; // // BLC: And ditto for the subclass // proc log_help(args) where isHomogeneousTuple(args) { lock$; write("---", here.id, "--- --> "); for param i in 1..1 { write(args(i)); } writeln(); lock$ = false; } } var consoleLogger : Logger = new ConsoleLogger(); consoleLogger.log("hello"); // // BLC: Add a second example to be sure: // consoleLogger = new Logger(); consoleLogger.log("hello"); -------- Output is: ---0--- --> hello Logger#log ... -------- Hopefully this will work for you -- please give a shout if it doesn't. I'll mention in passing (for the second time this week, I'm embarrassed to say) that the OOP features of Chapel have not received the attention that the parallel/locality features have, and that we're currently undergoing an ongoing effort to beef them up. Support for static methods/members is something that's on that TODO list, though it's not currently being actively worked on. Thanks, -Brad -------- Original Message -------- Subject: [Chapel-bugs] Shadowing a procedure with variable number of arguments Date: Sat, 31 Jan 2015 23:46:18 +0100 From: Marco Postigo To: Hello again :) I just wanted to create a class Logger which has some subclasses (e.g. NoOpLogger that does nothing, ConsoleLogger that logs to console, FileLogger etc.). Because there are no static methods and with that the ability to make a singleton object I've handed the object through those classes that needs logging. Then I noticed that if I just specify that the type must be Logger or a subclass of it that always the log(...) procedure of the superclass Logger were invoked, thus it seems to be not possible to shadow a proc with a variable number of arguments? I've written a short example that should illustrate my problem: 1 class Logger { 2 proc log(args ...?k) {writeln("Logger#log ...");} 3 } 4 5 class ConsoleLogger : Logger { 6 var lock$ : sync bool = false; 7 8 proc log(args ...?k) { 9 lock$; 10 write("---", here.id, "--- --> "); 11 for param i in 1..k { 12 write(args(i)); 13 } 14 writeln(); 15 lock$ = false; 16 } 17 } 18 19 var consoleLogger : Logger = new ConsoleLogger(); 20 consoleLogger.log("hello"); Output: Logger#log ... --> the implementation in the superclass Logger. Kind regards, Marco
------------------------------------------------------------------------------ Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________ Chapel-bugs mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/chapel-bugs
