In some ways, cat is an opposite of tee. Whereas tee reads from a single source and writes to multiple, cat reads from multiple sources including optionally stdin, and writes to a single target, stdout.
Reading from stdin is actually a key difference between cat and echo, in that echo ignores stdin.
# Doesn't work (where's the echo?): cat somefile | echo
However, in this example cat will uselessly write the input back to the output.
# Does work: cat somefile | cat
Initially considered making Grantlee::Cat implement QIODevice so that it too could be written to. That would make it analogous to the unix command, but would make the implementation of Cat more complex. It would need to use a Grantlee::Channel and maybe a Grantlee::Reserviour internally (which I haven’t written yet) and wouldn’t really have any advantages that can’t be solved some other way.
Then I decided that I should make it implement QIODevice anyway, because it would make the title of this blog post funnier.
In the end though I decided that blog titles are not a good yardstick to measure the aptness of a design, so Grantlee::Cat is-a QObject instead.
Once I have Grantlee::Channel written it might actually make sense to be able to write to Cat and be easy to implement, so I might reconsider it then anyway.
Cat reads sequentially from a list of QIODevices and writes to a QIODevice target. The internal implementation is very simple. It uses a Grantlee::Pump pointing at the target, and sets the source of the pump to each source device in the list until the source device is closed.
So Cat is easy to use with readable QIODevices, but if you want to write to Cat (from multiple devices), that’s where Grantlee::Channel will come in.