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ではなくて、いろいろな言語でソフトを書いている場合が多いので、そういうものを雰囲気だけでも、やっぱり他の言語もちょこっとだけでも触れてみる方が人生が豊かになるんだろうなと思った。時間は有限だけど。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です