hikiutils 0.2.3.13 → 0.2.3.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/hikiutils.gemspec +2 -1
  3. data/hikiutils_bob/Rakefile +30 -16
  4. data/hikiutils_bob/code.hiki +9 -30
  5. data/hikiutils_bob/figs/hikiutils_bob.002.jpeg +0 -0
  6. data/hikiutils_bob/figs/hikiutils_bob.007.jpeg +0 -0
  7. data/hikiutils_bob/figs/hikiutils_bob.pdf +0 -0
  8. data/hikiutils_bob/hikiutils_bob/hikiutils_bob.002.jpeg +0 -0
  9. data/hikiutils_bob/hikiutils_bob/hikiutils_bob.007.jpeg +0 -0
  10. data/hikiutils_bob/hikiutils_bob.key +0 -0
  11. data/hikiutils_bob/latex_all.hiki +33 -8
  12. data/hikiutils_bob/latex_dir/code.aux +7 -14
  13. data/hikiutils_bob/latex_dir/code.log +28 -0
  14. data/hikiutils_bob/latex_dir/code.tex +13 -31
  15. data/hikiutils_bob/latex_dir/hikiutils_bob.log +59 -50
  16. data/hikiutils_bob/latex_dir/hikiutils_bob.pdf +0 -0
  17. data/hikiutils_bob/latex_dir/hikiutils_bob.synctex.gz +0 -0
  18. data/hikiutils_bob/latex_dir/hikiutils_bob.toc +29 -29
  19. data/hikiutils_bob/latex_dir/latex_all.aux +19 -16
  20. data/hikiutils_bob/latex_dir/latex_all.log +28 -0
  21. data/hikiutils_bob/latex_dir/latex_all.tex +34 -9
  22. data/hikiutils_bob/latex_dir/sync.aux +16 -16
  23. data/hikiutils_bob/latex_dir/sync.tex +4 -4
  24. data/hikiutils_yamane/Rakefile +14 -2
  25. data/hikiutils_yamane/abstract.hiki +3 -3
  26. data/hikiutils_yamane/discussion.hiki +9 -0
  27. data/hikiutils_yamane/hikiutils_yamane.hiki +8 -10
  28. data/hikiutils_yamane/introduction.hiki +1 -1
  29. data/hikiutils_yamane/latex_dir/abstract.tex +3 -3
  30. data/hikiutils_yamane/latex_dir/{%CA%FD/313/241.aux → discussion.aux} +8 -7
  31. data/hikiutils_yamane/latex_dir/discussion.tex +9 -0
  32. data/hikiutils_yamane/latex_dir/hikiutils_yamane.aux +3 -6
  33. data/hikiutils_yamane/latex_dir/hikiutils_yamane.log +50 -59
  34. data/hikiutils_yamane/latex_dir/hikiutils_yamane.pdf +0 -0
  35. data/hikiutils_yamane/latex_dir/hikiutils_yamane.synctex.gz +0 -0
  36. data/hikiutils_yamane/latex_dir/hikiutils_yamane.tex +4 -7
  37. data/hikiutils_yamane/latex_dir/hikiutils_yamane.toc +21 -21
  38. data/hikiutils_yamane/latex_dir/introduction.tex +1 -1
  39. data/hikiutils_yamane/latex_dir/method.aux +46 -0
  40. data/hikiutils_yamane/latex_dir/method.tex +247 -0
  41. data/hikiutils_yamane/latex_dir/results.aux +49 -0
  42. data/hikiutils_yamane/latex_dir/results.tex +249 -0
  43. data/hikiutils_yamane/method.hiki +234 -0
  44. data/hikiutils_yamane/results.hiki +225 -0
  45. data/hikiutils_yamane/toc.hiki +0 -1
  46. data/lib/hikiutils/version.rb +1 -1
  47. data/lib/hikiutils_thor.rb~ +37 -37
  48. data/lib/templates/Rakefile_hiki_sync +32 -17
  49. data/lib/templates/mi_key_bind_setting +1 -0
  50. metadata +33 -19
  51. data/hikiutils_yamane/Rakefile~ +0 -477
  52. data/hikiutils_yamane/command.hiki +0 -111
  53. data/hikiutils_yamane/compare.hiki +0 -116
  54. data/hikiutils_yamane/latex_dir/command.aux +0 -35
  55. data/hikiutils_yamane/latex_dir/command.log +0 -0
  56. data/hikiutils_yamane/latex_dir/command.tex +0 -123
  57. data/hikiutils_yamane/latex_dir/compare.aux +0 -30
  58. data/hikiutils_yamane/latex_dir/compare.tex +0 -123
  59. data/hikiutils_yamane/latex_dir/optparse.aux +0 -31
  60. data/hikiutils_yamane/latex_dir/optparse.tex +0 -119
  61. data/hikiutils_yamane/latex_dir/thor.aux +0 -32
  62. data/hikiutils_yamane/latex_dir/thor.tex +0 -110
  63. data/hikiutils_yamane/optparse.hiki +0 -114
  64. data/hikiutils_yamane/thor.hiki +0 -107
@@ -0,0 +1,249 @@
1
+
2
+ \section{結果}
3
+ \subsection{コマンドの命名原則}
4
+ 機能ごとの動作はコマンドのオプションによって指定されます.
5
+ このオプションにどのような名前をつけるかは,どれだけコマンドを覚えやすいかという
6
+ 意味で重要です.コマンドの振る舞いを的確に表す名称をつける必要があります.
7
+
8
+ この振る舞いとしてもっとも受け入れやすいのがshellで用意されているコマンドです.
9
+ pwd, ls, rm, touch, openなどはもっとも直感的に動作がわかるコマンドです.
10
+ hikiutilsの振る舞いを予測できるシェルコマンドと同じ名前でオプションを提供する
11
+ ようにします.
12
+
13
+ \subsubsection{hikiutilsの想定利用形態}
14
+ ここでhikiutilsがあらかじめ想定している利用形態を解説しておきます.
15
+
16
+ \begin{figure}[htbp]\begin{center}
17
+ \includegraphics[width=10cm,bb= 0 0 737 553]{../figs/./hikiutils_yamane.002.jpg}
18
+ \caption{hikiutilsがあらかじめ想定している利用形態.}
19
+ \label{fig:002}
20
+ \label{default}\end{center}\end{figure}
21
+ hikiutilsは,
22
+
23
+ \begin{itemize}
24
+ \item local PCとglobal serverとが用意されており,
25
+ \item それらのデータをrsyncで同期する
26
+ \end{itemize}
27
+ ことで動作することを想定しています.これは,ネットに繋がっていないオフラインの状況でも
28
+ テキストなどの編集が可能で,さらに不用意な書き換えを防ぐための機構です.さらに,
29
+ どちらもが何かあった時のバックアップともなって,ミスによる手戻りを防いでいます.
30
+
31
+ これらの設定は,~/.hikircにyaml形式で記述・保存されています.
32
+ \begin{lstlisting}[style=,basicstyle={\scriptsize\ttfamily}]
33
+ bob% cat ~/.hikirc
34
+ :srcs:
35
+ - :nick_name: new_ist
36
+ :local_dir: "/Users/bob/Sites/new_ist_data/ist_data"
37
+ :local_uri: http://localhost/ist
38
+ :global_dir: nishitani@ist.ksc.kwansei.ac.jp:/home/nishitani/new_ist_data/ist_data
39
+ :global_uri: http://ist.ksc.kwansei.ac.jp/~nishitani/
40
+ - :nick_name: dmz0
41
+ :local_dir: "/Users/bob/Sites/nishitani0/Internal/data"
42
+ :local_uri: http://localhost/~bob/nishitani0/Internal
43
+ :global_dir: bob@dmz0:/Users/bob/Sites/nishitani0/Internal/data
44
+ :global_uri: http://nishitani0.kwansei.ac.jp/~bob/nishitani0/Internal
45
+ \end{lstlisting}
46
+ また,一般的に一人のユーザがいくつものまとまりとしてのlocal-globalペアを
47
+ 保持して管理することが普通です.それぞれにnicke\_nameをつけて管理しています.
48
+ \begin{lstlisting}[style=,basicstyle={\scriptsize\ttfamily}]
49
+ bob% hiki -s
50
+ hikiutils: provide utilities for helping hiki editing.
51
+ "open -a mi"
52
+ target_no:1
53
+ editor_command:open -a mi
54
+ id | name | local directory | global uri
55
+ -----------------------------------------------------------------------------
56
+ 0 | new_ist | /Users/bob/Sites/new_ist_data/ist_data | http://ist.ksc.k
57
+ *1 | dmz0 | /Users/bob/Sites/nishitani0/Internal/data | http://nishitani
58
+ 2 | ist | /Users/bob/Sites/hiki-data/data | http://ist.ksc.k
59
+ 3 | new_maple | /Users/bob/Sites/new_ist_data/maple_hiki_d| http://ist.ksc.k
60
+ \end{lstlisting}
61
+ とすると,それらの一覧と,いまtargetにしているnick\_nameディレクリが表示されます.
62
+
63
+ \subsubsection{コメンド名と振る舞いの詳細}
64
+ 検討の結果コマンドを以下の表\ref{table:ShellOption}のとおり書き換えることとします.
65
+ 上部に記した,特によく使うコマンドに関しては,shellでよく使われるコマンド名と一致するにようにしました.
66
+
67
+ \begin{table}[htbp]\begin{center}
68
+ \caption{コマンドオプションとshellコマンドの対応.}
69
+ \label{table:ShellOption}
70
+ \begin{tabular}{llll}
71
+ \hline
72
+ 変更前 &変更後 &動作の解説 \\ \hline
73
+ edit FILE &open &open file \\
74
+ list [FILE] &ls &list files \\
75
+ rsync &rsync &rsync files \\
76
+ update FILE &touch &update file \\
77
+ show &pwd &show nick\_names \\
78
+ target VAL &cd &targetを変える,cdとのメタファ \\
79
+ & \\
80
+ move [FILE] &mv &move file \\
81
+ remove [FILE] &rm &remove files \\
82
+ add & &add sources info \\
83
+ checkdb & &check database file \\
84
+ datebase FILE &db &read datebase file \\
85
+ display FILE &show &display converted hikifile \\
86
+ euc FILE & &translate file to euc \\
87
+ help [COMMAND] &-h &Describe available commands \\
88
+ version &-v &show program version \\
89
+ \hline
90
+ \end{tabular}
91
+ \label{default}
92
+ \end{center}\end{table}
93
+ %for inserting separate lines, use \hline, \cline{2-3} etc.
94
+
95
+ それぞれの意図を動作の解説として記述しています.
96
+
97
+ \paragraph{open FILE}
98
+ ファイルを編集のためにeditorでopen.Editorは~/.hikircに
99
+ \begin{quote}\begin{verbatim}
100
+ :editor_command: open -a mi
101
+ \end{verbatim}\end{quote}
102
+ として保存されている.open -a miをemacsなどに適宜変更して使用.
103
+
104
+ \paragraph{ls [FILE]}
105
+ local\_dirにあるファイル名を[FILE*]として表示.例えば,hikiutils\_yamane以下の拡張子が
106
+ ついたファイルを表示.hikiシステムではtextディレクトリーは階層構造を取ることができない.
107
+ 西谷研ではdirectoryの代わりにスネーク表記で階層構造を表している.
108
+
109
+ \paragraph{rsync}
110
+ local\_dirの内容をglobal\_dirにrsyncする.逆方向は同期に誤差が生じたり,permissionが
111
+ おかしくなるので,現在のところ一方向の同期のみとしている.したがって,作業手順としては
112
+ テキストの変更はlocal\_dirで読み行うようにしている.
113
+
114
+ \paragraph{touch FILE}
115
+ loccal\_dirで書き換えたFILEの内容をlocal\_uriに反映させ,ブラウザで表示.シェルコマンドの
116
+ touchによって,変更時間を現在に変え,最新状態とするのに似せてコマンド名をtouchとしている.
117
+
118
+ \paragraph{pwd}
119
+ nick\_nameの一覧とtargetを表示,current targetをcurrent dirとみなして,
120
+ コマンド名をpwdとした.
121
+
122
+ \paragraph{cd VAL}
123
+ targetを変える,change directoryとのメタファ.ただし,いまのところnick\_nameでは
124
+ 対応しておらず,nick\_nameの番号をVAL入力することで変更する.
125
+
126
+ \subsection{Thorによる実装}
127
+ 手法のところで概観した通り,Thorを用いることで記述の簡略化が期待できる.ここでは,実際に書き換える前後,すなわちoptparse版とThor版の対応するコードを比較することで,以下の具体的な違い
128
+
129
+ \begin{itemize}
130
+ \item クラス初期化
131
+ \item コマンド定義
132
+ \item CLIの実行プロセス
133
+ \end{itemize}
134
+ について詳しく検討を行う.
135
+
136
+ \subsubsection{クラス初期化}
137
+ \begin{figure}[htbp]\begin{center}
138
+ \includegraphics[width=10cm,bb= 0 0 737 553]{../figs/./hikiutils_yamane.003.jpg}
139
+ \caption{Thorのinitializeでのコード}
140
+ \label{default}\end{center}\end{figure}
141
+ Thorのinitializeでのコードはつぎの通りである.
142
+
143
+ \begin{enumerate}
144
+ \item Hikithor::CLI.start(ARGV)が呼ばれる
145
+ \item initializeメソッドが呼ばれる
146
+ \item これではThorのinitializeメソッドが呼ばれない
147
+ \item superを書くことでThorのinitializeメソッドが呼ばれる
148
+ \end{enumerate}
149
+ optparseではrequireでoptparseを呼びoptparseのinitializeを定義する必要はないが,Thorはinitializeを定義する必要がある.Thorの定義方法はrequireでThorを呼びCLIクラスで継承し,initializeメソッドにsuperを書くことでThorのinitializeが呼ばれる.initializeメソッド内ではThorの初期設定がされていないため,スーパークラスのメソッドを読み出してくれるsuperを書き加えることで図のようにinitializeメソッド内でThorのinitilalizeメソッドが呼ばれ定義される.
150
+ \begin{lstlisting}[style=customRuby,basicstyle={\scriptsize\ttfamily}]
151
+
152
+ module Hikithor
153
+
154
+ DATA_FILE=File.join(ENV['HOME'],'.hikirc')
155
+ attr_accessor :src, :target, :editor_command, :browser, :data_name, :l_dir
156
+
157
+ class CLI < Thor
158
+ def initialize(*args)
159
+ super
160
+ @data_name=['nick_name','local_dir','local_uri','global_dir','global_uri']
161
+ data_path = File.join(ENV['HOME'], '.hikirc')
162
+ DataFiles.prepare(data_path)
163
+
164
+ ...以下略...
165
+ end
166
+ \end{lstlisting}
167
+ \subsubsection{コマンド定義}
168
+ Thorではoptparseのような登録処理はない.図\ref{fig:004}にある通りにコマンドが記述される.
169
+
170
+ \begin{figure}[htbp]\begin{center}
171
+ \includegraphics[width=10cm,bb= 0 0 737 553]{../figs/./hikiutils_yamane.004.jpg}
172
+ \caption{Thorにおけるコマンド記述のひな形.}
173
+ \label{fig:004}
174
+ \label{default}\end{center}\end{figure}
175
+ それらは以下のように構成される.
176
+
177
+ \begin{enumerate}
178
+ \item desc以降にコマンド名と,その説明が記述される.これらはコマンドhelpで一覧として表示させる
179
+ \item mapによって別のコマンド名でも実行できるように定義される.
180
+ \item defで定義されたメソッドの実行コード
181
+ \end{enumerate}
182
+ Thorではdescで一覧を表示されるコマンド名,コマンドの説明を登録する.しかし,ここで記述したコマンドは単に一覧で表示させるためのものであり,実際に実行される時に呼び出すコマンド名は,defで定義された名前である.Thorでは処理実行を行うメソッド名がコマンド名となり,コマンド名1つが対応する.
183
+
184
+ これに別名を与えるために利用されるキーワードがmapである.
185
+ \begin{quote}\begin{verbatim}
186
+ map A => B
187
+ \end{verbatim}\end{quote}
188
+ mapとはBと呼ばれるメソッドをAでも呼べるようにしてくれるものである.
189
+ よって,これを使うことでコマンドの別名を指定することができる.
190
+ \begin{lstlisting}[style=customRuby,basicstyle={\scriptsize\ttfamily}]
191
+ desc 'show,--show', 'show sources'
192
+ map "--show" => "show"
193
+ def show
194
+ printf("target_no:%i\n",@src[:target])
195
+ printf("editor_command:%s\n",@src[:editor_command])
196
+ ,,,以下略...
197
+ end
198
+ \end{lstlisting}
199
+ 以上より,Thorではコマンドの指定と処理にはdesc,map,処理メソッドだけで済む.optparseではコマンドを登録するためのメソッドと処理メソッドの両方が必要になっていた.一方Thorでは,処理メソッドが直接コマンド名となるため記述が簡潔になる.
200
+
201
+ \subsubsection{CLIの実行プロセス}
202
+ CLIの実行プロセスは図\ref{fig:006}の通りである.
203
+
204
+ \begin{figure}[htbp]\begin{center}
205
+ \includegraphics[width=10cm,bb= 0 0 737 553]{../figs/./hikiutils_yamane.006.jpg}
206
+ \caption{CLIの実行プロセス.}
207
+ \label{fig:006}
208
+ \label{default}\end{center}\end{figure}
209
+ Thorにおけるcliの実行プロセスは次の通りである.
210
+
211
+ \begin{enumerate}
212
+ \item hiki\_thorのHikithor::CLI.start(ARGV)でhikiutils\_thor.rbのCLIクラスを呼ぶ
213
+ \item hikiutils\_thor.rbのCLIクラスのメソッドを順に実行していく
214
+ \end{enumerate}
215
+ Thorではstart(ARGV)を呼び出すことでCLIを開始する.Hikithor::CLI.start(ARGV)を実行されることによりrequireで呼ばれているhikiutils\_thor.rbのCLIコマンドを順に実行する.そして,入力されたコマンドと一致するメソッドを探し,そのコマンドの処理が実行される.
216
+
217
+ exe/hiki\_thorの具体的な記述は次の通りである.
218
+ \begin{lstlisting}[style=customRuby,basicstyle={\scriptsize\ttfamily}]
219
+ #!/usr/bin/env ruby
220
+
221
+ require "hikiutils_thor"
222
+
223
+ Hikithor::CLI.start(ARGV)
224
+ \end{lstlisting}
225
+ hikiutilsのoptparseバージョンと同様に「require "hikituils\_thor"」ではlib/hikiutils\_thor.rbを読み出してくることを期待している.
226
+ ここでもgemspecファイルでlibへのロードパスの記述がされているため,hikiutils\_thor.rbを参照することができる.
227
+ 「Hikithor::CLI.start(ARGV)」ではlib/hikiutils\_thor.rbのHikithorモジュールCommandクラスを実行する記述が成されている.
228
+
229
+ 呼び出される側のlib/hikiutils\_thor.rbの具体的な記述は次の通りである.
230
+ \begin{lstlisting}[style=customRuby,basicstyle={\scriptsize\ttfamily}]
231
+
232
+ module Hikithor
233
+
234
+ DATA_FILE=File.join(ENV['HOME'],'.hikirc')
235
+ attr_accessor :src, :target, :editor_command, :browser, :data_name, :l_dir
236
+
237
+ class CLI < Thor
238
+ def initialize(*args)
239
+ super
240
+ @data_name=['nick_name','local_dir','local_uri','global_dir','global_uri']
241
+ data_path = File.join(ENV['HOME'], '.hikirc')
242
+ DataFiles.prepare(data_path)
243
+ ...以下略...
244
+ \end{lstlisting}
245
+ 通常のclass呼び出しで生成されるようになっている.
246
+ rubyにおいても通常のclassからの実行では,newした後にexeする.
247
+ しかし,Thorにおいてはstartという関数名で初期化・実行される.
248
+ これは,rubyに付属しているRakefileの実行方法とよく似た構文となっている.
249
+
@@ -0,0 +1,234 @@
1
+ {{toc}}
2
+ !方法
3
+ !!optparseとthorの比較
4
+ 今回の研究対象のhikiutilsは,optparseというコマンドライン解析ライブラリで実装されている.
5
+ 本研究ではこの代替ライブラリとしてThorの採用を検討した.
6
+ 本章の最初では,FizzBuzzという簡単なコードを例にoptparseとThorにより作成するコマンドライン解析コードの比較を行う.FizzBuzzはThorの使い方を解説した記事{{cite(1-2)}}で紹介されている.比較しやすくするためoptparseでFizzBuzzを新たに実装した.
7
+
8
+ !!!Thor
9
+ Thorとは,コマンドラインツールの作成を支援するライブラリのことである.gitやbundlerのようにサブコマンドを含むコマンドラインツールを簡単に作成することができる{{cite(1-2)}}.
10
+
11
+ Thorの基本的な流れとしては
12
+ #Thorを継承したクラスのメソッドがコマンドになる
13
+ #クラス.start(ARGV)でコマンドラインの処理をスタートする
14
+ である{{cite(1-2)}}.
15
+
16
+ startに渡す引数が空の場合,Thorはクラスのヘルプリストを出力する.また,Thorはサブコマンドやサブサブコマンドも容易に作ることができる.
17
+
18
+ 以下に示したコードがThorで記述されたfizzbuzzである.
19
+
20
+ <<< ruby
21
+ module Fizzbuzz
22
+ class CLI < Thor
23
+
24
+ desc 'fizzbuzz', 'Get fizzbuzz result from limit number'
25
+ def fizzbuzz(limit)
26
+ print Fizzbuzz.fizzbuzz(limit).join(',')
27
+ exit
28
+ end
29
+
30
+ desc 'version', 'version'
31
+ def version
32
+ puts Fizzbuzz::VERSION
33
+ end
34
+ end
35
+ end
36
+ >>>
37
+
38
+ このコードもoptparseのfizzbuzzと同様fizzbuzzとversionのコマンドを実行させる.
39
+ !!!!fizzbuzzメソッド,versionメソッド
40
+ descでコマンド一覧で表示させるコマンド名と説明を書く.メソッド内ではそれぞれのコマンドの処理内容が書かれている.
41
+
42
+ !!!optparse
43
+ optparseとは,getoptよりも簡便で,柔軟性に富み,かつ強力なコマンドライン解析ライブラリである.optparseでは,より宣言的なスタイルのコマンドライン解析手法,すなわちOptionParserのインスタンスでコマンドラインを解析するという手法をとっている.これを使うと,GNU/POSIX構文でオプションを指定できるだけでなく,使用法やヘルプメッセージの生成も行える{{cite(1-3)}}.利用頻度はあまり高くないが古くから開発され,使用例が広く紹介されている.
44
+
45
+ optparseの基本的な流れとしては
46
+ #OptionParserオブジェクトoptを生成する
47
+ #オプションを取り扱うブロックをopt.onに登録する
48
+ #opt.parse(ARGV)でコマンドラインを実際にparseする
49
+ である.
50
+
51
+ OptionParserはコマンドラインのオプション取り扱うためのクラスであるためオブジェクトoptを生成されopt.onにコマンドを登録することができる.しかし,OptionParser\#onにはコマンドが登録されているだけであるため,OptionParser\#parseが呼ばれた時,コマンドラインにオプションが指定されていれば実行される.optparseにはデフォルトとして--helpと--versionオプションを認識する{{cite(1-4)}}.
52
+
53
+ 以下に示したコードがoptparseで記述したfizzbuzzである.
54
+
55
+ <<< ruby
56
+ module Fizzbuzz
57
+ class Command
58
+
59
+ def self.run(argv)
60
+ new(argv).execute
61
+ end
62
+
63
+ def initialize(argv)
64
+ @argv = argv
65
+ end
66
+
67
+ def execute
68
+ options = Options.parse!(@argv)
69
+ sub_command = options.delete(:command)
70
+ case sub_command
71
+ when 'fizzbuzz'
72
+ fizzbuzz(options[:id])
73
+ when 'version'
74
+ version
75
+ end
76
+ end
77
+
78
+ def fizzbuzz(limit_number)
79
+ (0..limit_number).map do |num|
80
+ if (num % 15).zero? then print 'FizzBuzz'
81
+ elsif (num % 5).zero? then print 'Buzz'
82
+ elsif (num % 3).zero? then print 'Fizz'
83
+ else print num.to_s
84
+ end
85
+ print ' '
86
+ end
87
+ end
88
+
89
+ def version
90
+ puts Fizzbuzz::VERSION
91
+ exit
92
+ end
93
+ end
94
+ end
95
+ >>>
96
+
97
+ このコードはfizzbuzzとversionをコマンドとして実行できる.
98
+ !!!!runメソッド
99
+ コマンド実行を行うためのメソッドであり,argv配列を代入することでexecuteメソッドを実行する.
100
+ !!!!initializeメソッド
101
+ 初期化を行うメソッドである.
102
+ <<<
103
+ @argv = argv
104
+ >>>
105
+ こうすることでargvをクラス内で利用できるようにする.
106
+ !!!!executeメソッド
107
+ 上記でoptparseではopt.onにコマンドを登録する必要があると説明したが,opt.onで登録できるものはハイフンがついたコマンドだけであり,ハイフンなしのコマンドの登録はこのようになる.
108
+
109
+ argv配列の解析を行うOptions.parse!(@argv)をoptionsに代入して解析を行いsub_commandに代入する.sub_commandがfizzbuzzであればfizzbuzz(options[:id])メソッドを実行,versionであればversionメソッドを実行する.
110
+ !!!!fizzbuzzメソッド
111
+ 引数としてlimit_numberを受け取り,0〜limit_numberまでの数字を繰り返す.numが15であればFizzbuzzを表示,5であればBuzzを表示,3であればFizzを表示,それ以外は数字を表示し,その後に空白を表示する.
112
+ !!!!versionメソッド
113
+ fizzbuzzのバージョンを表示する.
114
+
115
+
116
+ !!既存のhikiutilsのコマンド解説
117
+ 既存のhikiutilsはコマンド解析ライブラリのoptparseを用いて,コマンドの処理を行っている.
118
+ optparseの特徴は,「コマンドの登録,実行method」に分けて記述することが期待されている.
119
+ また,CLIの起動の仕方が特徴的である.この二つを取り出して,動作とコードを説明する.
120
+
121
+ !!!コマンドの登録と実行メソッド
122
+
123
+ !!!!caption:(fig:005)コマンドの登録と実行メソッドの対応.
124
+ {{attach_view(hikiutils_yamane.005.jpg,hikiutils_yamane)}}
125
+
126
+ optparseでは以下の通り,コマンドの登録と実行が行われる.
127
+ #OptionParserオブジェクトoptを生成
128
+ #optにコマンドを登録
129
+ #入力されたコマンドの処理のメソッドへ移動
130
+ optparseではOptionParserオブジェクトoptの生成を行い,コマンドをoptに登録することでコマンドを作成することができる.しかし,これはコマンドを登録しているだけでコマンドの一覧ではこれを表示することができるが,コマンドの実行を行うためには実行を行うためのメソッドを作成する必要がある.optparseでのコマンドの実行はoptで登録されたコマンドが入力されることでそれぞれのコマンドの処理を行うメソッドに移動し処理を行う.しかし,このコマンド登録はハイフンを付けたコマンドしか登録ができず,ハイフンなしのコマンド登録はまた別の手段でやらなくてはいけない.
131
+
132
+ <<< ruby
133
+ def execute
134
+ @argv << '--help' if @argv.size==0
135
+ command_parser = OptionParser.new do |opt|
136
+ opt.on('-v', '--version','show program Version.') { |v|
137
+ opt.version = HikiUtils::VERSION
138
+ puts opt.ver
139
+ }
140
+ opt.on('-s', '--show','show sources') {show_sources}
141
+ opt.on('-a', '--add','add sources info') {add_sources }
142
+ opt.on('-t', '--target VAL','set target id') {|val| set_target(val)}
143
+ opt.on('-e', '--edit FILE','open file') {|file| edit_file(file) }
144
+
145
+ ...省略...
146
+
147
+ end
148
+ begin
149
+ command_parser.parse!(@argv)
150
+ rescue=> eval
151
+ p eval
152
+ end
153
+ dump_sources
154
+ exit
155
+ end
156
+
157
+ def show_sources()
158
+ printf("target_no:%i\n",@src[:target])
159
+ printf("editor_command:%s\n",@src[:editor_command])
160
+
161
+ ...省略...
162
+
163
+ end
164
+
165
+ 以下略
166
+
167
+ >>>
168
+
169
+ !!!CLIの実行プロセス
170
+ !!!!caption:(fig:007)CLIの実行プロセス.
171
+ {{attach_view(hikiutils_yamane.007.jpg,hikiutils_yamane)}}
172
+
173
+ optparseを用いた場合のCLIの実行プロセスは次の通りとなる.
174
+ #HikiのHikiUtils::Command.run(ARGV)でhikiutils.rbのrunメソッドを呼ぶ
175
+ #new(argv).executeでexecuteメソッドが実行される
176
+
177
+ optparseではHikiutils::Command.run(ARGV)で実行され,requireで呼び出されたhikiutils.rbのrunメソッドが実行される.そこでコマンドを登録しているexecuteメソッドへ移動し入力したコマンドと対応させる.そして,対応したコマンドの処理が行われるメソッドに移動することで実行される.このようにoptparseでは実行を行うためのメソッドが必要である.
178
+ !!!コード
179
+
180
+ optparseの呼び出し側のexe/hikiのコードは次の通りである.
181
+ <<< ruby
182
+ #!/usr/bin/env ruby
183
+
184
+ require "hikiutils"
185
+
186
+ HikiUtils::Command.run(ARGV)
187
+ >>>
188
+ 「require "hikituils"」ではlib/hikiutils.rbを読み出してくることを期待している.
189
+ これはgemspecファイルでlibへのロードパスの記述がされているため,hikiutils.rbを参照することができる.
190
+ 「Hikiuils::Command.run(ARGV)」ではlib/hikiutils.rbのHikiUtilsモジュールCommandクラスのrunメソッドを実行する記述が成されている.
191
+
192
+
193
+ また呼び出される側のlib/hikiutils.rbのrunおよびexecute部のコードは次の通りとなる.
194
+ <<< ruby
195
+ def self.run(argv=[])
196
+ print "hikiutils: provide utilities for helping hiki editing.\n"
197
+ new(argv).execute
198
+ end
199
+
200
+ def execute
201
+ @argv << '--help' if @argv.size==0
202
+ command_parser = OptionParser.new do |opt|
203
+ opt.on('-v', '--version','show program Version.') { |v|
204
+ opt.version = HikiUtils::VERSION
205
+ puts opt.ver
206
+ }
207
+ opt.on('-s', '--show','show sources') {show_sources}
208
+ opt.on('-a', '--add','add sources info') {add_sources }
209
+ opt.on('-t', '--target VAL','set target id') {|val| set_target(val) }
210
+ opt.on('-e', '--edit FILE','open file') {|file| edit_file(file) }
211
+ opt.on('-l', '--list [FILE]','list files') {|file| list_files(file) }
212
+ opt.on('-u', '--update FILE','update file') {|file| update_file(file) }
213
+ opt.on('-r', '--rsync','rsync files') {rsync_files}
214
+ opt.on('--database FILE','read database file') {|file| db_file(file)}
215
+ opt.on('--display FILE','display converted hikifile') {|file| display(f\
216
+ ile)}
217
+ opt.on('-c', '--checkdb','check database file') {check_db}
218
+ opt.on('--remove FILE','remove file') {|file| remove_file(file)}
219
+ opt.on('--move FILES','move file1,file2',Array) {|files| move_file(file\
220
+ s)}
221
+ opt.on('--euc FILE','translate file to euc') {|file| euc_file(file) }
222
+ opt.on('--initialize','initialize source directory') {dir_init() }
223
+ end
224
+ begin
225
+ command_parser.parse!(@argv)
226
+ rescue=> eval
227
+ p eval
228
+ end
229
+ dump_sources
230
+ exit
231
+ end
232
+ >>>
233
+ runメソッドでは「hikiutils: provide utilities for helping hiki editing.」を表示させ,executeメソッドを実行させる.
234
+ executeメソッドでは最初に「@argv << '--help' if @argv.size==0」と記述する.これはもしargv配列の中身が空であればargv配列に'--help'を代入する.「command_parser = OptionParser.new do |opt|」ではOptionParserオブジェクトがoptを生成しコマンドを登録していき,command_parserに代入する.そして,「command_parser.parse!(@argv)」では@argvにある文字列をcommand_parserでparseする.つまり,ここでは入力されたコマンドを解析し,登録されたコマンドと一致すればその処理が行われる.もし,一致しなければevalメソッドで表示する.