hkoba blog

プログラマーです。プログラミング言語ミーハーです。ツッコミ歓迎です。よろしくどうぞ(能代口調)

謹賀新年/2016目標

あけましておめでとうございます

昨年交流させていただいた皆様、良くして下さり有難うございました。

また今年も、仲良く本音で楽しんで生きましょう。

昨年の反省点

  1. 引越し、ならず!荷物減らしも、イマイチ進まなかった。
  2. ライフワーク(オレオレ言語作り)にも、望んだほどは体力を充てられなかった。
  3. Twitter 読むのに時間を使い過ぎ?得られる情報も多いとは言え、なかなか難しい…

昨年の良かった点

  1. 生活
    • 食生活改善(肉を積極的にとるようにした)のお陰か、体が疲れにくくなった気がする。(2kg 太ったけれど、痩せ過ぎだったから良いよね?)。以前は一日働いた後は『燃え尽きた』ような脱力感があった。
  2. 仕事と OSS 活動
    1. YAPCAsia2015 のお手伝いが出来たこと
    2. 職場に Slack を有料版で導入してもらえたこと。細かいやり取りを記録に残せるようになったことで、業務のタコツボ化回避に極めて有効と分かった。(独り分報も始めてみた。こっちは todo の意識化程度)。正直、もう出社しなくても良いのでは…?
    3. 2015年の新人さん3人が、何とか職場に定着してくれたこと。本人も教育担当も、大変頑張って下さいました。ありがたや…
    4. お客様の社内で少しずつ YATT::Lite の導入事例を増やせていること。非プログラマのために作った YATT なので、それが目論見通りの成果を出すのを見るのは嬉しい。
    5. Perl で10年?以上かけて探求してきた use fieldsimport() を活かした、静的 typo 検出とコンパイル時コード生成を両立させたコーディングスタイルの、知見の集大成である MOP4Import::DeclareCPAN にリリース出来たこと。これで自作モジュール CPAN 化の最大の障壁が無くなった。
    6. (Fedora) LinuxSurface Pro3 の日本語キーボードカバー対応に、(ショボいパッチとは言え)貢献できたこと。
    7. 長年構想をあたためてきた、TclTk + sshcomm + tkhtml3 ベースの、業務特化ウェブサイトのための半自動設定 GUI、そのプロトタイプを一週間ででっち上げて実戦投入できたこと。大きな手応えを得られた。
  3. 英語
    • 未来塾で、自分の英語の音作りに関して、ほんの少し、進むべき道が見え始めたこと

今年の目標

  1. 追記 いいかげん棚卸しの習慣をつける。本のあふれ、食材の賞味期限切れに対策を。
  2. 引越し(移住?)を、現実の計画にする。Slack ベースで働ける体制が出来た以上、職場から遠くても良いので、家賃の低い所に移りたい。
  3. YATT::Lite (や perlminlint) の静的な typo 検出のメリットを、普通の人が簡単に受けられるように、 Web IDE とか作れないか…模索したい。
  4. TclTk + tkhtml3 という thin なプラットフォームの可能性を、もっと世の中の人に使いやすい形にまとめる。
  5. FSharp か OCaml の勉強をもう少し頑張って、実戦投入の道を探る。
  6. 自分の余暇時間を増やせるようなツール作りを模索する。(Twitter 関連かなぁ…)
  7. 彼女(嫁)探しを、諦めない…諦めない…(一体どこに行けば、オイラと共存可能なひとが見つかるのか…?)

SQLite でも列名を生成する時の quote には backtick (`) を使ったほうが良いぽい気がしてきた

軽くハマったのでメモ。

まずは実験用のテーブル tab1 を作ります。(中身は空のままにします)

sqlite> create table tab1(foo, bar);
sqlite> select * from tab1;
sqlite> select * from tab1 where foo = 3;
sqlite>

次に、意図的に列名を打ち間違って入れてみましょう。 例えば fooo みたいに。

sqlite> select * from tab1 where fooo = 3;
Error: no such column: fooo
sqlite>

ちゃんとエラーになります。では、今度は(間違った列名を) double-quote で囲んで "fooo" のように変えてみましょう。これは SQL 標準に従った書き方です。ところが…

sqlite> select * from tab1 where "fooo" = 3;
sqlite>

なんと、 エラーにならない!

なぜこうなるかは SQLite の公式マニュアル SQLite Query Language: SQLite Keywords にあるように、

If a keyword in double quotes (ex: "key" or "glob") is used in a context where it cannot be resolved to an identifier but where a string literal is allowed, then the token is understood to be a string literal instead of an identifier.

"..." の指す列が存在しないなら、代わりに 文字列として解釈し直して しまうから。…超、迷惑…

このように、SQLite において、列名を double-quote で囲むと 列名の誤りがエラーにならないため、問題に気づくのが遅くなるのでよろしくないのでは?という話です。

むしろ mysql 風の backtick (`) で囲ったほうが (SQL標準から外れても) エラーになるだけマシではないか?と。

sqlite> select * from tab1 where `fooo` = 3;
Error: no such column: fooo
sqlite> select * from tab1 where `foo` = 3;
sqlite>

SQL::Maker で引用符を切り替えるには

例えば PerlSQL::Maker - Yet another SQL builder - metacpan.orgSQLite に対してはデフォルトでは double-quote (") を使います。 これを backtick に切り替えるには、明示的にオプション "quote_char => q{`}" を渡して

use strict;
use SQL::Maker;
my $mk = SQL::Maker->new(driver => "SQLite", quote_char => q{`});
print join "\n", $mk->select(tab1 => ["*"], +{fooo => 3});
# SELECT *
# FROM `tab1`
# WHERE (`fooo` = ?)
# 3

とする必要が有ります。

zsh 実験メモ:文字列変数の中から空白文字の位置を探したい時…

ふと迷ったのでメモ。ツッコミ希望です。

foo='key foo   bar
  baz...'

のような文字列変数が有るとして、これを key

"foo   bar
  baz..."

の2つに分割したい。

要するに perlsplit " ", $foo, 2 がしたい。

一旦配列変数に展開してから、2つ目以後を取り出して join し直す、だと、途中に複数のスペースや改行があっても 一文字にされてしまうので、いつでも使えるとは限らないなあと。

ary=($=foo)
print $ary[2,-1]

文字列の中から、特定の文字の位置を探すのは、 subscript の (r) や (i) フラグを使えばいける、 けど、スペースを subscript に書くとパースエラーになる。 \" " だとマッチしないし。

% foo='key foo   bar
  baz...'
% print $#foo
22
% print $foo[(i) ]
zsh: invalid subscript
% print $foo[(i)\ ]
23
% print $foo[(i)" "]
23
% print $foo[(i)' ']
23
% 

一時変数を作ってそこにスペース文字を入れれば行ける、けど、凄く負けた感が有る。

% k=' ';print $foo[(i)$k]
4

自分が思いついた解決策

${:-文字列式} を使う。ベストかどうか、分かりませんが。

% print $foo[(i)${:- }]
4
% print $foo[(r)${:- },-1]
 foo   bar
  baz...
% pos=$foo[(i)${:- }]
% print key=$foo[1,pos-1] value=$foo[pos+1,-1]
key=key value=foo   bar
  baz...
%
% print key=${(qq)foo[1,pos-1]} value=${(qq)foo[pos+1,-1]}
key='key' value='foo   bar
  baz...'
%

(key 側に off by one が有ったので訂正)

追記:上記を位置パラメータに使うには ${...} が必要…

% set -- --define 'dist .fc22.hk1'
% print $2[(i)${:- }]
zsh: no matches found: dist .fc22.hk1[(i) ]
% print ${2[(i)${:- }]}
5
% typeset -A defines
% p=${2[(i)${:- }]}
% defines[${2[1,p-1]}]=${2[p+1,-1]}
% print ${(kvqq)defines}
'dist' '.fc22.hk1'
% 

(zsh) ある日のインフラ業 - bind の入れ替えを例に

雑に記録だけ。

大体、こんな感じだった。(Fedora22 の場合です. P3 の src.rpmここから download. YMMV)

fn=bind-9.10.2-4.P3.fc22.src.rpm
rpm -ivh $fn
cp ~/rpmbuild/SPECS/bind.spec .

# gpg --keyserver pgpkeys.mit.edu --recv-key 911A4C02
# gpg --edit-key codesign@isc.org trust
# gpg bind-9.10.2-P4.tar.gz.sha512.asc

fn=bind-9.10.2-P4.tar.gz
cp $fn ~/rpmbuild/SOURCES

sed -i -e 's/\(^%global PATCHVER\) P3/\1 P4/' bind.spec

LANG=C rpmbuild -ba --define 'dist .hk2' bind.spec |& tee build.log

sed -n 's/^Wrote: //p' build.log > bind-rpm.files

typeset -A rpmdict
rpmdict=($(for fn in $(grep /RPMS/ bind-rpm.files);
 rpm -qp --qf "%{NAME}\t$fn\n" $fn))
  
rpmnames=($(rpm -qa --qf '%{NAME}\n'|
 grep '^bind'|grep -v bind99|sort))
  
pkgs=()
for n in $rpmnames; do
 pkgs+=($rpmdict[$n])
done
  
sudo dnf upgrade $pkgs

sudo systemctl restart named-chroot

最後の YAPC::Asia 2015 、ボランティアで参加してみました

yapcasia.org

(今の形の) yapcasia は最後と聞いたので、最後くらいは少しでも恩返し出来ないかと、サポートスタッフのボランティアに参加してきました。

前日準備と前夜祭

ノベルティグッズの袋詰め作業(千人分以上?)は、事前の打ち合わせの時に牧さんが一番つらいと言っていたので、 私もかなり覚悟して行きました。でも実際にやってみると、(確かに肉体的には辛いものの) 意外に楽しめる面もありました(私にとっては。他の人にとって楽しめたかどうか…それは聞いてみないと分からない)。 記憶では、牧さんの予想時間より2時間?ほど早く作業を終えられた!とか。(11時集合で、14時頃にほぼ終わってたので…)

早く終わった理由を振り返ると、少し思い当たるのが、作業する自分たちを、並列プログラミングにおける『ワーカー・プロセス』に例える人が多かったこと、のように思います。並列度の大小に気を配り、ボトルネックを探し、思いついた改善を自ら即座に実行に移す人が多かったことと、それに誰もとがめず違和感ももたず自然に追試し良ければ即広める。でもそれが効果を発揮しない段階が来たらさっさと捨てて、また次なるアイディアの出し合いを楽しむ…そんな雰囲気が、うっすらですが、あったこと、でしょうか。

私の視点で振り返ると、

  • 最初の Tシャツたたみで、例の YouTube で話題になった2秒でたたむやり方を、自分の手で上手く出来るまでやってみたことで、改善意識に火が付いた。
  • 次に向かったノベルティグッズ詰めでも、工程の改善が見る間に進んでいった。
    • 当初は『チラシ重ね』『袋入れ』『グッズ入れ』『シール入れ』の四段流れ作業を4並列、だったかな?
    • チラシ重ねは、上に重ねるより下に重ねるほうが速いと気づく人が出て皆真似る→速度上がる
    • 速度が上がるとバッファがたまる→工程を減員して、別の工程に進んでもらう
    • 改善→移動を繰り返すうちに、全員が全工程に慣れる。
      • 今いる工程のパイプラインが詰まったら、自発的に別の工程に移動し始める
      • ムダに気づける余地が更に生まれる。
    • 『袋入れ』工程をグッズ入れ側で受持つように。
    • シールを一枚一枚、山から取ってトートバッグに直接入れるのは効率悪いと気づく人が出て、 シールだけまとめる人と、それ以外の工程の人へと分業
    • シールまとめの作業が狭苦しい感じだったので机を移動させる。ついでに移動距離も最適化

単調作業のストレスと肉体的大変さは有ったけど、こういった諸々の改善プロセスが、時間の経つのを忘れさせる面白さにもなったのかも?。勿論、仕事の工場とかだと、あんなふうに工程間を自在に行き来することは許されないでしょうけれど。

あの時、我々は、我々自身をプログラムしていたんじゃないかな…並列処理が当たり前の時代のプログラマーは、 ああいう作業の効率改善にも向いてるのかもしれない、な〜んて。

前夜祭

私は受付チームに配属されて、企業スポンサーさんとスピーカーさんの受付を @kaihar4 さんと一緒に受け持ちました。

開始早々、渡されてたリストが去年のだった!w なんてトラブルも有りましたが、 そこでスタックせずに『名刺だけもらって対応』路線にさっと切り替えを指示してくれた、 コアスタッフの女性陣、その後も随所に発揮してくれた柔軟性、臨機応変な対応力と適切な指示出しは、 非常に頼もしかったです。優秀な人は魅力的ですね!

英語圏のスピーカーさんの受付は、ちょっと緊張しましたが、牧さんに『お名前を伺ってもよろしいですか?』を何ていいますか?と聞いて『Can I have your name, please?』だと言ってもらえたので、よしこれ一本槍だ!と押し通しました。

一日目

やっぱり早起きが辛かった(^^

お昼までは、ひたすら受付してました。有名な方々が目の前に来るという点では凄く美味しいポジションだったのですが、 とにかく粗相をしないようにするのが精一杯、みたいな感じ。リストからお名前探すの遅くてごめんなさい!みたいな。『アメちゃんもどうぞ』で笑ってくれた方がそこそこ居てよかった…。

午後になって少し落ち着いたので、一件だけトークを聞きに行かせてもらいました。 個人的に興味が有ってどうしても聞きたかった WebAudio のトーク です。 WebAudio の全体像の説明がとても良くまとまっていたのと、 ScriptProcessorNode が Deprecated! みたいな最新の話題も 聞けて、更にそう来るか!みたいなビックリ応用の話もあって、大満足でした。

.oO(あの Canvasオシロスコープとか、github に置いてあるんでしょうかね…見てみたいな〜って…)

懇親会

color sync のお陰で、入場誘導が非常に楽でした。 (参加側だった去年までは、ごにょごにょって感じがあったので(><)。これは劇的な改善だったと思います)

いくつかの営業さんとお話出来たのは、もしかしたら今の仕事や将来に役立つかもしれないので、この御縁は大事にしたいなぁ、とか。

あと、大昔の O'Reilly の第一回 The Perl Conference Japan のトーク応募に私を誘って下さった、 前田 薫 さんが私に気付いてくださったのが、とても嬉しかったです。

るーるーるーだけの蛍の光で追い出し、楽しかった。(俺だけ?)

二日目

やっぱり早起きが(ry

(前の週のコミケ参加から続く)肉体的疲労もピーク! ですが、一日目に比べると遥かに暇で、まったりした感じでした。 ですので、交代で少しトークを聞くことが出来ました。

私は Jonathan Worthington の Perl6 の並列処理・非同期処理・並行処理のトークを聞きに行きました。 yapcasia.org

(同時通訳ではなく、英語だけで聞いたのですが)、彼の英語は、英語の耳さえ出来ていれば意味が追えるレベルのスピード・明瞭さだったので、内容に集中できました。

トーク後半の、Perl6 のメタプログラミング機能を使って書かれた OO::Monitors, OO::Actors の紹介の下りや、 "Concurrency is about competition to access and mutate" という概念把握は、非常に面白く聞かせてもらえました。

折角なので質問もしてみました。『メタプログラミングを使って実現しているとのことですが、 OO::Monitors や OO::Actors の複雑さはどれくらいか?例えば何行くらいか?』と(日本語で^^; 同時通訳さん、ありがとうございます) 尋ねた所、そんなに難しくないよ、monitor は 50(15?)行くらいじゃないかな?みたいな返事だったように思います。 ほんまかいな!と思ってググったら

oo-monitors/Monitors.pm at master · jnthn/oo-monitors · GitHub

今は 93 行だったけど、それでも凄いよ!

…それにしても、こういう技術的な質問を即席で英語で質問するのは今の私には非常に困難ですが、 日本語で質問して良いなら、かなり楽になりますね。やはり今回の通訳さんは、とても優秀な方だったのだと思います。

最後に, RJBS にバグの話を出来たこと

個人的に今回の yapcasia で、自分が達成できた一番大きなことは、 私が以前 RT に報告した perl5 のバグの問題を、 perl5 の開発まとめ役である @rjbs に話せたこと、 重大性を認識してもらえたこと、ではないかと思います。

↑このバグ自体の説明は省きます。詳しくは RT 参照、手元で動かせば重大さは理解できるはずです。

本当は懇親会の時に話しかければ良かったのですがボランティア業で頭が一杯で気づかず…

二日目の終わるギリギリに気付いて、でも rjbs は最後のトークを聞きに行ってる状況で。 でも諦めきれず、トーク会場に入ってこっそり彼の姿を10分ほど探すと、彼らしき人を発見。 トークに熱中してたら悪いな〜と思って遠くから様子をうかがうと、何やら手元に光る二画面の液晶が… DS じゃん!

なら迷惑にはならないか…と意を決して、彼に mention を飛ばした所、しばらくして、返事をくれました。

彼に私の服装(狂った紫の帽子!)を伝えて、 クロージングの後の、出口の所で待っていると、ちゃんと見つけてくれました。(今私のツイ見ると不定冠詞が落ちてるw)

後は、カタコトの英語でバックポートのお願いをした所、彼から今朝、RC に入ってるよ!って返事をもらえました。

これなら、少なくとも 5.20 以後は救われそうです。 Perl を主なプログラミング言語として使う者の一人として、この数カ月一番気をもんでいたことなので、 胸のつかえが取れた感じです。

Email での議論と違って、対面の英語は、身振り手振りを交えて英文自体の難度は相当下げることが出来るし、 相手の表情を確認しながら話せるので失礼がないか過度に心配する必要も無くなるので、 相手の英語を聞き取ることさえ出来れば かえって楽なのかもしれません。

中津燎子の英語未来塾で英語の発音改善に取り組んだ成果が出ているようで、 ちょっと自信がつきました。

まとめ

(IT)技術者がまともに尊敬される世の中に変わるために、何が必要か…久野先生との対話と反論

久野先生と、以下のような対話が有りました。(直接の面識があるわけではありません、念のため。 先生の著作 は好きですよ、ふふふ…)

私の反論が長くなりそうだったので、一旦こちらにまとめてみます。

私の考え

IT 技術者 以外 の、世の中の普通の人たちにも、プログラミングや情報科学の知識を広めることが、 世の中を良くするだろうこと は、勿論私も同意です。

『技術なんか知らん、金さえ払えば良いんだろ?』という(ビジネス側の)人間を、教育によって、生まれる前に消し去りたい…その気持ちも分かります。

ただ、IT 土方と呼ばれるような 奴隷っぽい扱い を本当に無くしたいなら、 最も大事なことは、 IT技術者側が、皆揃って、理不尽な扱いに抗い、拒否すること ではないか、 と私は考えるのです。そうして IT技術者を雑に扱う企業が淘汰されていく社会 を作っていく方が、 もっと直接的で効果的なのではないか、と。

そして、そのために鍵となるのは、

  1. IT 技術者も、非技術側の人間に頼らずにビジネス社会を生き延びられるだけの、複式簿記など商いの知識と、 お金の関わる交渉事をこなす胆力を身につけること

  2. IT 技術者自身が、起業したり社長になって、 IT技術者を大事にする企業を作り、 技術者が幸せになれる商取引の形を交渉して勝ち取っていくこと(ex. 「納品のない受託開発」、フリーランスな私の場合 - hkoba blog)、 技術者を使い捨てる会社を淘汰するべく戦うこと…

ではないか、そう私は考えています。

『技術の価値を知ってもらえれば、扱いが変わる』?

他人が自分たちをどう扱うかは、結局の所、他人の自由意思ですので…

『世の中の IT 知識の底上げ』は、勿論大事なのですが、 知識はあくまで中立な力でしかないので、 それをパワー・ハラスメントの道具に使う人間だって出るでしょう。

もっと言えば、 技術しか興味のない人間 (人間社会とガチンコで対峙し日銭を稼いで生き抜くことから、逃げた人間)は、 ビジネス層にとって、尊敬できる存在ではない、ように、私は想像します。むしろ、 カモにしても心の傷まない くらいの存在ではないかと。

そんなわけで、繰り返しになりますが、 もしゴールを『(IT)技術者がまともに尊敬される世の中』と設定するなら、 もっと直接的に『IT技術者を尊敬しない、大事にしない企業から、 技術者がどんどん流出して、淘汰されていく社会』を 志向した方が効果的ではないか?。

つまり、IT技術者自身が、理不尽な仕事を突っ込まれた時に、 ちゃんと No を言えること、 Win-Win or No-Deal を実践できること…

それが大事なんじゃないかな〜、と思っています。

備忘録:SQLite で timestamp と iso8601 を相互変換する定型句

忘れがちなので。ツッコミ歓迎です。 より詳しくはSQLite のマニュアル

timestamp(unixepoch) から iso8601 へ(現地時間で)

-- ts に timestamp が入っているとして。
select datetime(ts, 'unixepoch', 'localtime');

select datetime(0, 'unixepoch', 'localtime'); -- ex. 1970-01-01 09:00:00

-- datetime と等価な strftime
select strftime('%Y-%m-%d %H:%M:%S', ts, 'unixepoch', 'localtime');

utc で良い時は 'localtime' は省略できる

iso8601 から timestamp へ

-- timezone まで書いてあった場合
select strftime('%s', '1970-01-01 09:00:00 +09:00'); -- 0

-- timezone 書いてない時に、utc に戻すには
select strftime('%s', '1970-01-01 09:00:00', 'utc'); -- 0

roundtrip

% sqlite3 :memory: "select
 datetime(strftime('%s', '2015-07-31 16:11:02', 'utc')
          , 'unixepoch', 'localtime')"
2015-07-31 16:11:02
% 

オマケ。現在時刻の扱い。

-- iso8601 で. (timezone 抜き)
select datetime('now');

-- timestamp として
select strftime('%s', 'now');