LOG IN

阪大の問題2をもらった話

by らきいば

この記事はAFTAC2019、18日目の記事です。AFTACについては藤岡さんのブログを参照してください。

※この記事はプログラミングの話が主です。まったく知らない人でも読めるよう、配慮はしていますが、意味がわからない人は意味がわからないとおもいます。

1. はじめに

「暇だなぁ~」と思っていたある日のこと。

某氏からこんなデータを貰いました。

※なお、zipを全て解凍せずに、7zipで一時的に開いていただけなので、CSS、画像等は表示されていません。

どうやら、某阪大のシェルを作る課題を出して来たようです。

ということで、今回の記事は、自作のシェルをつくった話です。

「シェルってなんやねん!」と思った方、いますよね?

Wikipediaによると、「シェルはオペレーティングシステムのユーザーのためにインターフェースを提供するソフトウェアであり、カーネルのサービスへのアクセスを提供する。それだけではなく、この用語は非常にゆるやかに応用され、特定のコンポーネントの周辺に構築された任意のソフトウェアを含むこともある。」(Wikipedia - 「シェル」2019年6月30日 (日) 02:06の版より)

......と言われても、コンピューターに詳しくない人は、何の話か分かりませんよね。まあ、大雑把に若干間違いを含んだ言い方をすると、「Windowsのコマンドプロンプトのようなもので、使用者の指示をコンピューターに伝える役目を持つプログラム」という感じでしょうか。

それでもわからない方は、気の済むまでググってください(投げやり

2. いざ実装!

はい出来ました。

......そんな簡単にできたら苦労しません。

実装はJavaです。Twitterでは定期的に進捗のスクリーンショットを出していましたが、2週間の間、大学行ってるのとご飯食べてるのと寝てるの以外は、だいたいこれしてました。

初、ではないですが割とガッツリJFrameを触っていました。かなり知らないことが多く、ここだけでかなり時間を食っていました。JFrameとは、JavaにあるGUIを実装するプログラム群の一種です。ついでにGUIとはGraphical User Interface(グラフィカルユーザーインターフェース)の略で、画面にアイコンとか画像とか、そういうものを表示させて、ユーザーに操作してもらうものです。ちなみに対となるCUIはCharacter User Interface(キャラクタユーザーインターフェース)などの略でWindowsのコマンドプロンプトのようなものです。

こういうのがいわゆるCUI。

※ここでの説明はあくまでもイメージですので、完全に正確であるとは保証しかねます。

JFrameを触っているのだから、素敵なGUIをつくっているんでしょう、と思われがちですが、車輪の再発明とはまさにこのことで、JFrameでCUIコンソールをつくっていました。

実際につくった画像がこちら。

完全にCUIですね、分かります。コマンドプロンプトのパクリですかね。もっと、GUIらしいGUIを作りたかったです。一番下の一行が入力欄で、その一行にばーっと入力してエンターを押すと実行されて上側の広いところに表示されます。

ところで、JFrameのいいところは、様々な部品をフレーム(枠)内に設置していくイメージで、感覚的に出来、最終的にはレイヤーマネージャーというプログラム群がいい感じに配置してくれます。

緑の部分は、JTextAreaという部品(setEditable(false)を指定しています。つまり書き込み禁止になっています。)で、赤の部分はJTextField、紫の部分はJScrollPaneという部品です。これらを同一のJPanelに追加して、それを表示させています。赤い部分にactionPerformedという、エンターキーを押すと呼び出されるメソッド(関数のこと。いくつかの処理をまとめたもの)を実装し、これが呼び出されたタイミングで、赤い枠の中身の文字列を自作のコマンド意味解釈メソッドに渡します。

ウィンドウ自体のリサイズには、componentResized(ウィンドウの大きさが変わると呼び出される関数)をオーバーライド(もともとある機能を自分用に設定し直すこと)し、毎回、setPreferredSize(中身の部品のサイズを調整する関数)を呼び出すことで対応しました。

スクロールバーですが、これが地味に詰まりました。もしJavaでスクロールバーを扱おうと思う方がいれば、こちらの記事は必読です。(詳しいつまりポイントは、リンク先の記事に任せますが、この記事以外の部分で詰まることはありませんでした)

このCUIを表示させるGUIを作るだけで1週間ぐらい掛かっていました。

さて、自作のコマンド意味解釈メソッドは以下の順番で動作します。

  1. ワイルドカード(*)が含まれていないか

  2. エイリアスを変換

  3. コマンドが「exec」でないか

  4. コマンドの第2引数に「?」「-help」などがついていないか

  5. コマンド一覧に一致するものはないか

  6. コマンド一覧になければ、外部ファイルとして実行

  7. 実行履歴に残すかどうか

  8. コマンドが「cls」ではないか

エイリアスとは、「通称」とか「偽名」とかの意味で、あるコマンドを別の名前で保存しておける機能です。例えば「sprict」を「script」コマンドと関連付けておくと、「script」と入力しても「sprict」と入力しても同じ「script」コマンドが呼び出されます。

この画像はだいたい上記1~5のソースコードです。この画像を見て既にお気づきの人もいるかも知れませんが入力したコマンドは全て小文字に変換されて処理されます。

さて、各種コマンドですが、詰まったところを3点ほど紹介します。いろいろと説明するのがめんどくさくなってきたのと、記事がものすごく長くなってしまうので、わからない方は、読み飛ばしてください。

あ、あと単純にめんどくさかったのは、help内の文章を書くことです。

課題に表記されていなかった、独自仕様としては「cuiコマンド」「scriptコマンド」「clsコマンド」「reコマンド」「execコマンド」「helpコマンド」「manコマンド」「exitコマンド」「timeコマンド」「上下キーで履歴が入力される補助機能」「prompt nowで現在のディレクトリをプロンプトに設定する機能」です。各機能の実装方法やどんなものであるかは、長くなるので説明しません。

※execコマンドは、登録されているコマンドと同名のプログラムを外部コマンドとして実行したい(名前の重複がある場合)場合のために実装されました。

3. まとめ

製作期間2週間

コード640行

はじめ見たときは、結構簡単そうだなぁ、と思ったのですが、意外と時間かかってしまいました。原因はJFrame。もっとGUIも作っていかないと行けないですね......。あと、コードは640行なのですが、きっとコンパイラさんがいい感じに最適化してくれている(はず)ので、気にしないことにします。

あとから某氏に訊くと、別にGUIフレームを実装せずとも、CUIプログラミングでも良かったそうです。

以上。

OTHER SNAPS