まずはやってみよう

ひとまずやってみよう

それでは実際に作ってみましょう。

Args:
  クラス名
  クラスの概要
Index: ReptName1.cpp
// --------------------------------------------------------------------------
/**
 * ReptName2、実装
 */

#include "ReptName1.h"

ReptName1::ReptName1()
  : reptName1_(0)
{
}

void ReptName1::method1()
{
}

int ReptName1::method2() const
{
  return 0
}

Index: ReptName1.h
// --------------------------------------------------------------------------
/**
 * ReptName2、ヘッダ
 */

class ReptName1 {
public:
  ReptName1();
  ~ReptName1();

public:
  void method1();
  int method2() const;

private:
  int reptName1_;
};

Index: makefile
-->	ReptName1.cpp \
# @insert srcfiles

これはC++のクラスを一つ自動で作るReptファイルです。このファイルをaddClass.reptという名前で適当な場所に保存して下さい

新規にファイルを作ったりするので、新しく空のディレクトリを掘ってそこに置くのがおすすめ!。

さてもう一作業、このReptファイルはmakefileに自身を追加するので、以下の内容をmakefileという名前でReptファイルと同じ場所に置いて下さい。

  1. #
  2. # makefile
  3. #
  4. SRC_FILES = \
  5. # @insert srcfiles

準備はいいですか?それでは以下のコマンドを打ってみましょう!

% rept addClass.rept Hoge 'ホゲ'
引数  : Hoge, ホゲ
テスト: Hoge.cppは作成可能?
テスト: Hoge.hは作成可能?
テスト: makefileは挿入可能?
実行  : ファイル作成 --> Hoge.cpp
実行  : ファイル作成 --> Hoge.h
実行  : makefileに挿入
実行  :   挿入 "	Hoge.cpp \" --> "# @insert srcfiles"

いくつかのメッセージがだらだらっと出て、

  1. Hoge.hが作られて
  2. Hoge.cppが作られて
  3. makefileにHoge.cppが挿入される

となれば成功です。

ヘルプを見る

所でこのReptファイルで要求されているのはどんなデータ何でしょうか?そんな時は引数無しで実行してみましょう。

% rept addClass.rept
rept addClass.rept クラス名 クラスの概要

これはReptファイルのArgsによって提供されます。Argsの行数が要求している引数の数になり、各行にかかれているのがその引数の説明になります。

変数展開(ReptName)

ReptName1、2とか書かれている部分は、引数で入力された値に置き換わります。 大文字、小文字が違うreptNameとかがありますが、これはアルファベットで入力された時に大文字小文字を自動的に変換するためのものです。

注意 Reptは入力が先頭大文字のキャメルで入力されている、と仮定して大文字小文字変換を行います。

元に戻したい

Hogeって名前は余りにも適当だなあ、と思ってFooって名前にしたいですって? 大丈夫、Reptで作ったものは簡単に元に戻せます

% rept addClass.rept Hoge 'ホゲ' -u
確認  : 本当に元に戻していいですか?(y/n) y
引数  : Hoge, ホゲ
実行  : ファイルを削除 Hoge.cpp
実行  : ファイルを削除 Hoge.h
実行  : makefileから挿入行を削除します
実行  :   挿入削除 "	Hoge.cpp \" <-- "# @insert srcfiles"

これでさっき作ったものは挿入部分も含めて無しになりました!

注意 ただし挿入部分の削除には制約があって、「直前に挿入したものしか元に戻せない」という制約があります。

まとめて作る

同時に10個のクラスを作りたいのにいちいちコマンドを10回打つのは面倒ですって?大丈夫、Reptは複数入力もサポートしています。

% rept addClass.rept Hoge 'ホゲ' Bar 'バー' Foo 'フー'
引数  : Hoge, ホゲ
テスト: Hoge.cppは作成可能?
テスト: Hoge.hは作成可能?
テスト: makefileは挿入可能?
実行  : ファイル作成 --> Hoge.cpp
実行  : ファイル作成 --> Hoge.h
実行  : makefileに挿入
実行  :   挿入 "	Hoge.cpp \" --> "# @insert srcfiles"
引数  : Bar, バー
テスト: Bar.cppは作成可能?
テスト: Bar.hは作成可能?
テスト: makefileは挿入可能?
実行  : ファイル作成 --> Bar.cpp
実行  : ファイル作成 --> Bar.h
実行  : makefileに挿入
実行  :   挿入 "	Bar.cpp \" --> "# @insert srcfiles"
引数  : Foo, フー
テスト: Foo.cppは作成可能?
テスト: Foo.hは作成可能?
テスト: makefileは挿入可能?
実行  : ファイル作成 --> Foo.cpp
実行  : ファイル作成 --> Foo.h
実行  : makefileに挿入
実行  :   挿入 "	Foo.cpp \" --> "# @insert srcfiles"

要求する引数の数の倍数であれば、何個でも(各端末の限界まて)入力を受け取ることが出来ます。 まとめて作った場合はそのままアンドゥをかけるとReptの方で逆順に適用するのでそのまま削除されます。

% rept addClass.rept Hoge 'ホゲ' Bar 'バー' Foo 'フー' -u
確認  : 本当に元に戻していいですか?(y/n) y
引数  : Foo, フー
実行  : ファイルを削除 Foo.cpp
実行  : ファイルを削除 Foo.h
実行  : makefileから挿入行を削除します
実行  :   挿入削除 "	Foo.cpp \" <-- "# @insert srcfiles"
引数  : Bar, バー
実行  : ファイルを削除 Bar.cpp
実行  : ファイルを削除 Bar.h
実行  : makefileから挿入行を削除します
実行  :   挿入削除 "	Bar.cpp \" <-- "# @insert srcfiles"
引数  : Hoge, ホゲ
実行  : ファイルを削除 Hoge.cpp
実行  : ファイルを削除 Hoge.h
実行  : makefileから挿入行を削除します
実行  :   挿入削除 "	Hoge.cpp \" <-- "# @insert srcfiles"

最後にもうちょっと高度な使い方を

基本的な使い方はこんな感じです。ではこの章の最後に少し複雑なサンプルを紹介します。 reptを展開した場所にsample/というフォルダがあると思います。ここには紹介するもの以外にも様々なサンプルを置いていく予定ですので参考にして下さい。 ではsample/advanceを適当な場所にコピーして下さい。

Args:
  追加するクラス
  クラスの説明
Index: Root.h
-->  ReptName1* reptName1_;  // ReptName2
  // @insert member
Index: Root.cpp
-->  reptName1_ = new ReptName1();
  // @insert constructor

  // @insert destructor
-->  delete reptName1_;
Index: makefile
-->	reptname1 \
# @insert srcdirs
Index: reptname1/ReptName1.h
// --------------------------------------------------------------------------
/**
 * ReptName2
 */

class ReptName1 {
public:
  ReptName1();
  ~ReptName1() {}
};

Index: reptname1/ReptName1.cpp
// --------------------------------------------------------------------------
/**
 * ReptName2
 */

#include "ReptName1.h"

// --------------------------------------------------------------------------
/**
 * コンストラクタ
 */
ReptName1::ReptName1()
{
}

Index: reptname1/makefile
# 
# makefile
# 

SRC_FILES = \
	ReptName1.cpp \
# @insert srcfiles

SRC_DIRS = \
# @insert srcdirs
% rept advance.rept Foo 'フー'
引数  : Foo, フー
テスト: Root.hは挿入可能?
テスト: Root.cppは挿入可能?
テスト: makefileは挿入可能?
テスト: foo/Foo.hは作成可能?
テスト: foo/Foo.cppは作成可能?
テスト: foo/makefileは作成可能?
実行  : Root.hに挿入
実行  :   挿入 "  Foo* foo_;  // フー" --> "  // @insert member"
実行  : Root.cppに挿入
実行  :   挿入 "  foo_ = new Foo();" --> "  // @insert constructor"
実行  :   挿入 "  delete foo_;" --> "  // @insert destructor"
実行  : makefileに挿入
実行  :   挿入 "	foo \" --> "# @insert srcdirs"
実行  : ディレクトリ作成 --> foo
実行  : ファイル作成 --> foo/Foo.h
実行  : ファイル作成 --> foo/Foo.cpp
実行  : ファイル作成 --> foo/makefile

このreptファイルは以下のようなことを行います。

  1. 新しいクラスを定義し(置き場所はサブフォルダを自動に掘ります)
  2. Rootクラスの持ち物として新しいクラスを追加し
  3. オブジェクトの生成と削除コードをRootクラスのコンストラクタ、デストラクタに追加します

ディレクトリの自動作成、一つのファイルに対して複数箇所の挿入、逆方向への挿入等、Reptで出来ることの幅をイメージしてもらえればと思います。