2023年9月7日木曜日

つれづれ思うこと Perl 編 その1

あまり堅苦しい論文の話ばかりを書いていても一向にブログが進まないので、もうちょっと気軽な内容も書くことにしました。

蛋白質の立体構造の計算でいつも困るのは、Protein-Data-Bank の昔のフォーマットが統一されていないこと。例えばアミド水素など、あるソフトウェアでは 'H' と書かれていないといけないのに(おそらくこれが正式)、別のソフトでは 'HN' と書かれていないと動かない。その他にも CH2 の β1, β2, β3 の割り当てなど、泣きたくなるような不一致がいくつもある。これを修正するのは一苦労で某友人もイライラが募るとのこと。なお、今後は mmCIF と呼ばれるフォーマットに統一されていくので、このような問題はなくなるようです。

そういう時にファイル変換のためのプログラムが役立つわけであるが、どの言語を使おうか?Python, Perl, Ruby, JavaScript どれでもよいのであるが、そもそもプログラミングが本職ではないので、できるだけ手っ取り早く、さっさとファイル変換を済ませたい。すると、どうしても過去に自分で作ったプログラムを少しだけ修正して目前の問題に間に合わせることになる。これが 30 年間も続くと、ずっとその言語一色という状況が起きてしまう。

それで私は Perl 一色だったのであるが、最近はウェブで「Perl 将来性」などと引くと、「オワコン = 終わったコンテンツ」などと嘆かわしいページばかりが目につくようになった。それとは対照的に Python はまだまだ鰻上りである。というわけで、数年前からちょっとでも慣れようと思い "無理して" Python で書くようにした。Perl も Python もどちらも似たものだろうと舐めてかかったのであるが、なんと Perl の何十倍も作るのに時間がかかってしまった。

何故か?決定的だったのは括弧の有無である。例えば Perl の場合

if ($abc == 0)
{
     $def = 3;
}

のように {  } を使うが、Python では使わずに行を右へずらす(インデント)。ちなみに、私は癖で

if ($abc == 3) {
    $def = 3;
}

のようには書かない。その理由は、{ と } がエディター上で縦に揃っていると、if 文の及ぶ範囲が一目で分かるためである。しかし、Python では括弧がないので、vi で Python プログラムを編集した時、if 文の階段が5段ぐらい入れ子になり、そこでインデントを間違えた瞬間に崩壊してしまった。間違えた!と気づいても、どこをどう修正してよいのか分からなくなるのである。他人の Python プログラムを破壊するのは簡単である。エディター上でスペースキーをちょこっと押してやると、もう動かなくなり、修正にたいへん時間がかかる。

一応、vscode などの高機能エディターを使うと、縦の補助線が出るので少しは助かる。しかし、昔の人はこのような補助線なしにどうやって Python プログラムを書いていたのだろう?

Perl にも面白いところがあって、例えば "123" などを数値とみてもよいし、文字列と見てもよい。計算の中でその変数を使うと(例えば、1 を足すなど)自動的に数値として解釈してくれる。しかし、Python ではそうではないので、ちゃんと(昔習った C 言語のように)数値と文字列の違いをきっちりと区別し、ある時にはいずれかへの変換をちゃんと書いてあげないといけない。「そんな事は当たり前だろう」と言われそうであるが、30 年間も Perl 温泉に浸かってしまうと、なんて Python は不便なんだと悪口を吐いてしまう。。。

あまり Perl ばかりを褒めていてもよくないので、Python を使い始めて「これは良い」と思った点も書こう。それは、Perl では変数はデフォルトで大局変数(グローバル)になっているのに対して、Python ではデフォルトで局所変数(ローカル)になっている点である。大局変数の方が書きやすいのであるが、時に変数名が重複してしまい、知らない間に保存してあった変数の値が変わってしまうこともあり得る。そのため、Perl では、これはローカル変数にしたいと思った時に変数の前に my を付ける。一方、Python では考え方が真逆であるので、普通に変数を設ければ、それは自動的に局所変数となる。よって、安心してプログラムを書ける。しかし、これも 30 年間グローバル変数に慣れてしまうと、Python で書いた時に「なんて窮屈なんだ。この何十個もある変数をどうやって子供のサブルーチン関数に渡したらよいのか?まさか全部を引数で?」と悩んでしまう(もちろん、オブジェクトにすればよいのだけれど)。

これを書いていて、今もう一つ Python で良かった点を思い出した。それは、引数にデフォルト値を設定できることである。これは便利。もしかして Perl にもちゃんと備わっていて、私が知らないだけなのだろうか?

0 件のコメント: