Johan Sundström and I are about to make some attempts to make a Pike Cookbook. Regardless if we have the strength to make it all the way into a book or not, I think this is a good project to spend some time on. While we can get some ideas what this cookbook should contain by looking at e.g. the Perl and Python cookbooks, much of what is in them deals with how to solve problems that are inherit in the langauges themselves. As a consequence we would like to know what problems you have with Pike and how you solve them (if you have). Johan and I will set up some sort of database or repository and collect the responses as well as inserting our own stuff. We will probably aim at getting the same basic layout as in the present cookbooks in the database, e.g.:
----------------------8<-------------------- Title: Hello World Contributor: Martin Nilsson Problem: Make a program that prints Hello World! and exits.
Solution: int main() { write("Hello World!\n"); }
Discussion:
The above code is probably the smallest possible program, counting tokens, that solves the problem. Without unessecary white spaces this is 36 characters. A more "proper" solution would however be:
int main(int argc, array(string) args, array(strings) env) { write("Hello World!\n"); return 0; }
Here all the passed arguments are received in fairly typed variables, which you don't have to do. I say fairly typed, because there is always at least one argument passed to the program, the path of the program itself, so argc could be declared as int(1..). After the interesting code has been executed 0 is returned, as result code of the program. There is an implicit return 0; at the end of every function, which we relied on in the first code. Since the return value is always 0, the main function could be declared to return int(0..0).
Since the Pike master only feeds positive return values from main into an exit call, return 0; can be replaced with exit(0);. While this doesn't really matter here it does matter if we chose another aproach for this program all together. When Pike executes a script it first loads the file and compiles it into a program. Then it instansiate an object from the program and call its main function. Thus we can put our code in the object constructor and when finished exit Pike, so it doesn't find out that the main function is missing.
void create() { write("Hello World!\n"); exit(0); } ----------------------8<--------------------
So please give us your thoughts, problems and solutions, either here or as private messages.
Since the Pike master only feeds positive return values from main into an exit call, [...]
This should say "non-negative", not "positive". 0 is not a positive number.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-04-15 20:30: Subject: Pike Cookbook
Johan Sundström and I are about to make some attempts to make a Pike Cookbook. Regardless if we have the strength to make it all the way into a book or not, I think this is a good project to spend some time on. While we can get some ideas what this cookbook should contain by looking at e.g. the Perl and Python cookbooks, much of what is in them deals with how to solve problems that are inherit in the langauges themselves. As a consequence we would like to know what problems you have with Pike and how you solve them (if you have). Johan and I will set up some sort of database or repository and collect the responses as well as inserting our own stuff. We will probably aim at getting the same basic layout as in the present cookbooks in the database, e.g.:
----------------------8<-------------------- Title: Hello World Contributor: Martin Nilsson Problem: Make a program that prints Hello World! and exits.
Solution: int main() { write("Hello World!\n"); }
Discussion:
The above code is probably the smallest possible program, counting tokens, that solves the problem. Without unessecary white spaces this is 36 characters. A more "proper" solution would however be:
int main(int argc, array(string) args, array(strings) env) { write("Hello World!\n"); return 0; }
Here all the passed arguments are received in fairly typed variables, which you don't have to do. I say fairly typed, because there is always at least one argument passed to the program, the path of the program itself, so argc could be declared as int(1..). After the interesting code has been executed 0 is returned, as result code of the program. There is an implicit return 0; at the end of every function, which we relied on in the first code. Since the return value is always 0, the main function could be declared to return int(0..0).
Since the Pike master only feeds positive return values from main into an exit call, return 0; can be replaced with exit(0);. While this doesn't really matter here it does matter if we chose another aproach for this program all together. When Pike executes a script it first loads the file and compiles it into a program. Then it instansiate an object from the program and call its main function. Thus we can put our code in the object constructor and when finished exit Pike, so it doesn't find out that the main function is missing.
void create() { write("Hello World!\n"); exit(0); } ----------------------8<--------------------
So please give us your thoughts, problems and solutions, either here or as private messages.
/ Martin Nilsson (har bott i google)
It is better than the first version of that sentence, though. (Since the Pike master only feeds return values from main into an exit call...)
/ Martin Nilsson (har bott i google)
Previous text:
2003-04-15 20:34: Subject: Pike Cookbook
Since the Pike master only feeds positive return values from main into an exit call, [...]
This should say "non-negative", not "positive". 0 is not a positive number.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
What about backend-code activated by 'return -1;'? Should that be mentioned here?
/ Peter Lundqvist (disjunkt)
Previous text:
2003-04-15 20:34: Subject: Pike Cookbook
Since the Pike master only feeds positive return values from main into an exit call, [...]
This should say "non-negative", not "positive". 0 is not a positive number.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
loads the file and compiles it into a program. Then it instansiate an
.^ s
Anyway, I'm really glad to hear these plans!
/ Peter Lundqvist (disjunkt)
Previous text:
2003-04-15 20:30: Subject: Pike Cookbook
Johan Sundström and I are about to make some attempts to make a Pike Cookbook. Regardless if we have the strength to make it all the way into a book or not, I think this is a good project to spend some time on. While we can get some ideas what this cookbook should contain by looking at e.g. the Perl and Python cookbooks, much of what is in them deals with how to solve problems that are inherit in the langauges themselves. As a consequence we would like to know what problems you have with Pike and how you solve them (if you have). Johan and I will set up some sort of database or repository and collect the responses as well as inserting our own stuff. We will probably aim at getting the same basic layout as in the present cookbooks in the database, e.g.:
----------------------8<-------------------- Title: Hello World Contributor: Martin Nilsson Problem: Make a program that prints Hello World! and exits.
Solution: int main() { write("Hello World!\n"); }
Discussion:
The above code is probably the smallest possible program, counting tokens, that solves the problem. Without unessecary white spaces this is 36 characters. A more "proper" solution would however be:
int main(int argc, array(string) args, array(strings) env) { write("Hello World!\n"); return 0; }
Here all the passed arguments are received in fairly typed variables, which you don't have to do. I say fairly typed, because there is always at least one argument passed to the program, the path of the program itself, so argc could be declared as int(1..). After the interesting code has been executed 0 is returned, as result code of the program. There is an implicit return 0; at the end of every function, which we relied on in the first code. Since the return value is always 0, the main function could be declared to return int(0..0).
Since the Pike master only feeds positive return values from main into an exit call, return 0; can be replaced with exit(0);. While this doesn't really matter here it does matter if we chose another aproach for this program all together. When Pike executes a script it first loads the file and compiles it into a program. Then it instansiate an object from the program and call its main function. Thus we can put our code in the object constructor and when finished exit Pike, so it doesn't find out that the main function is missing.
void create() { write("Hello World!\n"); exit(0); } ----------------------8<--------------------
So please give us your thoughts, problems and solutions, either here or as private messages.
/ Martin Nilsson (har bott i google)
My biggest beef with Pike is that I can't get reliable Expect-like process control. Controlling things like yppasswd with create_process() and setsid does not work on both Solaris and Linux. I have spent hours reading the C code of both Pike and Expect trying to figure out what they do diffrently. So far without any luck.
I'm also starting to think that there could be a lower typing-overhead convienece version of Process.create_process(). I'm seeing a little bit to much of this in my scripts:
void timeout_handler(int signal) { write_errorlog("FATAL: operation timed out on SIGALRM. Aborting.\n"); exit(10); }
int main() { ...
alarm(180); /* 3 minutes should be enough for everyone... */
signal(signum("SIGALRM"), timeout_handler);
Stdio.File mystdout = Stdio.File(); Stdio.File mystderr = Stdio.File(); Stdio.File mystdin = Stdio.File(); object p=Process.create_process( ({ "/opt/timekeeper/settime", "-d", domain }), ([ "stdout" : mystdout->pipe(), "stderr" : mystderr->pipe(), "stdin" : mystdin->pipe(), ]) ); mystdin->write( time +"\n" ); int error = p->wait(); if(error) { write_errorlog("so: %O", mystdout->read(); write_errorlog("se: %O", mystderr->read(); fatalexit(11, "FATAL: Error %d for domain %s", error, domain ); } else { write_log("Domain %s worked out fine.", domain"); }
alarm(0);
... }
/ Peter Bortas
Previous text:
2003-04-15 20:30: Subject: Pike Cookbook
Johan Sundström and I are about to make some attempts to make a Pike Cookbook. Regardless if we have the strength to make it all the way into a book or not, I think this is a good project to spend some time on. While we can get some ideas what this cookbook should contain by looking at e.g. the Perl and Python cookbooks, much of what is in them deals with how to solve problems that are inherit in the langauges themselves. As a consequence we would like to know what problems you have with Pike and how you solve them (if you have). Johan and I will set up some sort of database or repository and collect the responses as well as inserting our own stuff. We will probably aim at getting the same basic layout as in the present cookbooks in the database, e.g.:
----------------------8<-------------------- Title: Hello World Contributor: Martin Nilsson Problem: Make a program that prints Hello World! and exits.
Solution: int main() { write("Hello World!\n"); }
Discussion:
The above code is probably the smallest possible program, counting tokens, that solves the problem. Without unessecary white spaces this is 36 characters. A more "proper" solution would however be:
int main(int argc, array(string) args, array(strings) env) { write("Hello World!\n"); return 0; }
Here all the passed arguments are received in fairly typed variables, which you don't have to do. I say fairly typed, because there is always at least one argument passed to the program, the path of the program itself, so argc could be declared as int(1..). After the interesting code has been executed 0 is returned, as result code of the program. There is an implicit return 0; at the end of every function, which we relied on in the first code. Since the return value is always 0, the main function could be declared to return int(0..0).
Since the Pike master only feeds positive return values from main into an exit call, return 0; can be replaced with exit(0);. While this doesn't really matter here it does matter if we chose another aproach for this program all together. When Pike executes a script it first loads the file and compiles it into a program. Then it instansiate an object from the program and call its main function. Thus we can put our code in the object constructor and when finished exit Pike, so it doesn't find out that the main function is missing.
void create() { write("Hello World!\n"); exit(0); } ----------------------8<--------------------
So please give us your thoughts, problems and solutions, either here or as private messages.
/ Martin Nilsson (har bott i google)
setsid doesn't do what you need, you need a tty/pty pair to do that stuff. I don't think anybody would object if you implement tty/pty allocation. Hint: Originally I envisioned it being an argument to Stdio.File()->pipe().
/ Fredrik (Naranek) Hubinette (Real Build Master)
Previous text:
2003-04-15 21:17: Subject: Pike Cookbook
My biggest beef with Pike is that I can't get reliable Expect-like process control. Controlling things like yppasswd with create_process() and setsid does not work on both Solaris and Linux. I have spent hours reading the C code of both Pike and Expect trying to figure out what they do diffrently. So far without any luck.
I'm also starting to think that there could be a lower typing-overhead convienece version of Process.create_process(). I'm seeing a little bit to much of this in my scripts:
void timeout_handler(int signal) { write_errorlog("FATAL: operation timed out on SIGALRM. Aborting.\n"); exit(10); }
int main() { ...
alarm(180); /* 3 minutes should be enough for everyone... */
signal(signum("SIGALRM"), timeout_handler);
Stdio.File mystdout = Stdio.File(); Stdio.File mystderr = Stdio.File(); Stdio.File mystdin = Stdio.File(); object p=Process.create_process( ({ "/opt/timekeeper/settime", "-d", domain }), ([ "stdout" : mystdout->pipe(), "stderr" : mystderr->pipe(), "stdin" : mystdin->pipe(), ]) ); mystdin->write( time +"\n" ); int error = p->wait(); if(error) { write_errorlog("so: %O", mystdout->read(); write_errorlog("se: %O", mystderr->read(); fatalexit(11, "FATAL: Error %d for domain %s", error, domain ); } else { write_log("Domain %s worked out fine.", domain"); }
alarm(0);
... }
/ Peter Bortas
Not entirely, no, but combining it with some plain Pike should do it:
array(Stdio.File) make_ptypair() { Stdio.File pf = Stdio.File(), tf = Stdio.File(); foreach(get_dir("/dev/"), string pty_name) if(pty_name[..2]=="pty" && pf->open("/dev/"+pty_name, "rw")) { if(tf->open("/dev/t"+pty_name[1..], "rw")) return ({ pf, tf }); pf->close(); } return 0; }
int main() { string luser = "fooson"; array(Stdio.File) f = make_ptypair(); object p = Process.create_process(({"passwd", "-r", "nis", luser }), (["setsid":f[1], "stdin":f[1], "uid":luser])); f[1]->close(); f[0]->write("hejhopp\n"); f[0]->write("hejhopp\n"); return p->wait(); }
(I haven't checked f[0] and f[1] here, so there might possibly be some confusion in the code. Please ignore that for now. :) )
And actually does on some system. I agree that is something that should be built in, but as long as I can't come up with the reason the current solution isn't working there isn't much point in making a permanent one.
/ Peter Bortas
Previous text:
2003-04-16 02:47: Subject: Pike Cookbook
setsid doesn't do what you need, you need a tty/pty pair to do that stuff. I don't think anybody would object if you implement tty/pty allocation. Hint: Originally I envisioned it being an argument to Stdio.File()->pipe().
/ Fredrik (Naranek) Hubinette (Real Build Master)
void create() { write("Hello World!\n"); exit(0); }
Somehow I don't like that version too much. It smells like "violating the rules by exploiting an implementation detail". But then, Pike is (to date) defined by its implementation, so "the rules" means as much as anything the implementation will swallow (unfortunately so?).
More to the point, my choice would have been to have the master check for the presence of main() in a script, before cloning an object from the compiled program, rather than passing argv to create()... but maybe I'm just nitpicking...
/rjb
/ rjb
Previous text:
2003-04-15 20:30: Subject: Pike Cookbook
Johan Sundström and I are about to make some attempts to make a Pike Cookbook. Regardless if we have the strength to make it all the way into a book or not, I think this is a good project to spend some time on. While we can get some ideas what this cookbook should contain by looking at e.g. the Perl and Python cookbooks, much of what is in them deals with how to solve problems that are inherit in the langauges themselves. As a consequence we would like to know what problems you have with Pike and how you solve them (if you have). Johan and I will set up some sort of database or repository and collect the responses as well as inserting our own stuff. We will probably aim at getting the same basic layout as in the present cookbooks in the database, e.g.:
----------------------8<-------------------- Title: Hello World Contributor: Martin Nilsson Problem: Make a program that prints Hello World! and exits.
Solution: int main() { write("Hello World!\n"); }
Discussion:
The above code is probably the smallest possible program, counting tokens, that solves the problem. Without unessecary white spaces this is 36 characters. A more "proper" solution would however be:
int main(int argc, array(string) args, array(strings) env) { write("Hello World!\n"); return 0; }
Here all the passed arguments are received in fairly typed variables, which you don't have to do. I say fairly typed, because there is always at least one argument passed to the program, the path of the program itself, so argc could be declared as int(1..). After the interesting code has been executed 0 is returned, as result code of the program. There is an implicit return 0; at the end of every function, which we relied on in the first code. Since the return value is always 0, the main function could be declared to return int(0..0).
Since the Pike master only feeds positive return values from main into an exit call, return 0; can be replaced with exit(0);. While this doesn't really matter here it does matter if we chose another aproach for this program all together. When Pike executes a script it first loads the file and compiles it into a program. Then it instansiate an object from the program and call its main function. Thus we can put our code in the object constructor and when finished exit Pike, so it doesn't find out that the main function is missing.
void create() { write("Hello World!\n"); exit(0); } ----------------------8<--------------------
So please give us your thoughts, problems and solutions, either here or as private messages.
/ Martin Nilsson (har bott i google)
This was actually discussed a while back when the clumsiness of the current main prototype was on topic. Instead of doing smart stuff with the main function call it was suggested that create was extended to get the information it could not retrieve in other ways (env can be retrieved from getenv and argc is of course sizeof(argv)). It can even be said that having a main function at all is a convenience detail, since no one has been trying to hide the fact that all programs are turned into objects, and thus have a create call.
/ Martin Nilsson (har bott i google)
Previous text:
2003-04-16 15:00: Subject: Pike Cookbook
void create() { write("Hello World!\n"); exit(0); }
Somehow I don't like that version too much. It smells like "violating the rules by exploiting an implementation detail". But then, Pike is (to date) defined by its implementation, so "the rules" means as much as anything the implementation will swallow (unfortunately so?).
More to the point, my choice would have been to have the master check for the presence of main() in a script, before cloning an object from the compiled program, rather than passing argv to create()... but maybe I'm just nitpicking...
/rjb
/ rjb
got anything for that yet?
everytime i spend considerably more time researching how to solve something, then the length of the solution should warant, then the solution deserves to be written down somehwere:
problem: turn time() into an SMTP Date: string
solution: Calendar.now()->format_smtp();
this one was easy, but i actually needed to make a function string get_time(int t); that would take time as an argument.
solution:
string get_time(int t) { return Calendar.Second(t)->format_smtp(); }
now this one took considerably longer to find. as it is absolutely not clear that Second is the only class to take unix time as an argument. (or is it?)
are there other solutions?
greetings, martin.
Well, it's rather logical if you think about it, since UNIX time counts what? Seconds.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-06-01 23:37: Subject: Re: Pike Cookbook
got anything for that yet?
everytime i spend considerably more time researching how to solve something, then the length of the solution should warant, then the solution deserves to be written down somehwere:
problem: turn time() into an SMTP Date: string
solution: Calendar.now()->format_smtp();
this one was easy, but i actually needed to make a function string get_time(int t); that would take time as an argument.
solution:
string get_time(int t) { return Calendar.Second(t)->format_smtp(); }
now this one took considerably longer to find. as it is absolutely not clear that Second is the only class to take unix time as an argument. (or is it?)
are there other solutions?
greetings, martin.
/ Brevbäraren
Well. That's all very nice and so on, but what offset should be used? That is not very obvious - however I have my guesses.
/ Peter Lundqvist (disjunkt)
Previous text:
2003-06-01 23:41: Subject: Re: Pike Cookbook
Well, it's rather logical if you think about it, since UNIX time counts what? Seconds.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
What do you mean, offset? time() doesn't give time with an offset.
/ Mirar
Previous text:
2003-06-01 23:45: Subject: Re: Pike Cookbook
Well. That's all very nice and so on, but what offset should be used? That is not very obvious - however I have my guesses.
/ Peter Lundqvist (disjunkt)
It does too. On my system time() returns a value counting the number of seconds from January 1 1970.
Other theoretical offsets are for instance the year zero for a given calendar.
What I'm saying is that unixtime might not be the only time encountered by pike.
/ Peter Lundqvist (disjunkt)
Previous text:
2003-06-01 23:45: Subject: Re: Pike Cookbook
What do you mean, offset? time() doesn't give time with an offset.
/ Mirar
Of course not. UNIX time is one frequently encountered though, which is why there are special shortcuts for it. If you want to use a different epoch, say my birthday, that's of course possible as well:
Pike v7.4 release 21 running Hilfe v3.5 (Incremental Pike Frontend)
Calendar.Second(1973,06,15,0,0,0)+1000000000;
(1) Result: Second(Mon 21 Feb 2005 1:46:40 MET)
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-06-01 23:52: Subject: Re: Pike Cookbook
It does too. On my system time() returns a value counting the number of seconds from January 1 1970.
Other theoretical offsets are for instance the year zero for a given calendar.
What I'm saying is that unixtime might not be the only time encountered by pike.
/ Peter Lundqvist (disjunkt)
A note should be added here: It doesn't count leap seconds. :-)
/ Mirar
Previous text:
2003-06-01 23:57: Subject: Re: Pike Cookbook
Of course not. UNIX time is one frequently encountered though, which is why there are special shortcuts for it. If you want to use a different epoch, say my birthday, that's of course possible as well:
Pike v7.4 release 21 running Hilfe v3.5 (Incremental Pike Frontend)
Calendar.Second(1973,06,15,0,0,0)+1000000000;
(1) Result: Second(Mon 21 Feb 2005 1:46:40 MET)
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Yes. This fact is convenient when dealing with UNIX time, which doesn't count leap seconds either, but it might affect other schemes negatively.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-06-01 23:58: Subject: Re: Pike Cookbook
A note should be added here: It doesn't count leap seconds. :-)
/ Mirar
I thought you meant offset from UTC.
I've never seen a standardized time based on seconds with any other offset. The >=days types uses julian days (ints or reals), since that makes sense there. The conversion for lesser units works here, though:
Calendar.Second("julian",2345455.7);
(1) Result: Second(Mon 15 Jul 1709 6:00:13 LMT)
Ah, and I found how you specify the time unit:
Calendar.Second("unix",2345455);
(2) Result: Second(Wed 28 Jan 1970 4:30:55 CET)
Calendar.Day("unix",2345455);
(3) Result: Day(Wed 28 Jan 1970)
but it doesn't work for Year(), hmm...
/ Mirar
Previous text:
2003-06-01 23:52: Subject: Re: Pike Cookbook
It does too. On my system time() returns a value counting the number of seconds from January 1 1970.
Other theoretical offsets are for instance the year zero for a given calendar.
What I'm saying is that unixtime might not be the only time encountered by pike.
/ Peter Lundqvist (disjunkt)
By the way, time() returns the number of seconds passed since the introduction of UTC on any system I've seen, except possibly DOS stations with no idea of timezones.
Someone please tell me how I can stop being annoyed at people giving timezones in GMT offsets. :-)
/ Mirar
Previous text:
2003-06-01 23:52: Subject: Re: Pike Cookbook
It does too. On my system time() returns a value counting the number of seconds from January 1 1970.
Other theoretical offsets are for instance the year zero for a given calendar.
What I'm saying is that unixtime might not be the only time encountered by pike.
/ Peter Lundqvist (disjunkt)
that is what made me try Seconds, yes, but on what basis can i assume that the integer being accepted by Calendar.Second(), is unix time_t?
other systems count time differently, and pike being crossplatform, is what makes this non-abvious.
but that is not the problem, and neither do i want to make this into another "docs are bad" discussion, i only wanted to assess the worthiness of this example for a pike cookbook.
greetings, martin.
Your first "recipe" is nicer because it doesn't involve UNIX time (explicitly) at all. But you did say that the second was also necessary. So I assume you already have some idea about its usefulness?
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-06-02 00:32: Subject: Re: Pike Cookbook
that is what made me try Seconds, yes, but on what basis can i assume that the integer being accepted by Calendar.Second(), is unix time_t?
other systems count time differently, and pike being crossplatform, is what makes this non-abvious.
but that is not the problem, and neither do i want to make this into another "docs are bad" discussion, i only wanted to assess the worthiness of this example for a pike cookbook.
greetings, martin.
/ Brevbäraren
the second was necessary because the actual situation was to fix the already existing function get_time(int t) which returned a datestring that was flagged by my spamfilter as being non-compliant.
apart from that, the usefullness would be that in unix time_t is used in a lot of places to store time values (say file access times and such) therefore i see a lot of situation where an existing time value != now needs to be evaluated.
Then I would suggest phrasing the problem as "turn the access¹ time of a file into an STMP date string", and adjusting the solution accordingly. I think a cookbook is much more useful when it shows how to solve actual problems rather than how to handle individual technicalities.
¹ Actually, modification date would probably make more sense.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2003-06-02 00:50: Subject: Re: Pike Cookbook
the second was necessary because the actual situation was to fix the already existing function get_time(int t) which returned a datestring that was flagged by my spamfilter as being non-compliant.
apart from that, the usefullness would be that in unix time_t is used in a lot of places to store time values (say file access times and such) therefore i see a lot of situation where an existing time value != now needs to be evaluated.
/ Brevbäraren
All time-of-day classes (Hour to Fraction) takes unix time as argument. I think I made an attempt to create anything from unixtime, but I forgot how it worked. Is it important?
Calendar.now() creates a Fraction, which is a nanosecond in precision.
/ Mirar
Previous text:
2003-06-01 23:37: Subject: Re: Pike Cookbook
got anything for that yet?
everytime i spend considerably more time researching how to solve something, then the length of the solution should warant, then the solution deserves to be written down somehwere:
problem: turn time() into an SMTP Date: string
solution: Calendar.now()->format_smtp();
this one was easy, but i actually needed to make a function string get_time(int t); that would take time as an argument.
solution:
string get_time(int t) { return Calendar.Second(t)->format_smtp(); }
now this one took considerably longer to find. as it is absolutely not clear that Second is the only class to take unix time as an argument. (or is it?)
are there other solutions?
greetings, martin.
/ Brevbäraren
pike-devel@lists.lysator.liu.se