もっと楽しむ! プログラミング言語 「豆」談義

第8回『なでしこ――こんにちは世界』(2)

定型処理の自動化をやってみましょう

前回は、日本語プログラミング言語のもつ背景的な部分と「なでしこ」の文法面に焦点を当てましたが、今回はなでしこの真骨頂である定型処理の自動化について見ていきます。

なでしこは、作者のクジラ飛行机さんが

『なでしこは「事務自動化ツール」として、プログラマでない人にも、プログラミングを使ってもらえるように考えて作っています[1]⁠。 』

と紹介しているように、文字列操作や日付時間処理のような基本的なものから、ファイル・ディレクトリ操作、ワードやエクセル操作、ファイルの圧縮解凍などが簡単に実現できるように、組み込みライブラリとして豊富な命令(関数)を持っています。

大事なデータをバックアップする仕組み

開発の仕事に従事している人であれば、CSVやSubversionといった構成管理ツールを使って作業成果物を管理していることと思います。また、そこまでではなくとも単純にファイルをコピーして退避することでバックアップとする人もいるかと思います。もちろんエクスプローラで「コピー&ペースト」してもいいのですが、この作業を「なでしこ」のスクリプトとして、リスト1のように、まずはごくごく簡単に実装します。

リスト1 所定のディレクトリを所定の場所にバックアップする
バックアップ対象は「{マイドキュメント}なでしこ」です。 ←――――――――――①
バックアップ先は「c:\_backup\」です。

#バックアップ対象のディレクトリ名を抜き出す
バックアップ対象からファイル名抽出し、バックアップ先にそれを追加する

もし、バックアップ先が存在するならば、
	# バックアップ実行済みなので
	終了する。
違えば
	バックアップ先にフォルダ作成する。

バックアップ先にバックアップ対象をフォルダコピーする ←――――――――――②

「バックアップが完了しました。」と言う。
終了する。

特殊フォルダの扱いをどうするか

Windowsにはユーザアカウントに対応してパスが変わるマイドキュメントやデスクトップといった特別なフォルダが存在しています。これらのフォルダの物理パスは一定のルールに従ったパターンになっていますから、パス文字列をゴニャゴニャと操作すれば求めるフォルダにアクセスできることはできますが、いかんせん面倒くさいです。

そのような時には、リスト1の①のように「特殊フォルダ」というカテゴリのなでしこ組み込みの変数を使用することで、特別な操作をしなくてもこれらのフォルダにアクセスできるようになります。このサンプルコードでは特殊変数をブレースで囲っていますが、こうすることで囲まれた式を展開することができ、その結果全体としてバックアップ対象のフォルダへのパス文字列を作っています。カギ括弧は、Javaでのダブルクォテーションと同じ役割です。

表1 特殊フォルダの一例
変数名物理パス
WINDOWSパスc:\windows
デスクトップC:\Documents and Settings\\デスクトップ
マイドキュメントC:\Documents and Settings\\My Documents

ファイルシステム操作

対象のフォルダのコピーをしているのがリスト1の②になるのですが、命令「フォルダコピーする」を使うだけでサブディレクトリまで含めてのコピーが完了してしまいます。ファイルシステム操作の命令としては、コピー以外にも作成・移動・削除・名前変更・存在確認・ファイルの列挙など必要となりそうなものは一通りそろっています。

一般的に関数に引数を渡すときにはその順序は関数の定義通りに渡すことになりますが、なでしこではこの順番を関数定義とは異なる順序で渡すことができます。なでしこでは、引数と実引数のマッピングを「助詞」をキーにして行うため、その順序が異なっていても引数を対応させられるのです。そのため、⁠AをBにファイルコピーする」としても、⁠BにAをファイルコピーする」としてもどちらでもなでしこは正しく解釈をしてくれます。さらに、命令によっては引数の助詞を複数登録しているものがあるので、プログラムの文脈によって「AからをBへファイルコピーする」とより日本語らしい表現を選ぶことができるようになっています。

バックアップ対象を選別する

List1のスクリプトでは、バックアップ対象となるディレクトリ中にある全てのディレクトリをコピーしていますが、場合によってはコピーしなくてもよいディレクトリがあったりします。そこで、先のスクリプトを改造して、バックアップ対象外のディレクトリを指定できるようにしてみます。さらにバックアップを日毎に履歴できるように日付を退避先ディレクトリ名とするように改造してみます。

リスト2 必要なディレクトリだけを、日付付きのディレクトリにコピーする
バックアップ対象は「{マイドキュメント}なでしこ」です。
バックアップ先は「c:\_backup\」です。
除外ディレクトリリストは「ツール」です。

バックアップ先に、「{今日の"/"を"\"に置換}\」を追加する。 ←―――――――①
# バックアップの対象となるディレクトリ名を取り出す
バックアップ対象からファイル名抽出し、バックアップ先にそれを追加する

もし、バックアップ先のフォルダ存在するならば、
	「バックアップ実行済みです。」と言う。
	終了する。

バックアップ対象のフォルダ列挙して、反復する
	もし、除外ディレクトリリストが対象を含むなら、続ける ←―――――――②
	保存先フォルダは、バックアップ先&"\"&対象
	対象フォルダは、バックアップ対象&"\"&対象
	「バックアップ中:{保存先フォルダ}」を表示する。
	保存先フォルダにフォルダ作成する。
	保存先フォルダに対象フォルダをフォルダコピーする
ここまで
「バックアップが完了しました。」と言う。
終了する。

●含む(listがdirを) ←―――――――――――――――――――――――――③
	listを反復する
		対象とdirを文字列比較する
		もし、それが0なら
			真で戻る
	偽で戻る

日付操作

リスト2の①では、退避先となるバックアップ実行日付に対応したディレクトリパスを作っています。⁠今日」というのは実行時の日付を"yyyy/mm/dd"形式の文字列として返す命令で、その文字列を「置換」という文字列操作命令を使って"yyyy\mm\dd"へと変換しています。そしてさらに、置換した結果を変数「バックアップ先」がポイントしている文字列に追加(append)してバックアップ先のディレクトリへのパスを作り上げています。

日付操作のための命令には、ある時点をとるための「今年」「来月」といったものや時間計算のための命令、さらには日付を和暦に直す命令までそろっています。

"1900/1/1"を和暦変換して、それを表示する。
図1 和暦変換の実行結果
図1 和暦変換の実行結果

関数定義

プログラムを作っていると自分で命令(関数)を作りたくなるケースにどうしても遭遇します。今回は、コードの見通しをよくするためにバックアップ対象のディレクトリが除外リストに含まれているかどうかを判定する処理をユーザ定義の命令としてくくりだしていますリスト2の③⁠。

なでしこでは、この「●」が命令定義の印となっています。命令の本体は、仮引数を使って処理のロジックを組んでいます。前回ふれた特別な変数「それ」は命令の本体からのリターンが代入されることになり、この場合は「真で戻る」⁠偽で戻る⁠⁠)の部分が該当して、⁠return true」に相当します。

新しく定義した命令「含む」は、リスト2の②の箇所で使っています。どうでしょう、日本語らしい表現となっているでしょうか? 命令の名前がこれに落ち着くまでは名前そのものや助詞をどうしたら日本語らしくかつわかりやすくなるかと少し試行錯誤しましたが、このように命令の名前と引数の助詞を工夫することで、プログラムをより日本語として理解しやすくすることができます。

おわりに

なでしこのコードを読み書きしていると、⁠日本語は曖昧」だとか「ロジカルな記述に向いていない」というよく言われる台詞に非常に疑問を感じるようになりました。世界中に存在するどんな言語よりも厳密で、ロジカルであるはずの「プログラミング言語」として立派に日本語は使えているのですから、問題なのは「曖昧な書き方をしている書き手」なのではないでしょうか?――そんなことを考えていると、いっそのこと仕様書をなでしこで書いてみてはどうだろうか、とも考えたりします。


『もっと楽しむ! プログラミング言語「豆」談義』としてお送りしてきた本シリーズは、今回でひとまず終了となります。

どうでしょう、皆さんのアンテナに反応する言語はあったでしょうか?

このシリーズでご紹介できた言語は世にある言語のほんの一部に過ぎませんが、それでも「へーっ」とか「ほ~」と思ってもらえたり、さらに実際に動かしてみてもらえていたり、さらにさらに、この連載が新しい言語を習得するきっかけとなっていたりしたら、最高にうれしいです。

おすすめ記事

記事・ニュース一覧