I’ve just pushed a new version, 4.23, of Fish to Github.
It contains three changes:
- It now shows non-primitive tag values when they are textual, where before it simply showed their MIME type and size.
- It allows standard input (stdin) to be used to specify long string values for tags, which are then written, by default, with MIME type text/plain.
- Where previously it used {...} to denote tag values that are sets of strings (both for input and output), it now uses [...] instead, reflecting a forthcoming change to the API. The change is that Fluidinfo’s primitive compound values will transmogrify from unordered sets of strings to ordered lists of strings. I will blog separately about that when the release occurs. (The change to Fish is backwards compatible, and braces will still be allowed on input.)
I’ll explain a little more about the first two changes.
In the early days of Fluidinfo, almost all tag values were primitive, i.e. they were either numbers, strings, booleans, sets of strings or valueless (NULL, if you prefer). However, the API has always supported tag values with arbitrary MIME types.
Fish largely ignored the MIME type in the early days, and since almost all values were primitive, this was not a great problem. However, as Fluidinfo has developed, ever more non-primitive tag values are used, and the result has been that using Fish’s show, tags and get commands has caused binary data to be dumped to terminals with at best meaningless, and at worst destructive consequences.
As a result, I previously changed Fish to show only information about the size and MIME type for non-primitive tag values. For example:
$ fish show abouttag image/red-spinner.gif
Object with about="abouttag":
/njr/image/red-spinner.gif = <Non-primitive value of type image/gif (size 3208)>
While this is good for MIME types such as GIF, it is less useful for textual MIME types. For example, instead of using primitive strings for Fluidinfo’s record of its API version and release date, the team decided to use MIME type text/plain so that these show up nicely in browers, as you can verify by visiting:
But with the old Fish behaviour, this meant that the result was the following, less than helpful, output:
$ fish show fluidinfo /fluiddb/version /fluiddb/release-date
Object with about="fluidinfo":
/fluiddb/version = <Non-primitive value of type text/plain (size 4)>
/fluiddb/release-date = <Non-primitive value of type text/plain (size 20)>
So with the change in 4.23, Fish now provides more helpful output whenever it recognizes a MIME type as textual:
$ fish show fluidinfo /fluiddb/version /fluiddb/release-date
Object with about="fluidinfo":
/fluiddb/version = "1.13"
/fluiddb/release-date = "2011-12-02T02:28:17Z"
I added the -f flag to Fish’s tag command the other day to allow the value of a tag to be set from a file. This left the slightly anomalous situation that when -f was used, any value specified would be taken as a filename, but any valueless tags specified were simply set as old-style valueless tags.
Since that useful change, I was reflecting on two further anomalies. First, in Unix, it is usually possible to use standard input instead of a file, which is helpful both for pipelining data and for typing multi-line input. Fish provided no mechanism for this. Secondly, there is no easy way in Fish of directly specifying a multi-line string value.
I realised that all three of these anomalies can be pleasingly remedied by changing things so that when a valueless tag is given to Fish’s tag command, in combination with the -f flag, Fish will read stdin to get a value for the tag. (If more than one tag is specified this way, the same value from stdin is be used for all of them.) By default, the MIME type will be set to text/plain, though the -M flag can be used to specify something different.
So that’s what I’ve done. Here is an example:
$ fish tag -f foo foo
This is line one.
This is line two.
...and that's your lot!
^D
$ fish show foo foo
Object with about="foo":
/njr/foo = "This is line one.
This is line two.
...and that's your lot!
"
For those less familiar with the Unix command line, here I typed fish tag -f foo foo at the command promt ($). Fish then read what I typed until I terminated the input with the end-of-file character (CTRL+D on Unix, including Mac OS X, CTRL+Z on Windows). The input was then used as the tag value.
Here is an example using a pipe:
$ cat > foo.txt
One
Two
Buckle my shoe
$ cat foo.txt | fish tag -f foo foo
$ fish show foo foo
Object with about="foo":
/njr/foo = "One
Two
Buckle my shoe
"