2010/08/17
創作の目的
いつもスケッチブックを持ち歩いていた知り合いの絵描きは、下描きも無しに、人体の手先や足先、あるいは背景の一部から描き出して一枚の絵を完成させることができた。それは彼女にとってはただの手すさびだったかもしれないけれど、私はペンの先から次に何が産み出されるのだろうとわくわくしながら眺めていたものだった。
文章を構成する、てな話になったときに、「書きたいことがあって、それを章構成に分解して、必要ならさらに節、さらにこまかく〜」なことを言ったら、「書きたいことなんてないよ」と返されたことを思い出しまして。
書きたいことがないのに、文章とか書けるものなのか、と思ったわけですが。 同様に、プログラムなんかもそうだし、絵なんかもそうかと思うんですが。 「表現したいもの」や「目的」、「訴えたいもの」があって、初めて文章や絵、プログラム、音楽になるんじゃないのかな、と常々思っていたので、そういうもののない方とは、たぶん議論にならないな、と思ったな、という話で。
何かを作る、ということは、何か目的があるものではないか、と思うんですよね。 それが文章であれ、プログラムであれ、絵であれ、音楽であれ。
「良い作品には、明確な目的としっかりした構成がある」っていうのはたぶん真。 けれども、「良い作品を作るには、まず目的を明確にして、 トップダウンにブレークダウンして構成を考えなければならない。」というのは必ずしも真ではない。
知り合いの物書きは、他人から「お題」を募集して、それをネタに ショートショートを書く、というのをやっていた。一時期は一日一本の ペースで書いていただろうか。トータルで数百本になっていたはず。 大抵は、構成も結末も考えずに書き出すのだと言う。 自分で書きながら、予想外の展開となってこの先どうなるんだろうかとどきどきしたり、 驚くような結末を書いてから、ああこれはこういう話だったのかと納得したりするんだそうだ。
もちろん、かの絵描きや物書きがそんなふうに(描|書)けるのは、 それまで散々、きちんと構成を考えて(描|書)くという訓練を積んできて、 もうそれが身体に染み付いているからだろう。 その域に達してない初級者中級者に、 目的を明確にして、ブレークダウンして構成に沿って書くべきだ、というのは正しい。
起承転結だのパラグラフライティングだのといった方法論は、 人間同士のコミュニケーションの歴史の過程から結晶してきたエッセンスのようなもので、 それに乗っかっていれば通じやすいことが実証されているわけだ。 伝えたいことが明確で、他人とのコミュニケーションをゴールとするなら、 実証されたやり方に乗っかるに越したことはない。
けれども、創作行為にはもうひとつ、重要な役割がある。 自分とのコミュニケーションだ。 作品という具体的なアウトプット=自分のココロの一面の投影を外部に作ることによって、 「自分が本当は何を言いたかったのか」を知る、という役割である。 作ったあとで振り返ってはじめて目的がわかる、というパターンだ。
「何か目的があるから作品をつくるのだ」というのは間違ってはいないけれど、 出発点となる目的が作者に最初から見えているとは限らない。 そもそも、「これから作る作品のテーマは××です」と言葉にして全部済ませられるなら、 わざわざ苦労して作品の形にする必要はないではないか。 小説なり、音楽なり、絵画なり、そのメディアでしか表現できない何か、 コトバで簡潔に言い表しようの無い何かがあるからこそ、 そのメディアを選んで作品にするのだ。
(作り手が、スローガンのように明確なメッセージを自覚していてなお作る作品、 というのも無くはない。それは普通、「宣伝」と呼ばれる。)
出来上がった作品を第三者が分析する時には、テーマを確実に掴むために ワンセンテンスにまとめる、といったテクニックがあるのだけれど、 それは「言葉になり得なかったもの」を捕まえるための グリップにすぎない。 作者の頭の中に最初からテーマとなるセンテンスがあったわけではないのだ。
目的を強調しすぎる弊害はいくつかある。 「これを表現したいんだ」とあまりに強く思い込んでいると妙な力みが入り、 創作の過程で「降ってくる」新しいアイディアを掴み損なうかもしれない。 「これを表現したいんだ」という想い自体が、自分でも直視したくない別の動機を 隠すための思い込みかもしれない。
けれども一番の弊害は、そうやって作っていると、作品は常に想定内に収まり、 自分の予想を越えて化けるということが無い、ということだろう。 それはそれで、作り手にも受け手にも安心感があり、そういう安心感の需要というのもある。 でも、それだけをやっていて飽きないでいることは、とても難しい。
そもそも、目的を明確に決めずにつくりはじめることなんて出来るんだろうか、 と疑問に思うかもしれない。そんな人は、「目的」と「題材」の違いを認識すると 良いだろう。スティーヴン・キングは超常現象や怪奇現象を題材とする 小説ばかり書いているけれど、彼の作品のメインテーマはほとんど常に、 人は人の心の中の制御不可能な部分とどうやって折り合いをつけてゆくのか、 という問いを中心としている。たぶん、そういうテーマを書こう、 と構えて書いてるわけじゃなくて、インタビューやエッセイから 察する限りでは、単に怖い話が大好きなだけだと思う。でも怖い話を書くと、 そういうテーマが忍び込んできてしまう。クーンツのホラーとキングのホラーで 読後感が全く異なるのは、そのせいだ。
ポイントは、何かをつくりはじめるには「題材」があれば十分だ、ということだ。 先に「目的」がある程度はっきりしていて、それに沿った「題材」を選ぶことも できるだろうけれど、「目的」が良く分からなくても、どうも気になって 仕方がない「題材」に出会ってしまう時ってのがある。 それは、きっと自分でも意識していない「目的」がゴーストラインの向こうから 囁いているんだ。だからとりあえず、手探りでいいからその題材を料理してみよう。 そして、霧の隙間から本当の目的の姿が垣間見えるのを見逃さないように、 アンテナをぴんと立てておこう。
あ、ちなみにこのエントリの話は、小説や絵画だけじゃなく、 プログラミングにも結構当てはまる話だと思うよ。
Tags: ものつくり, 表現, Programming
2010/08/16
アナリーゼを習いたい
ひととおり音符を追えるようになったら、 何か違う景色が見えるかもしれないと思い、 8年くらいかけて、ショパンのエチュード24曲を拙いながらもさらってみた。 出来上がったのは、退屈な演奏だった。 テクニカルな限界という、足に絡まる海藻をちょっとだけでも振り切って やっと水面に顔を出してみたら、垣間見えたのは茫漠とした海原だったって感じだ。
(別にがっかりしてるわけじゃなく、 むしろ「ああ、こうして退屈な演奏というのが出来るのだなあ」と感心することしきりなのである。 あと、色々テクニカルなコツはわかってきた。 Op.10は6年かかったけど(うち2年ブランクだけど)、 Op.25は2年で済んだのは、進歩と言えるだろう。)
Moffettのアクティングクラスで学んだのは、 役者の仕事は、上手く演技することではなく、 脚本の「イイタイコト」をいかに効果的に伝えるかにある、ということだった。 表現の技術はその手段にすぎない。 どんなに上手くても、脚本のイイタイコトを理解せずに演技していたら、 それは失格だということだった。 そして、そのための脚本の読み方というのがある。
そのアナロジーで考えれば、 楽譜の中に込められた「イイタイコト」を読み解く方法を、自分はまだ知らない。
脚本の読み方を知った時、霧が晴れたように感じた。 良くできた脚本では、「イイタイコト」は太字の拡大フォントのステッカーで 脚本の最初から最後まで、あらゆる箇所にべたべたと貼り付けてある。 ただ、読み方を知らなければ全く見えないだけなんだ。
アナリーゼというやつを学んだら、音楽についても同じことが起きるんじゃないか、 と期待している。
2010/08/15
文字クラスのマッチ
正規表現の[]でくくった文字列クラス内の文字の並びがマッチ速度に 影響を与えるかどうか、という話題。
対象となるコードが1バイト(つーかオクテット?)の範囲に収まるくらいなら、 ビットベクトルを使うのが多分常道で、その場合はどう書いても実行結果は同じのはず。 マルチバイト文字やらワイド文字やらUnicode なんかが対象に入ってくると これはもう実装次第としかいいようがないわけで。 仮に対象を Unicode としてその大きさがほぼ100万文字というパターンを考えると、 ビットベクトルでこれを収めるには…と。 まあイマドキの環境だったらどうってことないのかなあそれでも。
GaucheではASCIIの範囲はビットベクタ、それ以降は連続する文字の「範囲」を treemapで管理してる。各範囲の下限をキー、上限を値として。 なので順番は関係なく、ルックアップ速度は「範囲」の個数nに対してO(log n)。
まあ、treemapは内部的に既に持ってたから使っただけで、 単純に範囲をソートして配列で持っておくだけでもバイナリサーチかけられるので、 そうしない手はないと思う。 なので「順序で影響が出るような実装を使うメリットが思い当たらない」かなあ。
範囲で管理するのは、不連続な小領域が大量にある場合にえらく不利になる。 実用上たぶんそんなことは滅多に無さそうだとは思うけれど、最悪値を 良くしたいなら、範囲の数が閾値を越えたらビットベクタに切り替えるって手はある。 全部ビットベクタにしなくても、ある深さまでは範囲で、その下は その範囲だけのビットマップ、というふうにもできるだろう。
話はずれるんだけど、Gaucheは文字列をマルチバイト表現 (デフォルトutf-8) で 持ってるので、正規表現エンジンは文字単位ではなくオクテット列に直接 マッチをかける (マッチ開始位置は常に文字境界なので、euc-jpやshift_jisでも 非文字境界でマッチしてしまうことはない)。 なので基本的に utf-8 <-> ucs-4 の変換は 起きないのだけれど、ASCIIをはみ出す文字クラスの時だけはこの変換を行わないと ならない。
でも、ucs-4での文字範囲は、utf-8で表現したオクテットの範囲のツリーに 変換できるはずなので、それをやれば完全にutf-8のままマッチがかけられる。 もう何年も前から試したいとは思っているのだけど手をつけられていない。 そういう実装をやってるエンジンってあるのかな?
Tags: Programming, Gauche
2010/08/03
sambaプチはまりメモ
Ubuntu 10.04に入れ替えたら、sambaで別マシンからつなげなくなってることに 気づいた。[homes] セクションでホームディレクトリを見えるようにしてるんだけど、 外のWindowsから \\server\shiro でマウントしようとすると ひたすらパスワードを聞かれるだけでマウントできない。 入れ替えるまでは問題無かったので、smb.confのデフォルトが何か変わったのかなと 調べてて余分な時間を費やしてしまった。
原因は、確かに新しいバージョンで変わったところにあったのだけど、 その変わった箇所というのが意外な盲点だった。たぶんこれではまるのは特殊例。 トラブルシューティングの手順をメモっとく。
- sambaのdebug levelを上げてログを取る。最初log level = 2 で
check_ntlm_password: Authentication for user [shiro] -> [shiro] FAILED with error NT_STATUS_NO_SUCH_USER
というのがわかったが、これでぐぐっても一般的すぎてあんまり役に立たない。 - log level = 3にしたら手がかりらしきものが。
check_sam_security: Couldn't find user 'shiro' in passdb.
自分のアカウントが登録されてない? - passdbってなんじゃい、と思って調べる。sambaは独自にユーザデータベースを 持ってるのか。デフォルトでは /var/lib/samba/passdb.tdb というのを 見てるらしい。こいつの中身を覗くにはpdbeditというコマンドが使えるようだ。
- pdbedit -L すると確かに、他のユーザのエントリはあるのにshiroがないぞ。 他のユーザのエントリは多分インストール時に/etc/passwdから情報を取ってると 思うんだが、なぜshiroだけ抜けたのか。
- ひとつ怪しいのは、shiroのuidが500であること。最近のLinuxでは 一般ユーザのuidは1000から割り当てるけど、昔はもっと小さいuidを 使ってたのだ。500というのはたぶん10年以上前にLinuxをインストール した時に割り当てたuidで、OSを入れ替えても ファイルシステムをそのままアクセスできるようにずっとキープしていたのだった。
- でも、最近のディストリビューションだとuid < 1000 はシステムアカウント 用だから、sambaインストール時のpassdb構築時に無視されたんではないか、と推測。
- ビンゴ。"passdb.tdb uid 1000" でぐぐって http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=502801 に至る。
- UID_MIN とかをいじって再インストールするのも面倒なので、 pdbedit -a -u shiro として直接エントリを加えた。 これで解決。
uidを変えるべきかなあ。でもいくつもあるマシンを非同期に アップグレードするから、一斉に変えるのって面倒なんだよなあ。 かといってディレクトリサービス上げるほどの規模でもないし。
2010/08/03
ヘッダにstatic member
C++の class template を使えば static メンバの実体がヘッダファイルに書けるカラクリ - ひげぽん OSとか作っちゃうかMona
C++の class template を使えば static メンバの実体がヘッダファイルに書けるというテクニックがある。考えてみると不思議な動作に思える。だって分割コンパイルしたら実体が複数個出来そうじゃない?。この裏側で起こっている事を実験前に予想して試したところ、予想通りだったのでうれしかったのでメモを残す。
リンカがよしなに計らってくれるのか、なるほど。と思ったけど じゃあリンカの預かり知らぬところで共有されたらやばそうだよなあ。 例えばdlopenされるやつとか。
環境はgcc-4.4.3 on Ubuntu 10.04。
Hoge.h と a.cpp はひげぽんさんのと同じ。 b.cppはdlsym経由で 呼びやすいようにC linkageにしておく。
b.cpp:
#include "Hoge.h"
extern "C"
void funcB()
{
Hoge<bool> hoge;
hoge.incrementAndShow();
}
mainはこんなかんじ。
main.cpp
#include <dlfcn.h>
#include <stdio.h>
#include <errno.h>
extern void funcA();
void (*pfuncB)();
int main(int argc, char *argv[])
{
funcA();
void *h = dlopen("./b.so", RTLD_NOW);
if (!h) { perror("dlopen"); return 1; }
pfuncB = (void (*)())dlsym(h, "funcB");
if (!pfuncB) { perror("dlsym"); return 1; }
pfuncB();
dlclose(h);
return 0;
}
ビルドはこんなかんじ。
Makefile:
all : main b.so
main : a.o
g++ -o main main.cpp a.o -ldl
b.so : b.o
g++ -shared -o b.so b.o
b.o : b.cpp
g++ -fPIC -c b.cpp
clean :
rm -f main *.so *.o *~
実行結果。別々のHoge::counterの実体を見てる。
$ ./main counter = 1 counter = 1
まあ仕方ないっちゃ仕方ない話だけど。 外部APIとして見せるクラスでこのテクニックを使う場合は落とし穴になるかも。
(なお、b.cppを共有ライブラリlibb.soにしてmainリンク時に -lbでリンクした場合は、ちゃんとHoge::counterは共有される。)
理想的には、ランタイムがもっと賢くなって、 実行前の静的なリンク実行時の動的なリンクも同じように扱って くれればいいのかなあ。
Tags: Programming, C++

Comments (0)