Closed Hywan closed 8 years ago
Hello,
I think it's a really nice idea to add Output
layer here. We can handle more nicely the verbosity or the output destination. Also rely on Stream
add powerful capabilities...
Just one question, I saw that there are echo
calls to move Cursor
, set Window
size... Can it be a problem to redirect the output in a file for that cases ? These cases are more for utils than message...
@shulard The output class will not be responsible to manage the verbosity. We have to check whether Console::isDirect(STDOUT)
returns true to run the cursor API for instance. This is not part of this issue. However, you can open another issue if you want to.
So I would argue that adding this dependency will not hurt anyone.
:+1:
This seems to be a really nice feature, as @Hywan said, it will solve issues (and simplify code) on the Console contributions:
This will also allow us to bridge the new Output
interface to Symfony's output and provide new stuff like piping/redirecting outputs.
-- EDIT --
I forgot to mention this comment: https://github.com/hoaproject/Test/pull/46#discussion_r40193040 Introducing the Output
class will also let us solve this issue.
@jubianchi Good. So let's go!
Oh, Hoa\Stream
is already a dependency of Hoa\Console
, so it's fine!
Now
We use
echo
to print strings on the output of the current program.Issue
Sometimes we don't want to
echo
but get the output, compute it somewhere with something and delegate the output. For instance, with the Symfony console bridge official contribution, we plug to the Symfony console output object (/cc @jubianchi).Another issue happens recently with #52. TMUX(1) has some issues with specific control sequences. There is a solution to by-pass TMUX(1) and send control sequences to the upper terminal directly, see #53 for more explanation.
Proposal
We must introduce an output object. How though? This is a coding design discussion.
Output
class and objectI would go for a static
Output
class and use it everywhere instead ofecho
but this is no easily extensible, nor testable. So we should for an object instead of a class. We do not want to create one instance each time we call the cursor or window API, this would increase memory. Since #51 introducesConsole::getStdin
, we can imagine introducingConsole::getStdout
and compute an instance ofOutput
. To be able to extendHoa\Console
to delegate outputs, we can imagineConsole::setStdout(Output $output)
.What interface
Output
implements?Thus, all
echo
s could be replaced byConsole::getStdout()->writeAll()
. WhywriteAll
? This is the typical naming fromHoa\Stream
interfaces. But I am not likely to implement theHoa\Stream\IStream\Out
interface right now. Or maybe I would be likely. This is one more dependency and it requires to implementwrite
,writeLine
etc. It makes a lot of sense!However, what is the impact of adding a new dependency?
Hoa\Stream
is almost always a dependency, except if our program does not need any external resources (like files, sockets & co.), which is very rare. So I would argue that adding this dependency will not hurt anyone.Conclusion
I would like the opinion of several @hoaproject/hoackers please.
Appendix A
Here is a draft for the
Output
object:Here is a draft for the new
Hoa\Console
methods:Bonus with outputs and redirection
How to implement redirections (rhetorical question)? Either we add an argument to the
Output
class constructor representing a stream or a resource, or because we are usingHoa\Stream\IStream\Out
, we can do this:and then:
to redirect all outputs to the
/tmp/a
file!Tip: Using
echo
is strictly equivalent toHoa\Console::setOutput(new Hoa\File\Write(1));
, which is equivalent toHoa\Console::setOutput(new Hoa\File\Write('php://fd/1'));
, which is equivalent toHoa\Console::setOutput(new Hoa\File\Write('php://output'));
.Next
Output
likeenableDemultiplexerByPassing
. This will re-solve #53 more elegantly.Input
class? Not sure. Need more grooming.