RとBioconductorに触れている

Juliaの次はBioconductorのライブラリを試している。

世間ではPythonが人気のようだけれども、生命科学の領域ではPythonが人気とまでは言えない。
Bioconductorの審査制度があったりして、これからも末永くRの天下が続くのではないかという気がする。

Rに慣れていないので、勘違いだったらいけないけれども、
Rubyと全然違うところは、トップクラスにニョキニョキと関数を生やしていくことである。
ネームスペースとか、オブジェクトとかの概念は、弱いようだ。

そういう意味では単純でわかりやすい言語なのかもしれない。

WEB+DBのJulia特集を読んだ

ここ数日、Juliaに少しずつ触れようとしている。

Ruby言語しか知らないので、新しい言語にふれるとものすごくストレスを感じる。
Juliaのデータフレームが使いやすいとは思えず、Daruって意外とよくできているんだなと思ったりした。
Pythonも何回か挑戦したけどあきらめてしまった。Juliaは粘り強くやらないとね。

WEB+DBのJulia特集が出たので読んでみた。Julia1.0が登場した時期なので、これからJuliaを始めるにはちょうどいい時期らしい。

読んでみて、やっぱりJuliaはRubyに似ているなと思った。

 だから一番記憶に残ったところは、Rubyとは全く違うところ…「多重ディスパッチ」だ。データの操作とデータの定義が分離しているとのことだ。これはRubyと違う。真っ先に思い出したのは、Crystalのオーバーロードである。Crystalは、メソッドの中で型を判定しようとはせず、引数の型ごとにメソッドを別々に定義する。これは便利な機能である一方で、制約にもなると思う。

 Rubyの場合、引数の型が何であるかはわざと曖昧になっていて、型の判定はメソッドのなかでゴチャゴチャやることも多く、その方法も必ずしも一通りではないと思う。最近にはRubyにも型を導入しようとする流れがあるみたいだけど難しいことはよくわからない。

 けれども、JuliaはCrystalとも違う。Crystalはデータ解析向けのパッケージは充実していない。もしもCrystalに優秀な統計・行列計算のパッケージが付属すればJuliaのような言語になったのかもしれない。

 Crystalで特に素晴らしいと思ったのは、crystal コマンドであった。Rubyにおいてbundler(パッケージ管理), yard(ドキュメント), pry(REPLなど)が提供している機能が統一感のある簡潔なインターフェイスで提供されていて美しいと感じた。Rubyのbundlerやyardやpryはもともと外付けのツールで、Crystalのほど一体感があるわけではない。 ところがJuliaはこの点はむしろRubyよりもさらにいい加減にする方針のようだ。パッケージ管理やプロジェクトの管理についてはすべてREPLで行い、コマンドラインツールは使わないようである。確かにREPLの中で新しいライブラリを追加できたり、プロジェクトを作れるのは便利である。でも、これはとりあえず一つのメソッドを作って、その中で様々な型を判定して使い分けるRuby方式に近く、多重ディスパッチの努力までしているJuliaっぽくない…と感じたりする。

 だから、REPLの中で全部やるっていうのは、スタートアップ時期に人を集めるための工夫で、黎明期は便利だけど、ひょっとすると普及後の未来には足かせになるかもなと思った。

 Pythonを勉強している時は、Rubyの方がわかりやすいと感じることが多くて、なんでPythonが群を抜いて素晴らしい言語のように言われているのだろう?控えめに見てもRubyよりも劣っている点いっぱいあるよね?欧米人はこういうのが好きなの?と納得いかないことも多かったけど、Juliaの場合は、Rubyっぽい記法が随所に見られて「これならRubyから乗り換えても仕方ないか。やっぱりPythonの文法よりもRubyの文法の方が使いやすいと欧米のみなさんも思ってたんだね。納得〜」と感じる謎の安心感がある。引き続き勉強していきたい。

Juliaを使ってみた

最近、Juliaという言語がすごいらしいので使ってみた。使ってみたといっても文法とか何もわからないので、Jupyterのセルに、サンプルをコピーアンドペーストして実行しているだけだ。コードの内容はまるでわかってない。

実行してみて思ったのは、なるほど〜これなら普通に流行るだろうなという感想。あと、Pythonのコードを見てるとどうしても聞こえる(コレジャナイ…、ナゼRubyジャナイノ?)という心の声があんまりしない。どーせCodeなんかまともに書けないんだから違いはないはずなのにね。なんでかね。

Julia早いと言われてるけど、実際にはプリコンパイル入るので特に初回の実行に関しては早い印象ない。むしろ遅い。それから、すでにNumPyやNarrayをゴリゴリに入れてる計算に関しては、何倍も早くなるということはなさそうである。

それからデータフレームとか、データを集めてくる部分についてはまだ弱いし、そういう雑多な機能でごちゃごちゃしてくるとJuliaどうなっちゃうのだろうという感じが少しある。そういうJuliaの欠点の萌芽のようなものもすでにありそう。

Python、とくにpandasを置き換えるかどうかはわからないけど、相当流行るのは間違いなさそう。

バイオでもゲノムのマッピングのようなマシンパワー食う操作についてもC++で書かれたツールと匹敵するぐらいの速さが出たら面白いと思う。

Orangeすごいなあと思った

世間ではCloud AutoMLが流行しているようだ。

Google先生の戦略は「生産手段の私的所有が基本となっており、生産手段を持つ資本家が労働力を購入して商品を生産する。」みたいな大昔マルクス先生が主張された世界観を一世紀遅れで実現しているような気がして、あまり好きになれない。

生産手段を誰もが手にするためには、データセンターをみんなが作れるようになる必要があり、誰でもCPUを生産できるようにする必要がある。けれども、さまざまな政治的な思惑から、技術を禁止しようとする動きがあちこちで起きているようである。

これはそんなにおもしろい話ではない。なので注目している人が少ないであろうOrangeの話を書く。

Orangeは、スロベニアの リュブリャナ大学が開発しているScikit-Learn, Numpy, ScipyなどをGUIで操作できるようにするラッパーである。Githuのリポジトリをちらっと見た感じだと、全部Pythonで書かれているようだ。

なぜOrangeを知ったかというと、Anaconda-Navigatorがゴリ押ししてきたからである。ゴリ押しだなあ!と思ったので最初はいい印象がなかったが、とあることから使ってみて「これはすごい」と思った。

少なくとも、僕のようなど素人が、せこせことPythonやRubyのコードを、拾ってきてはJupyterにコピペするよりも、遥かに高速にかつ確実に解析ワークフローが作れるのである。Orangeが実現したUIは、将来的にどこか大企業が製品を発表して、Excelのように普及していくのではないだろうかと思った。MSがパトロンをやっているAnacondaがOrangeをゴリ押ししているので、Microsoft製品がそっちの方向に進化していく可能性もありそうだ。

しかし「すごい」と「普及」はまったく次元の違う話である。OrangeはPythonですべてGUIを書いている。ここから想像されるように、動作はもっさりしており、信頼性はあまり高い感じではない。そういうわけでOrange自体が今の形で普及することはないだろう。

なによりもスロベニアの大学が開発しているところが厳しい。プロダクトが普及するかどうかは、そのプロダクトの最初のコンセプトの輝きよりも、開発団体の体力で決まってしまうところが大きい。たとえ開発が継続できても、より大きなプロジェクトがやってきて飲み込まれてしまう。

そういうわけでOrangeは10年後にはなくなっている可能性が高いとは思うけど、言いたい。私はすごいと思いました。

どうしてOrangeがマイナーな存在なのか、ということを考えると、「データのローカリティ」ということが思い浮かぶ。Ruby用のクラスタ計算ソフトPwrakeでもデータのローカリティが計算速度に大きな影響を及ぼすとしている。ゲノム解析ではデータのサイズが大きすぎるので、データのダウンロードが一番大変な作業である。

OrangeはWebを用いたGUIではなく、Qtを使用している。もちろんsshでX11を使うという方法もあるかもしれないが、このソフトウェアは、基本的には手元のPCで手元のデータを処理することを考えているといっていいだろう。

私たちは、データは価値そのものだという現代的な価値観に染まりすぎているので、データのローカリティについて考える時、どうしても何か感情が邪魔をする。そんなことを考えた。

Rumale の分類器を比較してみる その1

Rumaleの分類器を比較してみた。
Gnuplotを使っているのだが、missing blank lineという残念な仕様があったりして、なかなかコードがキレイにならない。Gnuplotは高機能だけど一貫性がなくて流行らないわけだと思う。
今日できたところまで。ちゃんと整理ついたらQiitaとかに投稿したい。

RubyとDaruのイテレータについて

最近RubyのDaruを使っていて、もやもやと考えていることがある。

しかし頭がまとまらない。理由の一つはRubyのコードしか書いたことがないので知らないプログラミング概念がたくさんあるからかもしれない。そういうのを勉強すれば、もっとクリアな理解が得られるかもしれないという気がする。

習熟できなくても、概念に触れることはできるはずで、無理だと思わずに、C++やらrustやら難しいものを適当にかじってみた方がいいのかもしれない。しかし、今考えていることをアウトプットしておく。

Daruの使い方を調べていて、混乱したのが、イテレータであった。map や each である。私はmapが大好きだ。しかし、どうも最近mapがいかがわしく感じるときがある。

DaruにはVectorというクラスがある。データフレームは、ArrayとHashとNumPyの機能が全部必要だから、新しいクラスが必要なのだ。mapすると、Arrayが返される。これが直感に反する。Arrayではなく、Vectorが返ってきた方がよいのではないか。

それに、Daruを全面的に信頼できなくて、結局to_aを使ってしまうのである。こうなると、ArrayやHashを使うことになり、Daruの機能を使わないことになる。

そして、一度mapに疑問を持つと、いかがわしく見えてくるものがある。ブロックである。

私は上のコードが好きだ。わかりやすい。一方で、自分でイテレータや、yield を書くほど、プログラミングできるわけではない。ブロックを受け取るようなメソッドを自分で作ることない。

話がとぶが、Rubyを使い始めた頃、メソッドがオブジェクトではないのがすっきりしなかった。動的にメソッドを定義したり、削除したりすることはできても、メソッド自体はオブジェクトではない。

みたいな書き方ができない。Rubyでは、メソッド、Proc、lambda、lambdaのあたらしい書き方、ブロックなど、関数っぽいもがたくさんあって、ゴチャゴチャしているのである。

最初はDaruのイテレータが混沌としているのは、Daruの設計が悪いからだと思った。

けれども、ひょっとするとこれはArrayやHashを使わずに独自のクラスを設計すると常に発生する問題かもしれないと感じたのである。なんでもやってくれるArrayと、mapと、オブジェクトではないブロックの組み合わせは、ひょっとすると、本当はいびつなのかもしれない。どんな作業でもArrayを使うからあまり気にならないだけで。

だとすると、Arrayによく似たオブジェクトとイテレータを設計するのは難しい。もしApache ArrowのようなバックエンドのライブラリがRuby用の新しいデータフレームに採用されても、Rubyらしいイテレータを作成しようとするとまた困ってしまう。

map はブロックではなく、オブジェクトを引数に取る方がきれいかもしれない。そして、ブロック、メソッドは1種類のオブジェクトの方が美しいかもしれない。mapはArray以外のオブジェクトに対しても適応されることがあるので、Array以外のオブジェクトを返却する方が自然かもしれない、などと素人考えで思ったりする。

ruby 2.6 が出たので触ってみて、python と比較してみた
という記事を読んでみて、lambdaをフル活用したRubyが新鮮だったこともあり、そんなことを考えた。

こういう素朴な記事は、よく知っている人にとっては、恥ずかしくて書けないんだろうと思う。わからないことだらけだ。

想像だけど、きっとブロックをオブジェクトにするには、なにか実装に大きな問題があるのだと思う。そうでなければ、何でもオブジェクトにしたがるRubyで、ここまでグチャグチャしているはずがない。ブロックは、周囲のスコープを眺めることができる。つまり、ブロックは定義された位置に依存する存在なので、オブジェクトにするのには何か支障があるのかもしれない。

日本語でもそういうことはよくある。「県立図書館」がどの建物を意味するのかは、その単語が使われた都道府県によって全然違うだろう。ヒトは情報を処理する時に、そういう位置依存・文脈依存的な処理をフル活用している。自分だけではなくて、周囲環境が考えてくれてると言ってもいいかもしれない。

データをクレンジングを行う作業のうちいくらかの部分は、そのような文脈依存を剥ぎ取るための作業だと感じるときがある。

Daruのメリットを考える

Qiitaに投稿したDaruを使うから主観が強すぎるところをブログに移動しました。

Daruのメリットを考える

データサイエンスのツールとしてプログラミングをやりたい人が気にするのは次のような点だろう。

  • Daruは信頼できるのか?
  • Daruには継続性があるのか?
  • Daruのバグは少ないのか?

 正直に言うと、いずれもあてはまらない。Daruの信頼性はあまり高くなく、熱心に使い始めると小さなバグをそこかしこに見つけることができるだろう。Daruはビジネス上の緊急の問題解決に応えるためのツールではないのである。しかし、Daruのソースコードは小さく、速度に最適化されていないため、詳しくない人でも読むことができる。

 Daruを使ったデータ分析は、ビジネス上の問題を解決することや、Kaggleで高得点を出すことから、少し離れたところにある。一番効率的なツールを使って、最高の手段で問題解決に資したいと思うのは自然なことだ。そして、そのことで周囲から評価されたらなお嬉しいと思うだろう。
 ところが、そうやって問題解決のために自分を最適化することは、よいことばかりではなく、一歩引いて見るとある種過学習のような状態におちいっているケースがある。
 よくもわるくも、Daruにはそのような心配がない。これがRubyでデータ処理をやろうとする隠れたメリットの1つかもしれない。

もちろん、そのようなメリットがあるのは理解できるけれどもデメリットの方が大きいだろう、というのが一般的な考え方だろうなとは思います。

numo-narray に依存している Gem の一覧を作ってみた

Qiitaの記事:特定の gem に依存している gem の一覧を調べるによると、RubyGems.org の提供している下記のAPIを叩くことで、簡単に依存しているGemを調べることができるらしい。

これでnumo-narrayの依存しているGemを検索してみるとしよう。

2019年1月6日現在で

numo-narray に依存する Gem

Gemの名前内容
ruby-dnnディープニューラルネットワーク
gray_scott_gtk3反応拡散系
svmkit機械学習
smalltext文書分類
cumoGPU対応
numo-linalgBLAS/LAPACK バインディング(公式)
red-chainerディープニューラルネットワーク
nnニューラルネットワーク
rubexRuby拡張のためのプログラミング言語
machine_learning_workbenchベンチマーク??
hanny最小近傍法
numo-gslGNU Scientific Library 対応(公式)
neural_network_rbニューラルネットワーク
ffi-gdalGDAL(地理空間データ)
dicom医用画像
magnifier-ruby異常検知
numoネームスペース(公式)
numo-fftw離散フーリエ変換
red-arrow-numo-narrayApache Arrow
rblearn機械学習

こんな感じだ。こうやってリストにして表示してみると趣がある、

 個別のプロジェクトを眺めていても、プロジェクトや作者の隠せない個性みたいなものがちらっと見えたりして、とそれなりに楽しい。作者の名前もだいたい1回は見たことがある気がする。完全に観測範囲外だったのが、ruby-dnn と、ffi-gdal と magnifier-ruby。

 numo-narray が依存しているプロジェクト全体の広がりみたいのも結構面白い。

 こうやって眺めていると、一般の人がどんどんプログラミングができるようになって…開発者とユーザーの境界がなくなっていく、みたいなのは幻想なんだろうな、とふと思った。pythonやnumpyのような過密地域ではどうだか知らないが、Rubyのデータ処理のような過疎地域では、ユーザーの集合が、そのまま開発者の集合みたいな世界になっていて、みんなコツコツ自給自足しているようだ。そして、そういう世界では、プログラムはものすごくできるか、全然できないか、のどっちかしかありえない。初心者が生きるには厳しすぎ、上級者はあまりにも長くそこに定住して上級者になっていく人たちだからだ。

 そんななか、ひたすら開発者の道具をつかっていくユーザーが開発者の3倍ぐらいる状況がたまたま誕生すると、コミュニティは大きくなっていくと思う。そのような状況下でのみ、コミュニティが拡大し、コミュニティが拡大するほんの短い期間だけ、初心者と、中級者と、上級者がグラデーションのように存在するのだろう。それ以外の時間は、消滅する初心者と、ひたすら強い上級者だけが存在し、多様性が失われる。

 データの裏付けは何もないが、そんなことを考えた。

 考えてみると、数年前からこのブログでnumo-narrayの宣伝をしているが、ブログを読んで「パソコンに強い人たち」が numo-narray を使っていろいろ「すごいもの」を作ってくれたら、私は非エンジニアとしてRubyを使い続けながらその成果物を利用できるんじゃないか。みたいな下心が強く渦巻いていたことは否めない。というか今でもある。実際にはそんなことは起きなかったけれども。

 しかし、上記の結果をぼーっと眺めていると、「パソコンに強い人たち」がRubyで「すごいもの」を作る現象は、これからも起きにくいんじゃないかという気がする。それに、なんというか、最近は、本当に面白くて大事なところって、「そこ」じゃないんだろうな〜、という気もしている。これは最近生まれた気持ちなので、どういうことなのか自分でもよくわからない。

 あとは、何というか自分のような人間は思っている以上に希少ということが再確認された気がして、微妙にうれしくない。まさか「初心者が numo-narray を使って役に立たないけど面白いものを作ってみました」的なGemがこんなに少ないとはね。オリジナリティがあるのは結構だが、Rubyの代わりにPython勉強した方がよかったかな。

Cumo/NArray をつかってみた

(Cumo/NArray によって生成された画像(GIMPによる加工あり))

https://github.com/sonots/cumo

 結論から言うと、思ったよりよかった。

 Cumo/NArray とは、RubyでGPUを使って行列計算するためのライブラリ。開発している方の所属をみると、PFNとかDeNAがちょっと関わっているようである?

 世の中のGPUの90%ぐらいは、GPUをゲームシーンの表示のために使っていると思う。残りも多くは、3Dレンダリングなど、画像・動画表示編集ソフトなどに使われているだろう。

 そこからさらに少ない人が、GPUで仮想通貨のマイニングをしたり、DeepLearningをしている。マイニングやDeepLearningのアルゴリズムを自分で考えるのは普通無理なので、他の人が書いた行列計算のセットを実行している人がほとんどだと思う。

 GPUでカスタムな行列計算を大量にしようとか思う人はもっと少ない。

 そういう行列計算をたくさんする人は、だいたい科学者とか、コンピュータのエンジニアとか、そういう特殊な人たちだ。コンピュータに詳しくない人も詳しい人が行列計算をする必要に迫られた場合でも、まずは信頼性と情報量の多さを考えてPythonとかC言語とかを使うのが普通なので、RubyでDeepLearningとも仮想通貨とも関係がない高速な行列計算がしたい人は世界でも、まあ、多く見積もって10〜30人ぐらいしかいないんじゃないかな。

 そういう、世界全体でもほとんど発生しない、すごくニッチな需要が、昨日エンジニアでもなんでもなく趣味でパソコンをやってるだけの自分の中で発生した。自分の中で発生すればそれは1件でも100%である。よって、はじめてCumo/NArray をつかってみた。

 そもそも何でいままでCumoを試してこなかったかというと、メインのパソコンをUbuntu 18.10 に移行したからだ。18.10には公式のCudaが提供されておらず、インストールが面倒くさい状況になっていた。DeepLearning で遊ぶためだけにUbuntuをダウングレードして手元の環境を壊すのもちょっとな…と思った。

 それに Cumo/NArray にも期待していなかった。ひとたびGPUが絡むと、Tensorflowのように有名なライブラリですら、Cudaのバージョン、Pythonのバージョン、Anaconda、Ubuntuのバージョン、必要なライブラリやらアップグレードやらで、インストールやコンパイルは複雑怪奇・悲喜こもごもになる傾向がある。もはや個人で遊ぶには迷惑な存在なのである。Docker とかAWSとか知らんし。

 ところが、先日Numo/NArrayでちょこちょこ遊んでいる(Pythonのコードを参考に参考に書き写した)Gray-Scottのモデルの計算があまりにも遅いので、どうにかしたいと感じるようになった。何しろ、ちょっと大きな画像を得ようとすると、それだけで結果が出るまで半日かかる。

 そこでいよいよ Cumo/NArrayでも使ってみますか(それでだめだったらcupyでも試してみるか)、ということになったのである。気は進まなかったが、GeForce GTX 980 Ti を搭載したちょっと昔の自作PCを立ち上げて、Cudaアップグレードして、Cumo/NArray をインストールしてみた。

 結論から言うと、インストールは拍子抜けするほど簡単だった。

これがまず予想外。エラーがたくさん出てインストールできないと思っていた。エラーが出ても、ユーザーが少ないのでStackOverFlowを頼ることはできない。途中で挫折して、GitHubのissue欄に「エラーが出てインストールできません > < (Help me!)」というクソコメを残して撤退する予感があったので、あまりに簡単にインストールが終了して拍子抜けした。

 インストールは成功したように見えたが、ちゃんと動作するかまるで信用できなかったので、rake compile を実行してあからさまなエラーが発生しないことを確認した。さらに rake test まで自分で実行してみた。これ、普段なら絶対にやろうとも思わないやつである。全部パス。ここでまたびっくりした。

 しかし、本当にこいつGPUで動いているのか? もしかして、GPUが使用できないときは、バックグラウンドでNumo/NArrayやRubyで計算してヌカ喜びさせているだけちゃうんか?という不安が襲ってきたので、ターミナルで watch -n 1 nvidia-smi を実行。テストの実行中に見事にGPUの使用率が上昇しているのを確認した。最初からちゃんと動いていたのである。ここまでインストールしただけだが、感動の連続であった。

 そして、Numo::NArrayのコードをCumoに置き換えたが、これがまた普通に動く。メソッド #linespace と #clip には対応していないようだが、ちょっと書きかえればいいだけなので大きな問題にはならない。むしろ予想したよりも広くNArrayの基本的なクラスやメソッドをカバーしているみたいでとてもよい。

 さらに、計算速度も早い。実は、計算速度も全然期待していなかったのである。WebGLを利用して行列計算をしているというgpgpu.js の公式サイトに、5倍ぐらい高速になりますよ、と書かれていたので、Cumo/NArrayも5倍ぐらい高速になればいいかな〜と思っていた。ところが、ディープラーニングでCPUをGPUに切り替えたときのアレみたいに、普通にめちゃくちゃ計算が早くて!!また感動してしまった。

 このようにCumo/NArrayを使ってみた印象はとてもよかった。最初からあまり期待していない方、インストールに対する感動の閾値が低くなっている方にはおすすめです。(もうちょっと遊んでいると印象が変わってくるかもしれないけれども)

 使ってる人があんまりいないと思われるので、とりあえずブログを書いてググラビリティを側方支援、と。

Gemを作って気がついたこと

 書捨ての100行ぐらいのスクリプトではなくて、RubyのGemを公開するのは2回目である。前回のGemは変なGemだったので、ある程度ちゃんとしたGemは今回が初めてだと思う。いくつかやっているうちに気がついたことがあるので、忘れないうちに文章にして記録する。

ソフトを世界中に公開できる手段があるというのは気持ちいい

 まずはポジティブなところから。やっぱり gem install で簡単にソフトウェアを流通できる環境といいうのは便利でものすごいことだと思う。アイディアを形にしたら発表して、地球の反対側に住んでいる人にも瞬時に使ってもられる。これって控えめに言っても、大変なことだと思います。

シミュレーションが作りたいのかな

 私は大量のデータから、単純な回答を求めるものよりも、シンプルなルールから複雑な結果を生み出すものが好きらしい。シミュレーションを作る場合、シミュレーションを実行するクラスと、GUIを表示する2つのクラスを作成するのがよいようだ。大量にデータを扱う場合は、drubyやApacheArrowなどを挟んで非同期的にするとスピードが早くなるのかもしれない‥けどわからない。大量のデータを検索するようなものが必要になったら sqliteや ActiveRecord みたいなものを勉強していけばよいのかな。

Gemには命名規則がある

 知っている人には当たり前の話なのだろうけれども、単語の区切りは _(アンダーバー)、既存のGemやクラスの拡張は – (ハイフン)でつなぐ。Gemの命名はディレクトリの構造と一致するようにする。

Vimで複数の文章を開いてコピペするのが苦手

 普段はvimで満足している(基本機能しか使いこなせていないけれど)。Jupyterのように一つの100行ぐらいの書捨てのスクリプトを書けば満足なので初心者向けの機能で十分なのだ。しかし、Gemを作る場合には、クラスごとにファイルを作成するから、AのファイルからBのファイルに飛び回る、コピペするといった操作が必要になる。これが私にはできなかった。geditとかを開いてGUIでっている。しかし、本当は勉強すればVimでもできるはずだ。とりあえず画面のスプリット機能を使いはじめてたけれども、慣れるまでかなり時間がかかりそう。

クラスを作成する場合や、メソッドを作成する場合に、自分のいるスコープの外側に何があるか気にする

 書捨てのスクリプトだと、いつでもトップレベルからスタートするので、自分の外側の世界に何があるか、ということを気にしなくてもよかった。トップレベルからrequireしたり、includeしたり、ネストしたクラスを作る場合でも、基本的には内側へ内側へとモジュールが広がっていくので、外側の世界を気を配る必要はなかった。しかしGemを作る場合や、既存のライブラリを拡張する場合は、このメソッドはどこに生やすべきか、そのメソッドがいる場所から外側にはどんな世界が見えるべきか、ということを考える必要がある。

 メソッドがどの場所に生えているか、どのスコープに存在するか、モジュールとモジュールの内包構造をどうするか、という問題について、オブジェクト指向の強いRubyでも、特殊な記法を採用しているように見える。new とか使わないで人間の視覚に訴えかけるように、モジュールやクラスを定義するという感じで。

 あるモジュールから動的に特定の条件のメソッドだけ引っこ抜いて、よそのクラスに打ち込んだり、特異メソッドを互いにやりとしたり、その時々の状況に応じて、クラスの継承関係がダイナミックに逆転したり、といったことはあんまりやらないみたいだ。

 そう考えると、どのクラスがどのクラスを内包するか、メソッドがどこの場所にあるか、という場所をあとから変更するのは用意ではなく、一旦その骨格が決まってしまうと、あるパッケージ・ライブラリの進化の律速‥などという言葉があるのかわからないけれども‥のようなものになりやすくなっていると思われる。思いつきだが、ランダムにスコープやモジュール構成や、メソッドの範囲が変化するようにしておいて、どのような構成の時に最も落ち着くか、焼きなますようにしてシミュレーションしていくと面白いかもしれない。その場合、ユースケース(評価関数)に応じて局所最適解がいくつもあって、そのために同じような機能でも、ライブラリが複数発生するのだとしたらおもしろいと思う。こんどぜひともやってみたいけれども、本当にそんなことできるかな? そういうシミュレーションはAIによるプログラミングにつながっている気がする。GANのように、APIを使うAIと、設計するAIが、相互作用のなかで学習してライブラリを成長させていく。そんな妄想。

 自然界であ、AとBの2つのモノの相互作用の近くに複雑な構造が現れていくというものが多いから、そう考えると、クラスやモジュールの膜の表面に複雑なメソッドがはえていくのも、相互作用の中で表面が複雑化していく自然現象に似ている気がする。クラスやモジュールの内包関係が一旦規定してされてしまうと、なかなか変化せず、持続的な進歩を行うよりも、まっさらな状態から新しく作り直した方が早いケースが多いところも似ている。

 やや話は変わるけれども、普段の生活でも、この場やスペースがどういう場所で、職権がどの範囲まででとか、そういうことを考えなければならないシーンは多い気がする。モジュールの外側の世界を気にし始めたら、実世界でもそういう自分の外側にあるスコープがやけに気になるようになった。

 うーん、考えていたらずいぶんと遠いところにきてしまった。

やっぱりそれ以前にモジュールとか、特異メソッドとか、モジュールのインスタンス変数とか、クラス変数とかよくわかっていない。もちろんlambdaとprocの違いも

 ここのへんはRuby関連の読み物の中ではしょっちゅう出てくるけれども、未だにさっぱりわからない。悲しい。

トップレベルにメソッドを生やしたい場合は、Kernelモジュールを拡張すればいい

 タイトルの通りだけれども、awesome_print のようにトップレベルにメソッドを生やすタイプのライブラリーってどうやって定義しているのだろうかと思って調べて知った。

Gemは $LOAD_PATH にファイルを追加している

 これは gemspec を見れば気がつくことだけれども、今まで見過ごしていた。思ったより簡単な仕組みなんだなと思った。今はたまたまGemという仕組みが普及しているけれども、パッケージの作成、管理、配布を行う別の方法があってもおかしくないと感じた。

 $LOAD_PATHをRubyドキュメントで調べて、Kernel モジュールの中に特殊変数という名前のグローバル変数があることを知った。この特殊変数たち、大事なんだろうけれども、何となく見た目があまりかわいくない感じがするな。あくまでイメージの話だけど。

GUIを作るのは案外むずかしい

 世の中はプロが作った使いやすいGUIがあふれているため、GUIを作るのは簡単だという気がしてしまう。でも、それは思い違いだと思った。上の話と似ているけれども、あとから、この機能がほしい、あの機能がほしいという感じで少しずつGUIを修正して改変していくと、最終的に出来上がったものが微妙になっていく傾向があるみたいだ。

 GUIを考えるときは、一旦頭の中を博しにして、PCの電源を切って、コードのことは忘れて鉛筆と上で図面を書きながら考えることが必要みたい。

 少なくとも既存のGUIを眺めながらこっちの方がいい、あっちの方がいいと逐次的に修正を繰り返すだけではよいGUIを作るには不十分みたいである。GUIビルダーで仕上がりを観察しながら作れば、コードを手打ちするよりも便利なGUIができる、というわけでもないんだなということがわかった。

 市販のソフトで、GUIとデザインに半分以上のお金を払っているんじゃないかと感じることは多い。そういうものを「ギミック」と軽視する向きもあるけれども、やっぱりプロの仕事というものはすごいものだと思う。そういう無形の価値も評価されて、正当な対価が支払われるといいと思う。

今のところRuby/GTKでGIOのリソースやcomposite classを使う意味は薄いかな

 使ったほうが便利な場面も出てくるのかもしれないけれども、私のシンプルな使い方では compsit class を使うメリットはあんまりない感じがした。Windowsだとglib-compileresourcesとか、個別の環境では動かないこともあるし、とりあえず素人が書くぶんには、クラスを継承して、GObjectとRubyのオブジェクトを一致させようとか考えずに、委譲を中心にやっていった方がいいみたい‥というか難しくてそれしかできない。

Ruby以外の言語のことも勉強した方がいい気がした

 Rubyのこともよくわかっていないし、他の言語を勉強する能力も余力もないけれども、やっぱり世界にはたくさんすごい人がいて、その人たちはRubyではなくて、いろいろな言語でソフトを書いている場合が多いので、そういうものを雰囲気だけでも、やっぱり他の言語もちょこっとだけでも触れてみる方が人生が豊かになるんだろうなと思った。時間は有限だけど。