« プログラミングを始めるには(13) | Main | プログラミングを始めるには(15) »

August 09, 2014

プログラミングを始めるには(14)

以前の記事で「手っ取り早くプログラミングを始めるには普段使用しているPCにMeadowをインストールすることである」というようなことを書いた。これは普通の人が使用しているPCのほとんどがWindows PCであろうと想定してのことであって、プログラミングをする環境としてはやはりUNIXの方が優れている。

Windowsの前身?であるMS-DOSもバージョン2.0までは、これをプログラミング環境と呼んでよいかどうかは分からないが、MASM(マクロアセンブラ)が標準で入っており、ファイル管理はUNIXにかなり似ていた。Windowsのコマンドプロンプトが馴染む人ならUNIXにあまり違和感は無いはず。しかもUNIXのシェルはコマンドプロンプトのコマンドインタプリタよりも格段に便利で使いやすい。

UNIXといっても、今はほとんどの人にとってUNIX=Linuxであろうと思われる。純粹にUNIXというとfreeBSDはそれに當たるのかもしれない。しかし、freeBSDをたとえば最近のCentOS7やUbuntu14あたりの操作性までもっていくのはかなり骨が折れる作業だ。なにしろインストール直後は端末ログインであり、X11の環境設定をちゃんとしてやらないとデスクトップ環境として使えないというシロモノだからだ。私も最近freeBSD10に挑戰してみたが、端末ログインしたあとにstartxして、X11の畫面まで立ち上がるようにしたところでギブアップした。こういうのを整備していくのが好きな、根っからのシステム管理者指向の人には良いのかもしれないが、それをやっているだけで疲れてしまって、本來の目的であるプログラミングをする以前に挫折してしまう。

それに比べると、最新版のUbuntu(Debian Linuxの派生ディストリビューション)、CentOS(RedHat Enterprise Linuxのクローン)、Fedora(RedHat Enterprise Linuxの實驗版)の3つはインストールも非常に分かりやすいし、VMware Playerのような假想マシンで動かしてもWindows環境とほとんど變わらないくらいの域に達していると思われる。なので、この文章はFedora上のEmacsで書いている。いよいよWindowsのお尻に火が付くのかもしれない。Windows8のような評判の惡いものをリリースしている場合ではないし、CALで使用端末數分さらに金を取るなんてことをやっている場合ではないのだ。

で、私の場合、Linux上で文章を書けるようにするには、むかしEgg+Wnnからの入力で癖になった「ラ行L打ち」の設定をしなければならないのであるが...WindowsのMS-IMEだと簡單に出來るのに、Linuxだと簡單ではないし、同じIBUSでもディストリビューションによってAnthyだったりkkcだったりして、結構鬱陶しいのだ。一應設定變更は出來たが、日本語入力中に英字を打とうとするとF10の半角變換でもうまくいかない。少なくとも先頭が英大文字だったら自動的に直接入力になって慾しいものだが、これは贅澤というものだろうか?

ちなみに、ローマ字設定を變えたい人は/usr/share配下にある日本語入力エンジンのディレクトリをくまなく探して、自分でハッキングしてください。こんなもの、ディストリビューションのバージョンが變わると設定ファイルも變わるようなので、ここに書いておいても無駄だと思うし、書かれている通りにやったら壞れたというアホな人も居そうなので割愛する(笑)

さて、餘談が長くなり過ぎた。UNIX上でEmacsを使えば、UNIX上のコマンドや他のスクリプトで書いたプログラムの出力を取り込んで處理するということが容易になる。

たとえば、Emacs Lisp Introというドキュメントではファイル中の文字數、語句數、行數を表示するプログラムをelispで書くための說明が書かれているが、それをすべてelispで書くのではなく、數え上げの部分はUNIX上のwcコマンドに任せて、その結果を處理するように書けば手閒が省けるわけだ。

Screenshot_from_20140809_182921


(require 'cl)

(defun my-wc-command (dir)
  (interactive "DDirectory: ")
  (let ((default-directory dir))
    (with-temp-buffer
      (shell-command "wc *" t)
      (let ((line-list (mapcar
			(function
			 (lambda (line)
			   (delete "" (split-string line "[ 	]+"))))
			(split-string (buffer-substring-no-properties
				       (point-min)
				       (1- (point-max)))
				      "\n")))
	    (buffer (generate-new-buffer "*WC COMMAND*")))
	(save-excursion
	  (set-buffer buffer)
	  (dolist (line line-list)
	    (insert (nth 3 line) ","
		    (nth 0 line) ","
		    (nth 1 line) ","
		    (nth 2 line) "\n")))
	(pop-to-buffer buffer)))))

非常に安直に作るとこうなる。shell-commandの出力をいじっているのは、ファイル名を左端に表示するためである。これではあまりにも安直過ぎて、指定したディレクトリにさらにディレクトリがあると結果出力のバッファに文字列をinsertしているところでランタイムエラーになる。wcコマンドが「それはディレクトリです」というエラーを出すため、期待している出力にならないからだ。

それならばということで、さらに安直にwcコマンドのエラー出力をNULLリダイレクトするとどうなるか、と考えた。するとOKになるようである。今この文章を書いているディレクトリで實行するとOKでも、別の、たとえばホームディレクトリとかで實行すると樣子が變わってくる。そのためwcコマンドが處理すべきなのは「*」だけでなく「.*」も必要なのだと分かった。

(require 'cl)

(defun my-wc-command (dir)
  (interactive "DDirectory: ")
  (let ((default-directory dir))
    (with-temp-buffer
      (shell-command "wc .* * 2>/dev/null" t)
      (let ((line-list (mapcar
			(function
			 (lambda (line)
			   (delete "" (split-string line "[ 	]+"))))
			(split-string (buffer-substring-no-properties
				       (point-min)
				       (1- (point-max)))
				      "\n")))
	    (buffer (generate-new-buffer "*WC COMMAND*")))
	(save-excursion
	  (set-buffer buffer)
	  (dolist (line line-list)
	    (insert (nth 3 line) ","
		    (nth 0 line) ","
		    (nth 1 line) ","
		    (nth 2 line) "\n")))
	(pop-to-buffer buffer)))))

修正版はこれ。ほとんど何も變わっていなくて、wcコマンドに渡すパラメータに「.*」を加えて、標準エラー出力をNULLリダイレクトしただけである。つまりUNIXコマンドをどう打つかによって、それを受け取るプログラムが大きく變わるわけだ。

(defun my-wc-command (dir)
  (interactive "DDirectory: ")
  (let ((default-directory dir)
	(buffer (generate-new-buffer "*WC COMMAND*")))
    (save-excursion
      (shell-command (concat "wc .* * 2>/dev/null | "
			     "awk '{OFS=\",\";print $4,$1,$2,$3}'") buffer)
      (pop-to-buffer buffer))))

出來るだけUNIXコマンド側に處理をさせるとこうなる。これだと別にシェルから實行すれば良くて、何のためにelispで書くのか分からなくなる。まあ、これは例が惡いのだろう。

|

« プログラミングを始めるには(13) | Main | プログラミングを始めるには(15) »

Comments

Post a comment



(Not displayed with comment.)


Comments are moderated, and will not appear on this weblog until the author has approved them.



TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/74224/60122116

Listed below are links to weblogs that reference プログラミングを始めるには(14):

« プログラミングを始めるには(13) | Main | プログラミングを始めるには(15) »