トップ 最新 追記

日々の破片

Subscribe with livedoor Reader
著作一覧

2020-01-01

_ 初詣

行ったことがないところに行こうということで、気になっていた市谷亀岡八幡宮に行くことにした。なんとなく靖国通りの防衛庁前は路側駐車帯になっていると思ったらそんなことはなく、しょうがないので一度津之守坂から新宿通りに入り、裏側の谷沿いのどこかに100円駐車場があるだろうとあたりをつけて、坂町の適当なところに停めた。祝日30分120円とか信じがたく安い。

で、坂の残りを下ると左型に鳥居が見えたので多分お稲荷さんっぽいから帰りはこっちに寄ろうと話し合って靖国通りに出る。監視カメラとか結構設置してあって、なるほど防衛庁ですなぁと市ヶ谷のほうへ行くと、八幡さまの階段にでんでんと長蛇の列で驚く。行列はいやなので戻って、お稲荷さんで初詣することにする。

横に公園があって、子供が親とブランコでキャーキャー大騒ぎしながら遊んでいて、いかにも町のお稲荷さんで気持ちが良い。

由来が書いてあると読むと、桝箕稲荷神社という名前で、幕府の下賜米を桝で計って配ったのでこの漢字名がついたとかある。元は真須美稲荷のマスミだったのだろうから江戸っぽくておもしろい。

なるほど、かっては外堀から続く川で、城から俵を積んだ船でここらに荷揚げしたのだろうとか考える。楽しい。

お稲荷さんは好きだが、どうせなら、かねてから気になっていた飯田橋と神楽坂の間の山にある神社にも行ってみようと考える。

こちらは、タイムズでつねに15分220円だかだけどしょうがない。

するとなんちゃら寅造の碑とかあって、浪曲か? とか思いながら後で読もうと階段をのぼると右手にさびれきった、しかし坂をうまく滑り台にした児童遊園があって良い感じだが、お稲荷さんと違って遊ぶ子供はいないというか、なんか暗いよ。

上ると左手に神輿蔵があって2(?単位はなんだろう)。右側のは読むと宝永年間(あやふや)の漆塗りとか書いてあるから350年以上の神輿で美しい。その左は白木で約200年くらいだが、元は白木でもすっかり黒くなっていて、右の漆塗りと良い勝負になっている。鋼で固めてあるので丈夫なようだが、それ以上に漆の保存力はすげぇな。

右手には猿が2匹で桃と戯れていて、孫悟空でなければ、林檎を桃と勘違いした失楽園かと思えなくもない石碑があって、これも古そうだ。

後で坂の途中にあった能書きを読んだら、これまた古い庚申塔で、猿と桃のモティーフは珍しいとあるが、確かに初めて見た。ついでにそこに立つ石鳥居は区内最古とかあって、今のさびれっぷり(初詣客は数人しかいない)とはまた異なる面影を考える。

で、寅造の碑には良く見ると楽譜になっていてオタマジャクシをたどるとまさかりかついだ金太郎で、おお、寅造があの歌を作ったのか! と初めて知る。

来てみないとわからないものだ。というわけで、漆塗りの神輿も猿と桃の庚申塔も寅造もおもしろかった。


2020-01-05

_ PDFからテキスト抽出

yancyaさんのQiitaの「RubyでPDFと戯れるの巻」は参考になるが、origamiよりもソースが読みやすいので、pdf-readerを使ってPDFからのテキスト抽出をしていた。

多分現在のorigamiもそうだろうが、エンコーディング情報が入っていれば、テキストの抽出はえらく簡単で、少なくともpdf-readerだと次のようにすればよい。

reader = PDF::Reader.new(filename)
reader.pages.each do |page|
  puts page.text
end

が、これはあくまでもエンコーディングが設定されている(yancyaさんの記事だとToUnicodeが設定されている場合なのだが、CMap(キャラクターマッピング表ということかな)があればOKのようだ)、埋め込みフォントを利用して、かつグリフのみの場合で詰んだ。

上のやりかたで、ある特定ページからのputs page.textで出力される文字がむちゃくちゃになる。

はて? と生データを見ることにする。

puts page.raw_content

raw_contentによって、ynacyaさんの記事と同様の内容を得られる。 こんな感じだ。

 
/C0_0 1 Tf (略)[<001B00190003>-4139.9 <00190015>-2120 <001600180015000F001400190013>]TJ 

で、/C0_0というフォントを見てみると

page = reader.page(出力がおかしくなったページ)
puts page.fonts[:C0_0]

次のような出力を得られる。

{:BaseFont=>:"MS-Mincho-Identity-H", :DescendantFonts=>[{:BaseFont=>:"CNBLDP+MS-Mincho", :CIDSystemInfo=>{:Ordering=>"Identity", :Re\
gistry=>"Adobe", :Supplement=>0}, :DW=>1000, :FontDescriptor=>{:Ascent=>723, :CIDSet=>#<PDF::Reader::Stream:0x00007f2ca02b4138 (略)  :CapHeight=>709, :Descent=>-241, :Flags=>6, :FontBBox=>[-82, -13\
7, 996, 859], :FontFile3=>#<PDF::Reader::Stream:0x00005640ea24f6b8 (略)

ToUnicodeは無い。

pdf-readerは何を根拠にテキストを出力しているのだろうか? 不思議に思ってpdf-readerのFontオブジェクトを作ってみる。

c0_0 = PDF::Reader::Font.new(page.objects, page.fonts[:C0_0])
puts c0_0.to_utf8(0x1b)  #=>▯
puts c0_0.to_utf8(0x19)  #=>▯
puts c0_0.to_utf8(3)     #=>▯

確かにpage.textで表示された文字列に一致しているが……

puts c0_0.encoding  #=>  #9647, 1=>9647, 2=>9647, 3=>9647, 4=>9647... 

CID 9647に相当する文字を5078.Adobe-Japan1-6.pdfで見てみるとiアクセンテギュみたいだが、該当フォントがないので▯になっているのかなぁ。

しかし、そもそもOrderingがIdentityでJapanXではないのだから、見ている表が違うわけだろう。

要は埋め込みフォントのグリフを直接指定しているに違いない。

それで、埋め込みフォントを抜いてみることにする。

sudo apt-get install fontforge

でfontforgeをインストールして、フォントファイルとしてPDFでフィルタして読み込むと、どのフォントか? と聞かれるので、CNBLDP+MS-Mincho (上でC0_0のDescendantFontsのBaseFontとされているもの)を選ぶ。

すると、3がスペース、0x1bが8、0x19が6のグリフを持つフォントが表示された(その前にfontforgeはCMapが無いけど無視するか? と聞いてくる。そもそもCMapが無いのでこんなことしているのでGive Upをクリックする)。これは、該当PDFの表示と一致する。

ということは、文字コードに相当するものがどこにも無いのだから、TJで指定されているCIDに相当するグリフを埋め込みフォントから拾い出して文字認識させるか、PDFをそのままOCRするか、しかテキストを取得する方法は無いということだ。

というわけで、フリーのOCRでPDFを入力できるもので試したが、結果はひどいもので(多分、余分な情報が多いのだと思う)、グリフを使うほうが良さそうだなというところまでは来たのだが、fontforgeと同じようなグリフの取り出しってどうやればできるんだろうか? pdf-readerのstreamを使ってデータは取り出せるのはわかっているのだが、フォントの格納形式はわからないんだよな。

_ pdf-reader その他の使い方

pdf-readerを利用して単に文字コード変換テーブルを内包したPDFからテキストを抽出するだけならば、各ページオブジェクトのtextプロパティを呼び出せば良い。上のエントリーの最初のコード片参照。

より詳細な情報は、reader#objectsを利用する。

reader = PDF::Reader.new(filename)
1.upto(reader.objects.length - 1) {|i|  # objectsをeachで回すと最初のnilがスキップされる。PDF内のobjectのIDとインデックスを一致させるためだと思うが、配列としてアクセスするほうが話が簡単だった)
  puts "#{i}: #{reader.objects[i].inspect}"
}

objectsはHashとPDF::Reader::Streamのいずれかが入る。Hashが示すオブジェクトの実データはPDF::Reader::Referenceが示すStreamに格納される。

{:Contents=>#<PDF::Reader::Reference:0x00005640ea49b1d8 @id=2, @gen=0>, :CropBox=>[39.6567, 137.534, 555.563, 704.466], :MediaBox=>[0, \
0, 595.22, 842], :Parent=>#<PDF::Reader::Reference:0x00005640ea498460 @id=114, @gen=0>, :Resources=>{:ExtGState=>{:GS0=>#<PDF::Reader::
Reference:0x00005640ea4aacf0 @id=130, @gen=0>}, :Font=>{:C2_0=>#<PDF::Reader::Reference:0x00005640ea4aa610 @id=126, @gen=0>, :C2_1=>#<P
DF::Reader::Reference:0x00005640ea4a9698 @id=139, @gen=0>}, :ProcSet=>[:PDF, :Text]}, :Rotate=>0, :Type=>:Page}

上のHashはContents(ページ内のテキストなど)を示す。実際のデータは、@id=2のStreamであることがわかる。

puts reader.objects[2].filtered_data  # filetered_dataは圧縮などがされている状態から実データを復元する。ここではContentsということがわかっているのでputsで呼び出す。
#=> 0 0 0 rg /GS0 gs 297.96 717.2 0.24 25.56 re f 39.6 ...

Streamからは、フォントのグリフや、CMapも取得できる。FontDescriptorなどの非バイナリオブジェクトは、Hashとなる。

下の例は、FontDescriptorで、フォントデータは、FontFile2で示されるID(objectsのインデックスに等しい)のPDF::Reader::Streamから取得できる。
{:Ascent=>880, :CIDSet=>#, :CapHeight=>0, :Descent=>-120, :Flags=>4, 
:FontBBox=>[-26, -174, 1000, 881], 
:FontFile2=>#, 
:FontName=>:"CJKHCO+RgGothic-Md-90ms-RKSJ-H", :ItalicAngle=>0, :StemV=>0, :Type=>:FontDescriptor}
上記のFontDescriptorをポイントするBaseFontを示す。ここでFontDescriptorとして示されている@id=13、つまりreader#objects[13]が上記である。
{:BaseFont=>:"CJKHCO+RgGothic-Md-90ms-RKSJ-H", :CIDSystemInfo=>{:Ordering=>"Identity", :Registry=>"Adobe", :Supplement=>0}, :CIDToGIDMap=>:Identity, :DW=>1000, 
:FontDescriptor=>#, :Subtype=>:CIDFontType2, :Type=>:Font, :W=>[17, [500], 19, 28, 500]}

2020-01-11

_ この世界の(さらにいくつもの)片隅にを観る

妻と丸の内TOEIに「この世界の(さらにいくつもの)片隅に」を観に行く。

銀座線で降りて確か昔プランタンがあったあたり(全然丸の内じゃないので、妻とやたらと歴史がある映画館だから、有楽町(そもそも数寄屋橋という呼び名もあったし)よりも丸の内のほうが通りが良い時代に命名したのかなぁとか話ながら)だと地下をだらだら行くと、数段程度の階段がそこら中にあって、どうにも造りが良くない(あるいは歩兵の進軍を止める目的とかあったのか?)と考える。というか、割と通ることはあるのだが、工事中でやたらと狭かったりするので気になったみたいだ。

で、最初入ると数人しか客がいなくて、ちょっと驚いたが終わって外に出るとそれなりには入っていてなんとなく安心した(去年で終わりのはずの特典絵葉書をまだ配布しているってことは、集客がいまいちなのかと心配になったのだった。とはいえ、防空壕の中の集合写真みたいな絵葉書で、なぜこれを配るのか? と不思議ではある。受け取らない人もいるんじゃないかと言うと、妻は家族の収まりが良い構図だったからかなとか言うし、それはそうかも知れない)。

()無しとの一番の違いは、自分が代替物ではないかという感覚で、()無しでは義姉の子供を死なせたことが広島へ帰ることの一番の理由だったようなのが(子供ができないことも理由だったのかも知れないが)、随分印象が異なる。

次が枕崎台風の襲来で、こんなにすごい被害をもたらした台風について全く知らなかったのがある意味驚きだった。踏んだり蹴ったりのようだが、残留物質を洗い流したというような記述も見るので必ずしも悪いことばかりではなかったのかな(いずれにしても住民にとってはたまらん)。

おれにとっては一番観ていて辛いのは、被爆してガラスで針鼠みたいになった母親と子供のシーンなのだな、と今回も思った。居場所があるというのは本当にありがたいことだなぁ。


2020-01-13

_ フランケンシュタイン

子供と日生劇場(初めて足を踏み入れたような気がする)でフランケンシュタイン。韓国製のミュージカルとしてはアンクルトムに続いて2つ目だ。

物語はわりと良く知っているシェリー夫人のフランケンシュタインだが、幾つかミュージカルとして物語を際立たせるための改変がある。

主人公のヴィクトルフランケンシュタインは母親の死のショックから永遠不滅の生命というものを、母親の死に対してなんの手も差し伸べなかった神に変わって作り出そうという目的へ邁進する男として作られている。最初の子供っぽい復活のための実験を村人に勘違いされて、家を焼かれてそのときに父親も喪失している。

おそらく悲劇を際立たせるために、ヴィクトルの回りに重要な4人の人物を配する。

1人は忠実な執事で、孤児(後述する姉はいる)となったヴィクトルを父親の代わりに溺愛している。ヴィクトルに対して完全に無償な貢献を行う。

1人は姉で、ヴィクトルの気持ちもわかるが、頭の悪い村を生活の場として定めた以上は折り合いをつけさせるべきだという思いもある。唯一ヴィクトルの実験に対して反対の意見を(まともに)表明している(まともではない反対は頭の悪い村すべてなので問題とはならない)。

1人は親代わりに引き取った伯父の娘で、ヴィクトルの天才っぷりに心底いかれている。

そして、ナポレオン戦争中に不服従の罪で銃殺直前のところをヴィクトルに救い出された元医学生(人体の再利用という研究をしていたが廃棄して、やけになっている)のアンリで、ヴィクトルの生命創造への論理的な支持者である(執事と伯父の娘はおそらく同情と頭の良さに対する闇雲な支持者なので、相当異なる)。

ヴィクトルはナポレオン戦争で死体から兵士を作るというアイディアが採用されて実験をしまくっているが、ワーテルローでナポレオンが敗けたために実験途中で解散を命じられる。しかし、そのときに、停戦合意書に署名をするために子爵の失われた右腕を作るという依頼をクリア(実際の執刀はアンリが行ったらしい。またその手術の腕前が評価されてヴィクトルの右腕になれたのだろう)したために、戦争の英雄として村へ帰還する。そのため、風当たりは少し弱まることになる。

伯父さんは市長をやっているのだが、いきなりえ? と驚くほど下手な歌を歌い出すので、これはミュージカルではないのではないかと疑ってしまった。が、その後に出てきた伯父の娘が素晴らしい歌を歌ってみせて、ほっとした。やっぱりミュージカルのようだ。

ヴィクトルの研究はほぼ完成していて、焼け残った居城の地下に実験施設があるのだが、新鮮な脳みそを持つ頭が手に入らないために、失敗しまくる。

執事が、葬儀屋から入手することを思いつき、段取りをつける。しかし葬儀屋は金をすぐ欲しいもので、無から死体を生み出す。その死体が自分に対する敬意を示した医学生だったので、ヴィクトルは怒りのあまり葬儀屋を突き飛ばす。打ち所が悪くて死体が2つになった。仰天してヴィクトルも気を失う。

そこへ警察がやってきたため、アンリが身代わりとなって逮捕される。

ヴィクトルがアンリの脳髄を手に入れることもありだな、と考えていると姉がやってきて、お前はさすがにまともではないとたしなめる。(微妙に、姉とアンリはお互いに惚れあっているような描写はいくつかある)

さすがに、ヴィクトルもアイディアの外道っぷりに反省して自首する。

まるでカラマーゾフの兄弟のイワンの証言のような扱いになる。ヴィクトルは戦争の英雄なのに対して、アンリは突然あの頭のおかしなフランケンシュタインが連れてきたよそ者だから、犯人はアンリに決まっているという理屈で、徹頭徹尾、この村は2000人の狂人の村として描写される。

かくしてアンリの新鮮な首を盗み出したヴィクトルは生命を吹き込む。

だが、生まれた人間は元のアンリではなく、執事を噛み殺してしまう。怪物を作ってしまったと認識したヴィクトルは銃で撃つがもう遅い。怪物は窓から逃亡してしまう。

2幕。数年後。伯父の姿が見えない。連れて行った犬が無残に噛み殺されている。

かくして、ヴィクトルが村人を率いて山狩りが始まる(とりあえず、ヴィクトルは村人と和解できている)。

山小屋で伯父の死体とナイフを持ったまま気絶している姉が見つかる。村人たちは、やはりフランケンシュタインだと、裁判もせずに姉を吊るす。

ヴィクトルは例によって死体を盗み出して、地下の実験室で姉を生き返らせようとする。しかし、すべての機械が破壊されている。一体何が起きた? と見ると、怪物が、姿を現す。懲りない男だな。

言葉が話せるのか? とヴィクトル。

アンリの記憶はないが、知識は使えるようだ、と、怪物は自分が味わった辛酸について語り始める。

熊に襲われた女性を助けるために熊を殺して(その前から熊を殺して食べていたらしく、「熊おいしい」というのはこの作品のミームになっている。お土産売り場では熊カレーが売っているので子供は買っていた)、人々のところに連れて行くと、怪物が出たと、いきなりタコ殴り(多勢に無勢なのだ)で縛り上げられ、地下格闘技場の闘士とされてしまう。

しかし、心優しく勝っても止めをささないために人気がなく、ひどい扱いを受けている。

地下牢の前で美しい誰もいない北極で暮らしたいの歌を助けた女性は歌ってくれるのだが、結局、彼女は自由になりたいいために、賭け試合に必勝を期すための計画に加わって怪物に毒を飲ませる役回りとなる。

この賭け試合と結末のつけかたのテンポはすごく好きだ。

裏切られた怒りと、それとは別にフランケンシュタインの実験ノート(生命を得たときに、裸では寒そうだとヴィクトルが自分のコートを着せたが、そのポケットに入っていたのを闘技場の支配人が渡す)を手に入れたことで、怪物はレゾンテートルに悩むことになる。

悩んでもしょうがないので、創造主に対して復讐を誓う。こんなにおれが苦しむのは、この世の中におれを生み出したやつが悪い。当然、その前に闘技場は燃えることになる。

というわけで、お前の姉を殺させたわけだ、と怪物は言う。おれの受けた辛酸すべてをお前にも味あわせてやるから、まだまだ続くぜ。そう言い残してまたまた窓から去る(と気づいたが、地下室じゃないんじゃないか?)

伯父の娘とヴィクトルは結婚する。

当然、怪物は娘を殺す。

自分を愛したすべての人間を失ったヴィクトルは怪物の語った物語から北極を目指す。

ついに極北の地で怪物を撃ち殺すことに成功するが、その前に脚を折られて(ことにする)アナキン状態のヴィクトルも直に死ぬだろう。

おしまい。

まあ、盛沢山ではある。

テクノロジーの進歩に戦争は不可欠とか、無知な村人には科学は邪悪な魔術で焼き払うべき対象で、誰かが死ねば適当な誰かをリンチで吊るすのがそのての村人に対する治世の要諦(有罪率99.4%だな)とかいうようなどうでも良い教訓もあるが、そういう話ではない。

ささやかな幸福もあれば(実際のところ、北極の歌のところでは、体は苦痛を感じていてさえ、怪物ですら少しは幸福感を持ったはずだ)、苦痛や悲嘆もあるという当たり前のこともどうでも良さそうだ。

音楽の印象がほとんどないのは、物語が(余分なエピソードをてんこ盛りにしたとはいえ)シェリー夫人の手の中にあるからだろう。

要はどれだけ理想に燃えていてもやり過ぎるとすべてを失うということなのだった。その失うというここそ恐怖の根源で、だからこそ恐怖物語としてフランケンシュタインの怪物は生まれなければならなかったわけだ。

ヴィクトルはいきなり母を失い、父を失い、姉との生活を失い(寄宿学校へ送られる)、せっかく得た親友/理解者/協力者を失い、実験の成果物に逃げられ、どう考えても執事という職業からは有償なはずなのに無償の愛を注ぎ込む執事を失い、姉を失い、実験室を失い、研究ノートも考えてみたら失い、奥さんを失い、最後は自分の手で成果物を失い、自分の生命も失う(他のあれこれに比べれば一番どうでも良い喪失に見えてくる)。恐怖の連続だ。恐ろしい。

ところが、まったく恐ろしくなく、終わるとむしろ良い感覚を得るのがおもしろい。実のところ、この作品は魂の救済の物語っぽい。喪失は恐怖だが、一方では自由の獲得でもあるからかなぁ。

それにしても音楽の印象がまったく残っていない。そういう意味ではアンクル・トムもそうだったが、物語を語ることに主軸が有り過ぎるのではないかなぁ。ある意味ステレオタイプだから、物語は時間をもたせるためのスキャフォールドに留めておくことも可能だと思うのだが、それ以上に物語を語ってしまって、ほぼ演劇(時々歌が入る)となっている。だが、おもしろかったから、それは難点ではなく、そういうミュージカルということなのだろう。

せっかくいるのに、ヴィクトルとアンリの二人が同時に歌うのは1幕の戦場の実験室の中だけかな?(というか、あったかどうかも怪しい)モーツァルトのサリエリとアマデウスのように二人が歌いまくって終わりになるわけでもなかった。

※ 子供が物語を間違って覚えていると指摘したので訂正。

・葬儀屋を突き飛ばすのではなくフランケンシュタインが石で殴る。やばいと思ったアンリがフランケンシュタインを気絶させて、その間に自首する。

・姉はナイフではなく遺産目録を手にして横に倒れていたらしい。

※ 鑑賞後にすがすがしいのは、上では書いてないもう1つの喪失の物語があるからではないか。ヴィクトルは母の喪失の前に、呼びかけに答えない神を喪失している(近代人では当たり前のことなので意識していなかった)。一方、怪物にとっての神はヴィクトルだという点が重要で(ヴィクトルのことを造物主と呼ぶ)怪物はヴィクトルの代わりに神に対して復讐を成し遂げる。宗教からの自由こそ近代なのだから、これこそゴドウィンの娘であるシェリー夫人の作品のテーマそのものだった。


2020-01-19

_ PDFは難しい

以下のように出力されるPDFがある。

これが、pdf-readerでは正しくテキストが取れない。

X座標が関連業の部分と(0.2%)の部分で入れ子になるからだ。x座標が(の部分で左に移動している。

x:81.15690000000001, y:428.4363, char=関
x:87.15690000000001, y:428.4363, char=連
x:93.15690000000001, y:428.4363, char=業
x:86.6769, y:428.4363, char=(
x:92.6769, y:428.4363, char=0
x:95.6769, y:428.4363, char=.
x:98.6769, y:428.4363, char=2
x:101.6769, y:428.4363, char=%
x:107.6769, y:428.4363, char=)

生データは以下となっている。

/C2_0 1 Tf 4.44 0 0 6 51.1569 428.4363 Tm <0BBE0869020605CB0FF606FE10B207AA>Tj 6 0 0 6 86.6769 428.4363 Tm <022A00

(Tjで指定されている文字はUTF8変換で正しい)

Tmで設定されているメディアボックスの解釈をpdf-readerが間違っているのは明らかなので、要は86.6769のXまでに51.1569からのTjの文字がすべて入る必要があるのだが、4.44の倍率だけでは解釈できない。

それはそれとしてpdf-readerを修正した場合、PRするのは簡単だが、テストケースが作れない(変換元のPDFをどうすれば良いか?)のは難しいな。

_ 続き

書いてみたら、ふと気づいたが、そうではなく、次のメディアボックスのXに収まるようにXの位置を調整するのが正解なのではなかろうか? とすれば、メディアボックスを先読みするようにすれば良いのだな。(あるいは直前のメディアボックスの開始位置まで巻き戻してXを再設定する)

いや、今気づいたが、最初のメディアボックスの4.44が効いていないような。(以降は6ずつ増えているのだから、フォントサイズを1とすれば、最初の部分は4.44ずつ増えるべきだが、同じく6ずつ増えている。

_ 結論

コード( https://github.com/yob/pdf-reader/ )を眺めてもらちが明かないので、ばかでかくてすごく嫌だがPDFのリファレンスを眺めることにする。

P.410の5.3の最後に、Tmを適用している。この処理が、PageState#process_glyph_displacementでは正しく行われていない。というのは、font_sizeの計算がおかしいからだ。

--- /usr/local/lib/ruby/gems/2.6.0/gems/pdf-reader-2.4.0/lib/pdf/reader/page_state.rb   2019-12-27 11:54:10.395106352 +0900
+++ /tmp/page_state.rb  2020-01-20 01:48:27.286352348 +0900
@@ -109,8 +109,8 @@
 
       def font_size
         @font_size ||= begin
-                         _, zero = trm_transform(0,0)
-                         _, one  = trm_transform(1,1)
+                         zero, _ = trm_transform(0,0)
+                         one, _  = trm_transform(1,1)
                          (zero - one).abs.round(2) # 小数点2位くらいまでは実際に設定されるのでそこに丸める。最後の文字は999999……になることが多い
                        end
       end

なんだけど、元のコードはフォントサイズに縦を利用していて、もしかしてそれが正しい場合もあるのかも知れなくて、困るな(おれは困らないので、このパッチを適用するわけだが、PRしようがない)。


2020-01-20

_ 港区散歩

芝浦3丁目あたりだと思うが、倶楽湾という中華料理屋があって、味も適当においしいし、とにかく内装が素晴らしいので、たまに港南のほうに用があるときに妻と行く。

何が素晴らしいかといえば特に1階から2階への階段なのだが、ぼーっとしていると店員にエレベータへ案内されてしまうので帰りにしか味わえないが、適度に暗くて正方形に区切った壁面にいろいろ不可思議なものが置いてあるのが実に良い雰囲気なのだ。あと最近改装されてつまらなくなってしまったが、男子トイレに入ると妙なゴルファーの像があってそれに見とれていると奥のほうに薄明かりがついて、ギギギーバタン!という怪しげな音とともに便器の蓋が跳ね上がるのが照らせれるのが不気味千万ですさまじく楽しい(が、改装されて普通に明るくてつまらなくなってしまった)。

2階も、小奇麗ではあるが、上海バンスキングとはこういう場所が舞台なのですなという感じで(後で調べたら、本当に上海租界のイメージで内装を作ったというようなことが書いてあった)、好きだ。

上海バンスキング・FIRST(吉田日出子)

で、昨日も同じく港南に用があったので、妻と愛育病院のあたりから芝浦公園を通って田町のあたりへ歩いていたのだが、残念なことに倶楽湾は臨時休業だった。それで田町駅のステーションタワーのほうで食事をしたのだが、芝浦公園のあたりから、この一帯は、少子化なにそれ? なほどに子供がたくさんいて、なんかすごく活気があって楽しい。子供って基本的に頭が悪いから、いきなり歌は歌うし踊りは踊るし、走り回るし、嬌声を上げるわけだが、それがなんか適当な節度なので、見ていてこちらも楽しい。

全体的にも住人が若い。

この一帯ってイメージでは、老人が多そうなんだが、どうも再開発の時期が良かったのか、比較的小さい子供を持つ家族世帯が多いようにみえる。

つまり、町としてなんかすごく良い雰囲気なのだ。

そのとき、あ、だからここは港区女子というものがすなっている場所なのかと電撃のように理解した。

たとえば、こんな記事が見つかる。

港区内格差:港区内で格下とされる芝在住の女が、バーキンを持つ前にやるべきこと

わかんないだろうなぁ。


2020-01-22

_ Design It! ―プログラマーのためのアーキテクティング入門

翻訳担当の島田さんから頂いたDesign It! を読み終わって少し時間がたったが紹介する。

システムを開発するときに、どのような筋道で開発に着手するかの前段階の調査と思考の筋道を説明した本である。プログラミングそのものも設計だが、それより下位の設計(たとえばクリーンアーキテクチャのような実装設計であり、フレームワークへの適用設計である)よりもさらに下位にくる、全体の見取り図の設計、実装設計のための方向性の決定のための設計と考えると良い。アーキテクチャとしては下位だが、上流工程とも言える。上か下かは立ち位置による。以下では下とする。

内容はおれさま判断で正しい。この言語化(つまりは書籍化、結局は筆者のマイケル・キーリングのノウハウの分化と手順化)には舌を巻く。

11月の末頃いただいて、大体1か月くらいかけて通勤時の何割かと休日に読んだ。ただし、1/3強を占めるパターン集(アクティビティと本書では呼ぶ)は適宜読んでいるので別。

全体は380ページある。そのうち本文に相当するのが全体の2/3で、残り1/3はパターンカタログ(ただし本書ではアクティビティ(ワークショップで実行するための科目)としてあるし、実際に、設計での合意のためのワークショップで行うべき作業)となっている。

本文は第1部30ページ弱と、残りすべてを占める第2部(200ページ弱)で構成される。

第1部は設計という作業全体についての要約である。

第2部ではそれを分解して手順化した具体的なやるべき作業として示す。

結構読むのに時間がかかるのは、コードが無く、ほぼ文章でかつ内容が比較的抽象的(見方による。おれにとっては脳内作業なので抽象なのだが、本書は目的からワークショップでの科目なので具体作業である)なので咀嚼に時間がかかるからだが、考え方の筋道を示す図が多数入っているので難しいわけではない。

おれが読むのに時間がかかったのには2つの理由があると考えられる。

1つは、用語が多数出て来てそれらが自由自在に組み合わさるために、ある言葉がどういう意味で出てくるのか時々見失うからだ。特に重要な語句は頭語になっているのだが、結構これを忘れる。幾つかについては後述する。老化もありそうだし、ボキャブラリーが微妙に異なることにもありそうだ。

もう1つは、今となってはおれにとって瞬時に終わるようになっている設計上のポイントについて、チームでの合意形成のためのワークショップで行う内容の説明と例示として説明されていることにありそうだ。このため、自分の中でほとんど無意識に行える判断と突き合わせるのに、内的な言語化と視覚化が必要となり、そこに時間がかかったようだ。

もう1つ付け加えると、本書は、個人~数人レベルのプロダクトを対象したものではなく、遥かに大きいシステム(総員100名、10人チーム×10サブシステムくらいで、本書の範囲に3ヵ月程度を利用できるというかしなければならない規模)を想定している。本文を読む限りでは開発期間100日のうち30日を本書の範囲としているようだが、それには盛沢山に過ぎるように見える(上で書いた10チームがそれぞれで本書の内容を30日で行うとすれば帳尻は合う)。

そのため、チームマネージメント(下位設計時点なので合意形成が主眼となる)についてのありよう、つまりはワークショップ(会議では断じて無い!)が丁寧に示されている。これは現在のおれには興味がなく、考えたくもない領域だが、読む限りとても良いことを書いていると感じる。

特に重要な点というよりも、本書が正しいと考えられるのは、おれ個人の内部での合意形成(つまりはポイントポイントでのアーキテクチャ選択)の筋道と合致しているからだ。

ここまで書いた時点で疲れたので一度中断。

Design It! ―プログラマーのためのアーキテクティング入門(Michael Keeling)


2020-01-27

_ 動物園の思い出

妻となんか動物園の思い出話になって、大人になってから衝撃を受けた2シーンを備忘のために残しておく。

荒川遊園地の動物園: 子供が生まれる前に妻と行って、生まれて初めて観覧車に乗って恐怖を味わったのだが、動物園のほうのアライグマが最高におもしろくて今でもときどき思い出すし、語り草になっている。

アライグマは檻の鉄柵(だと思うが金網かも知れない)の手前に来ていて、こちらは檻の手前の人間用の柵から見ている状態。

アライグマ舎の鉄柵の下が溝になっていて水が流れている。

で、アライグマは何かを探していて、見ていると何やら地面に落ちていた黄色いものを手にした。どう見ても糞だが、それを一心不乱に洗い始めた。

おお、アライグマって本当に洗うんだな、とびっくりすると同時に、あれ? 食べ物を洗うわけではなく、なんでもサイズが合えば洗うのか? と思う間もなく、糞は溶けてしまって無くなってしまった。溝は黄色く染まっている。

するとアライグマは呆然としたあとに、いきなり右手を振り上げて水をパシッと叩いて奥へ引っ込んでしまった。なんで無くなるんだよ! と怒ったとしか思えん。

以後、荒川のウンコアライグマが、妻との間で暖簾に腕押しのような意味で使われる言葉となった。

井の頭自然文化園: 子供を連れて行って、ヤマアラシの山を見ていたら、3匹くらい連なって行進している。ぐるぐる塀の回りを回り続けている。時々コースを変えるのだが、隊列は乱れない。つかず離れず隊列乱さず大行進なので、どういう習性なんだろうと不思議に思う。後で調べても縄張りの見回り行進をするというような習性は書いてないし、発情して追っかけまわして結果的に大行進になるというようなことも出ていないし、今でも不思議だが、少なくとも20分くらい見ていた間はずっと行進していた。

なんかそういうものなのかな? とその後、数回行ったときにヤマアラシを観察するのだが、以降、2度と見ることはなかった。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|

ジェズイットを見習え