わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

RubyとCのテンプレート

当ブログでちょっとしたコードを公開するため,また授業準備や研究などで疑問に思ったことを検証するため,テキストエディタMeadowを使って,RubyまたはCでこりこり書いています.
だいぶ前から,Rubyスクリプトについてはテンプレートを使用していました.~/.emacsには

;; auto-insert template
(setq auto-insert-directory "~/.emacs.d/template/")
(auto-insert-mode)
(setq auto-insert-query nil) ;; テンプレート挿入時に尋ねない
(setq auto-insert-alist
      (append
       '(
	 ( ruby-mode . "template.rb" )
	 )
       auto-insert-alist))

と書き,~/.emacs.d/template/template.rb は以下の内容です.

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

class AClass
  def initialize
  end

  def start
  end
end

if __FILE__ == $0
  AClass.new.start
end

そして開けば最初に,query-replaceで,AClassをクラス名に置換していました.しかし考えてみると,これは手間です.
Rubyスクリプトにおいて,クラス名の慣例は

ファイル名は、すべて小文字とし、単語の区切りに`-'を用いる。また、ファイル中の主な定義クラスの名前を変換したものをファイル名に使用する。

Rubyコーディング規約

です*1
ということで,たとえばsample.rbというファイルを新規に開けば,Sampleクラスが出てくるよう,変更を試みました.Emacsの設定についてはEmacs の auto-insert 用のテンプレートを作って楽をしよう - higepon blogが分かりやすく,これを自分向けにアレンジしました.
結果.~/.emacsは,こうなりました.

;; auto-insert template
(setq auto-insert-directory "~/.emacs.d/template/")
(auto-insert-mode)
(setq auto-insert-query nil) ;; テンプレート挿入時に尋ねない
(setq auto-insert-alist
      (append
       '(
	 ( ruby-mode . ["template.rb" my-template])
	 ( c-mode . "template.c" )
	 )
       auto-insert-alist))

(defvar template-replacements-alists
  '(("%rbclass%" . (lambda () (capitalize (file-name-sans-extension (file-name-nondirectory (buffer-file-name))))))))

(defun my-template ()
  (time-stamp)
  (mapc #'(lambda(c)
        (progn
          (goto-char (point-min))
          (replace-string (car c) (funcall (cdr c)) nil)))
    template-replacements-alists)
  (goto-char (point-max))
  (message "done."))
(add-hook 'find-file-not-found-hooks 'auto-insert)

ポイントは,「capitalize」です.これを入れることで,sample.rbを新規に開いたら,%rbclass% はSampleになります.動作確認には,Meadowのscratchバッファを使いました.カッコに始まりカッコに終わる行を打ち込んで,C-jで,評価結果が出てきます.

(file-name-sans-extension (file-name-nondirectory "/home/uchinoko/tmp/sample.rb"))
"sample"

(capitalize (file-name-sans-extension (file-name-nondirectory "/home/uchinoko/tmp/sample.rb")))
"Sample"

もう少しだけ脱線.編集中に,単語の先頭文字だけ大文字,あとは小文字にするのは,capitalize-word,キーバインドではM-cというのを知っていました.それで上の式で「(capitalize-word (…))」と書いていて,エラーに悩まされました.
Emacs Lispはここまで.あとはテンプレートファイルの整備です.~/.emacs.d/template/template.rb は以下の通り.

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

class %rbclass%
  def initialize
  end

  def start
  end
end

if __FILE__ == $0
  %rbclass%.new.start
end

あと,Cのプログラムの「#include 」とmainの外形を毎回打ち込むのも面倒だったので,これも簡単なテンプレートを作りました.~/.emacs.d/template/template.c は,こうです.

#include <stdio.h>

int main(void)
{

  return 0;
}

これで快適になりました.
ところで,ファイル名の規約のあとに

foo.rb # クラスFooを定義
foo-bar.rb # クラスFooBarを定義
foo/bar-baz.rb # クラスFoo::BarBazを定義

Rubyコーディング規約

という例も書かれています.2番目の例,すなわち「foo-bar」から「FooBar」への変換は,Emacs Lispのマニュアルをもう少し調べて苦闘すれば,できそうにも思えますが,手間と利便性の兼ね合いから,今後の課題として残しておくこととします.