CoSVON 〜 Yokohama.rb #40 2014.1.11

問題

CoSVON (Comma Separated Value Object Notation ) という記法を以下に定義する。

この仕様に従い、

という2つの機能を持った gem を作れ。

大雑把な話

要するに。

という話。

詳細

外形

CoSVON は、CSV である。CSV として読むことができる。文字のエスケープなどの仕様は CSV に準ずる。
ファイルの読み書きを行う場合は文字コードが問題になるが、US-ASCII 互換で、文字コード 0x20〜0x7e 、改行、タブ だけからなる文字列(以下、「きれいな文字列」と呼ぶ)に対応すれば良い。

保存できる値

ひとつの CoSVON 文字列は、ひとつの Hash を保存したものになる。 Hash のキーと値はいずれも empty ではない文字列 でなければならない。 ( 「きれいな文字列」 に限定してよい )
また、Hash は空ではないとする。
想定外のオブジェクトを保存しようとした場合の動作は未定義(つまり、例外を投げてもいいし、to_s か何かで適当にあしらってもよい)。

構造

最初の行には CoSVON:0.1 と、書かれている。また、
CoSVON:0.1,,,"",, のように、コンマや、空のセルが何個か続いていても良い。
言い換えると。
最初の行の最初のセルには CoSVON:0.1 と書かれており、それ以外のセルは、空である。

2行目以降は key-value pair になっており、最初のセルがキー、キーのセルの右に値がある。
値のあるセルの右には、セルがないか、空のセルがある。
値のあるセルの右に空でないセルがあった場合の動作は未定義(つまり、例外を投げてもいいし、気づかずに読み込んだりしてもよい)
最後に、空のセルのみからなる行が何行か続いている可能性がある。

保存時の動作

ruby の場合は Hash に順序があるが、保存時にその順序通りに保存しなくても良い。

保存時にはセルを二重引用符で囲んでも良いし、囲まなくても良い。

読み込み時の動作

ruby の場合は Hash に順序があるが、読み込み時にCSV上の順序どおりの Hash にならなくてもよい。
また、保存したものを読み込んだ場合に、保存前の順序を再現する必要もない。
先頭の CoSVON:0.1 がない場合や cosvon:0.1.1 のような惜しい内容の場合の動作は未定義。
冗長な空のセルがあった場合は無視すること。

事例

下表の見方。
「ruby」の欄のオブジェクトを CoSVON としてシリアライズすると「CoSVON」の欄にある文字列になる(かもしれない)。
逆に「CoSVON」の欄の文字列を読むと「ruby」の欄のオブジェクトになる(かもしれない)。
また、「CoSVON」の欄にある文字列を CSV とみなして表計算ソフトで読むと「表」の欄にあるような雰囲気になる。
「かもしれない」と何度か書いたのは、保存時には Hash の順序、二重引用符や空のセルの有無という自由が、読み込み時には Hash の順序という自由があるので、一意に定まらないからである。

ruby CoSVON
{
  "DreamCast"=>"SEGA",
  "HI-Saturn"=>"Hitachi",
  "FamiconTV"=>"Sharp",
}
CoSVON:0.1
DreamCast,SEGA
HI-Saturn,Hitachi
FamiconTV,Sharp
CoSVON:0.1
 
DreamCast
SEGA
HI-Saturn
Hitachi
FamiconTV
Sharp
{
  "foo"=>"bar",
}
CoSVON:0.1
foo,bar
CoSVON:0.1
 
foo
bar
{
  "comma"=>"[,]",
  "dq"=>'["]',
  "n"=>"[\n]",
  "tab"=>"[\t]",
}
CoSVON:0.1
comma,"[,]"
dq,"[""]"
n,"[
]"
tab,[	]
CoSVON:0.1
 
comma
[,]
dq
["]
n
[
]
tab
[	]
{
  "SH3"=>"Super Hitachi 3",
  "ATOK"=>"Awa TOKushima",
  "ICU" => "Isolated Crazy Utopia",
  "BING"=>"Bing Is Not Google",
}
CoSVON:0.1
SH3,Super Hitachi 3
ATOK,Awa TOKushima
ICU,Isolated Crazy Utopia
BING,Bing Is Not Google
CoSVON:0.1
 
SH3
Super Hitachi 3
ATOK
Awa TOKushima
ICU
Isolated Crazy Utopia
BING
Bing Is Not Google
{
  "Google"=>"Chrome",
  "Apple"=>"Safari",
  "Opera"=>"Opera",
  "Mozilla"=>"Firefox"
}
CoSVON:0.1,,,
Google,Chrome,,
Apple,Safari,"",
Opera,Opera,,""
Mozilla,Firefox,"",""
,,,
,,,
,,,
CoSVON:0.1
 
 
 
Google
Chrome
 
 
Apple
Safari
 
 
Opera
Opera
 
 
Mozilla
Firefox
 
 
 
 
 
 
 
 
 
 
 
 
 
 
{
  "no DQ"=>"foo",
  "with DQ"=>"foo",
  "inner DQ"=>"foo\"bar",
  "many DQs"=>"\"\"\"\"\"\"\"\"\""
}
CoSVON:0.1
no DQ,foo
with DQ,"foo"
inner DQ,"foo""bar"
many DQs,""""""""""""""""""""
CoSVON:0.1
 
no DQ
foo
with DQ
foo
inner DQ
foo"bar
many DQs
"""""""""
{
  "no extra comma"=>"hoge",
  "extra comma"=>"fuga",
  "extra comma with DQ"=>"piyo",
  "many extra commas"=>"moge"
}
CoSVON:0.1
no extra comma,hoge
extra comma,fuga,
extra comma with DQ,piyo,""
many extra commas,moge,,,,,,,
"",""
,,
,"",
CoSVON:0.1
 
 
 
 
 
 
 
 
no extra comma
hoge
 
 
 
 
 
 
 
extra comma
fuga
 
 
 
 
 
 
 
extra comma with DQ
piyo
 
 
 
 
 
 
 
many extra commas
moge
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

補足