Also, I'm taking the opportunity of being currently unemployed to modernize the Act hosting and finally migrate to the PSGI port. So adding new features (like QR codes badges) should be easier and faster.
]]>I agree that some of these steps could be left out of PCLI, to avoid it being too broad. On the other end, if it is too small, will it be useful at all?
I didn't include input and output because I couldn't see the point of passing the corresponding file handles. Thinking again, I can see some use cases, but that feel technically awkward.
However I had forgotten exit codes, silly me.
Your modules are interesting. I'll have to take a serious look at them.
Thanks for your comment.
I don’t like environment variables, because it feels like some king of “hidden” information. Also, you can’t commit them. But many programs and modules make use of them, hence my including them in the discussion.
I think that was what made Matt angry: there are hundreds of modules to parse options, each with oh so slightly different features. Hence the idea of something that would possibly end this mess (quoting Matt with more urban words ;-)
But please note that the idea of PCLI is not to make yet another framework, but to write a specification that describes how things should work. This specification could then be implemented in different modules, and they would all be compatible because they would follow the spec. That’s what PSGI does for web applications. My post was to examine whether it’s actually possible to write such a generic specification.
Your remarks are interesting but I have an even simpler example of “options” for which I don’t know a module on the CPAN that provides a generic framework to handle them: object-verb -based syntax. Think of the Linux ip(8) command:
# ip route add default via 10.0.0.42
Maybe we could find something here similar with the “route handlers” in web apps, and use coderefs. Or see the options as a grammar that we want to describe. In both cases it seems pretty complex to describe, explain, and use.
Regarding I18N, I’d say it’s out of the PCLI scope, just as it is out of PSGI or even HTTP scope: it’s about describing how things work, not standardize the messages.
I included the step 3 because it provides a shortcut to avoid doing useless processing.
Steps 7 to 9 stretch the things a bit far. I agree they are useless in short-term programs. But they are needed in long-term programs. I included them in the list because they are useful to determine the scope of a PCLI specification.
To answer your question, I usually stick to Sys::Syslog, which is good enough, shipped with Perl and with a stable API. In fact, for the programs I wrote over the past years, the modules shipped with Perl were all good enough: Getopt::Long, Pod::Usage, Sys::Syslog. Only adding Proc::Daemon and Proc::PID::File for daemons.
Thanks for your detailed comment.
]]>I may be wrong, but my guess is that you don't have enough information about the encoding you receive, and the round-trip conversion won't be 100% safe. Especially because you need to know the encoding of the underlying filesystem of the volume hosting the file. Different OS have different formats (Windows uses UTF-16, most Unix seem to use UTF-8), but also different flavours (IIRC, OSX uses Canonical Form D, or something).
All in all, it seems jut safer to keep the file names as is.
Encoding of the environment variables, as you noted, is a wild guess. And about the configuration file, it means that the specification would need to impose a particular format, which it should not. I find .INI files very useful for most of programs I wrote over the past years, but I can see the need for more complex formats like Apache-like or even YAML. (or even XML, if you're into that.)
A very interesting idea. We were a few (BooK, cmaussan, niels and myself) to begin thinking about what this PCLI specification could look like. I wrote down on paper what I've been doing in the numerous CLI programs (for a broad value of the terms) I wrote over the past years.
A CLI program has to go through these steps:
%ENV
); errors may be warned about or fatal@ARGV
); errors are fatalPod::Usage
INT
, TERM
, QUIT
, HUP
), usually for daemons, but can also be useful for programs running for a long timeNow, I didn't know what PSGI looked like (I'm a sysdev, not a webdev). Today, I read the specification, and it confirmed what I had already identified: yes, PSGI is brilliantly "simple" because it was written by people knowing very well this field, helping themselves with the experience of similar specifications (WSGI, Rack, JSGI). But it is also simple because it is a protocol built on top of a protocol (HTTP), built on top of a protocol (TCP), built... At PSGI level, there's just a bidirectional channel with data going in both directions. And it's platform agnostic.
However, in the CLI world (and let's limit ourselves to the Unix world for the sake of simplicity), we have multiple channels of input (%ENV
, options, configuration file(s), STDIN
, input data files, signals) and output (STDOUT
, STDERR
, logging, output data files), and no standardized protocol of any kind.
Now, I'm afraid that either we try to cover most of the features we need, and we end up with a specification too complex, or we limit to a subset of the features, and we end up with a specification too simple to be actually useful.
Did I miss something? Was Matt too optimistic or am I once again too pessimistic?
]]>use 5.010;$:=v117.116.102.56;eval"use encoding $:=>STDOUT=>'$:'";$c=
1e4;$i=-1;$b=0x3041;@f=(20,71,41,72);while($i<4){@v=map+int rand(86)
,1..4;@v[0..$i]=@f[0..$i]if$i>0;$c--if$c&&$v[1+$i]%4==0;$c=+5e3,$i++
if$c==0&&$v[$i]==$f[$i];print+chr($b+$_)for@v;print"\r"}print"\n\x4"
(I know, it barely deserve the title "obfuscation", but I don't have BooK's or cognominal's experience in this domain. At least, it's correctly justified.)
The aim of this code is to print, in a funny way, 5 important characters. The first 4 are the Japanese characters さよなら (sayonara). The last character is ASCII 0x04, EOT (End of Transmission). I'll assume I need not explain the meaning and references.
Now, if I began writing about this code, it's to explain the mistake I did in it. Can you see it?
It's not very apparent because the code basically works. In fact, it works faster than I expected. This is the problem. On my PowerBook G4, it takes a bit more than 5 sec to execute. On a more recent computer, usually less than a second.
The reason? I stupidly used loops to simulate sleeps. This is surely lesson one when making a demo or a game: fix your timestep so the program performs consistently on different platforms. That's not something we're used to think of in sysdev, but that's the basis when making a game.
]]>WRT to your tests, are you testing the code or the data? if the code, why testing against live data? why not keeping some well-known data to provide stable samples to work with?
]]>