スキップしてメイン コンテンツに移動

投稿

2月, 2017の投稿を表示しています

仕事で使わない Perl コーディングテクニック

Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it? -- Brian Kernighan (まずもって、デバッグがプログラミングの倍も難しいことは衆知である。だからもしあなたが能う限りの知力でコードを書いたとしたら、どうやってデバッグするのか?) 言語のマイナ機能とか関数のデフォルトの挙動なんかを駆使してプログラムを書くと未来の自分や同僚が困るので、普段はいくらか制限して書くと思う。 僕は Perl 5 だとライブラリはともかくアプリケーションのコードは「続・初めてのPerl (Intermediate Perl)」程度の知識を前提して書いていた。 要するに意図的に低俗なコードを書いているわけで面白くない。 だいたい頭の内にあるボンヤリとした「Perl 的な書き方」が実際に動くのがこの言語の良いところで、昔2ちゃんねるで見かけた「キモいが矛盾していない、それが Perl」というコメントはけだし慧眼だったと思う。 そんなわけでマイナであったり環境の都合で自制していた言語機能をいくつか紹介したい。 メソッドの事前解決 Perl 5 のメソッド呼出しは遅い。まずもってメソッドの解決が遅い。繰り返し同じメソッドを呼ぶときはメソッドを一度だけ解決してそれを直接呼び出したい。要するに Objective-C で selector を取得してそれを実行するようなことをやりたい。 名前のせいで述語と勘違いしがちだが UNIVERSAL::can はまさにこのメソッド解決を行う。例えば my $do_foo = $obj->can('do_foo'); とすれば $obj が属するパッケージないしその親クラスに存在する do_foo メソッドへのリファレンスが得られる。存在しない場合は undef である。 そうとなれば後は簡単で、メソッドは第一引数にインスタンスないしクラス名を受けるただのサブルーチンなので、 $do_foo->($obj, ...)

MacPorts の GHC が macOS Sierra でビルドできない件の回避策 (i.e. MacPorts のパッチの当て方)

多分じきに修正されて腐る内容だが、MacPorts の port にパッチする方法としてまとめておく。 会社を辞めたので久方ぶりにブログを書こうと思い、pandoc をインストールしようとしたところ GHC のビルドがコケた。 ログをみると GetTime.c というファイルのコンパイルに失敗している。MacPorts の Trac を検索してみると果たして 既知の問題 だった。「Haskell 処理系とそれに依存する全パッケージがインストールできない」問題が四ヶ月前に報告されていまだに直っていないという大らかさ。 幸いチケット内に パッチ が提案されていたのでこれを適用してことなきを得た。 まずローカルに GHC の port をコピーし、MacPorts の ports tree として登録する: $ sudo -i Password: # mkdir -p /usr/local/ports/lang/ && cd /usr/local/ports/lang/ # cp -r $(port dir ghc) ./ # cd ghc && port lint # cp /opt/local/etc/macports/sources.conf{,.orig} # vi /opt/local/etc/macports/sources.conf # 作成したディレクトリをデフォルトの ports tree の前に追記する # diff -u /opt/local/etc/macports/sources.conf{.orig,} --- /opt/local/etc/macports/sources.conf.orig 2017-02-10 14:10:00.000000000 +0900 +++ /opt/local/etc/macports/sources.conf 2017-02-10 14:11:04.000000000 +0900 @@ -29,4 +29,5 @@ # sites, etc.), the primary MacPorts source must always be tagged # "[default]", even if switched from the def