11
ことり先輩の授業はだいぶ進んでいった。
それに従い、プログラムの完成が近づいている。ここで話したい話題だよ、と彼女は今までのプログラムに新しい処理を書いてくれた。
「さあ、今まで書いてきた処理はどこで動作させるのでしょうか」
*───────────────────
void main(){
int result; //計算結果のメモリを用意する
//イコールボタンを押すまで繰り返し
while (buttonequal.Click = false)
//いずれかの数字ボタンを押すと、メモリに加算される
if (button1.Click = true)
result = result + 1;
if (button2.Click = true)
result = result + 2;
...
//メモリに格納されている計算結果を表示する
Print result;
}
────────────────────
彼女はこう言いながら、最初と最後の1行ずつに、まるで包み込むように書き足した。
目玉焼きを作るにはフライパンを使わないといけないように、今まで書いてきた処理を動作させるには、適切なアイテムが必要なのだ。
それが<メソッド>という。
「今まで書いてきた処理は、メソッドの中に書かないといけない。
その目的は、プログラムの機能を"処理"としてまとめるためだよ」
まとめる、と言われてもあまり想像ができないものだ。
「これは"電卓を立ち上げてから計算結果を表示するまで"という処理を書いているよね。
つまり、電卓という目的のためにまとめられている」
なるほど。
目的という単語が出てくると少し理解できるような気がした。
「実際のところは、目的に沿ったメソッドが呼び出されることで、その中に書かれている各処理がひとつずつ動作するようになっているんだよ」
でもさ、と彼女は問いかけるような瞳をこちらに向けながらコーヒーを飲んだ。
「ゲームを遊ぶときって、どんな流れになるかって想像できると思う?」
うん? この人は何を言っているのだろう。
例えば、<アスリート娘>のアプリで遊ぶことを考えてみた。アプリを立ち上げると会社のロゴマークが出て、タップするとメインの画面だ。
そこからは......。あれ? と僕は頭を悩ませた。
育成メニューをタップするかもしれないし、ガチャかもしれないと考えて答えに詰まった。
「育成を途中まで続けたけどやっぱ止めて、ガチャを引きたくなったら?
忙しくて、ログインボーナスだけをもらってすぐ閉じる人もいるよね」
ことり先輩は僕の考えていることを読み取って会話を引き継いだ。
「つまり、ひとつだけのメソッドの中にすべての処理を書くわけにはいかないんだ。
処理の目的に応じたメソッドをそれぞれ作るのが基本なんだ。
ひとつだけだと、すべての遊び方を捉えきれないから。
そして何よりこのメソッドだけが大きくなりすぎちゃうから」
例えば、と彼女は説明してくれた。
メニュー画面の動作が変更になったとする。
このメソッドの中から対象の場所を探していくより、メニュー関連のメソッドを修正するだけで改修が済む。ほかの画面には修正しなくて良い。
「......たくさんのメソッドがあるからアプリが巨大になっていく。それにメンテナンスもひとつだけちょいっと行えば良いわけだ」
なるほど。
......それにしても、なぜ考える題材として<アスリート娘>を選んだのが伝わっているのだろうか。この人はエスパーなんじゃないかとちょっと思ってみた
・・・
そして、この電卓の処理はどのように分割すれば良いのだろうか。
「計算するところでしょうか」
「そうだね、今直してみるよ」
僕の推理を聞き入れてくれた彼女は新しいコードにすぐ直した。
*───────────────────
void main(){
int result; //計算結果のメモリを用意する
//計算するメソッドを呼び出す(→電卓の処理をしてもらう)
result = calc();
//メモリに格納されている計算結果を表示する
Print result;
}
//計算するメソッド
int calc(){
int num;
//イコールボタンを押すまで繰り返し
while (buttonequal.Click = false)
//いずれかの数字ボタンを押すと、メモリに加算される
if (button1.Click = true)
num = num + 1;
if (button2.Click = true)
num = num + 2;
...
return num; //処理の結果をmainメソッドに戻す
}
────────────────────
メソッドは必要に応じて作成していく。
変数の名前と同じように、目的に沿った名前を決めることが大切だと教えてくれた。
<mainメソッド>は電卓の全体を、<calcメソッド>はその中の計算する部分だけを賄うことになる。
ちなみに、"calc"は"calculate"の略である。
このプログラムの処理について、彼女は指をなぞりながら解説してくれた。
* mainメソッドから処理が始まり、calcメソッドを呼び出す
* calcメソッドは1行目から処理が行われる
* イコールボタンを押すまで数字を変数numに加算する
* 最後にnumの値をmainメソッドに戻し、画面に表示する
メソッドは機能によって分けていくことが大切だという。
<calcメソッド>は計算を行うが、printの一文によって計算結果を表示するのは<mainメソッド>の中に書かれている。これは計算する処理を切り出したからなのだが、<mainメソッド>では実のところ何を表示すればよいか分からない。
だからこそ、<calcメソッド>で計算し終わった結果を<mainメソッド>に渡してあげる必要がある。
これが計算結果を戻すということ、return num;という一文だ。
その戻したものがresult = calc();の処理によって変数resultの中に入る。
「そう、メソッドの開始の文に注目してみようか」
そう言ってことり先輩はプログラムのある部分を指さした。
*───────────────────
void main()
...
────────────────────
これは<mainメソッド>を宣言している部分になる。
ここで"main"という名前の前に書かれている単語が、"値を戻す必要があるかどうか"ということを表している。
"void"というのは、"値を返しませんよ"という意味だという。ちなみに、"void"を辞書で引くと"
対して、<calcメソッド>はこのように書かれている。
*───────────────────
int calc()
...
────────────────────
"calc"という名前の前に"int"と書かれていて、つまり"int型の値を戻しますよ"ということを表している。
値を戻すことが前提で作られるメソッドであるため、先のように"return"の一文が記述されていないとエラーとなりプログラムを実行することができない。
「例えば、君が八百屋の店員だったとする。
レジ打ちした商品をを渡してあげないとお客さんは食べられない。
ビニール袋っていう結果を返してあげる。
ここでいうnumというもの、結果を戻すときに使う値を<戻り値>っていうんだ」
なるほど。
自分がその役割を果たす想像したら、理解できるような気がした。ことり先輩の例えは実に面白い。
そんな彼女はこちらを見ながらニコニコと笑っている。
・・・
例えば、この間のアイドル風プログラムは次のようなメソッドを作ることができるという。
*───────────────────
void main(){
greeting(); //オープニングで自己紹介する
//-----歌を歌う-----
greeting(); //アンコールにも自己紹介する
}
//自己紹介のメソッド
void greeting(){
Print("こんにちは!");
Print("自己紹介します~");
Print("私はことりちゃんです");
}
────────────────────
「例えば、私がアンコールでもう一回自己紹介しなきゃいけなくなったとする。
2回同じ発言をするコードを書くと大変だよね」
3行くらいなら簡単だろう、と僕は言いかけて止めた。ゲームのメニューだって、何回も呼び出される可能性があるからだ。それに、片方だけ修正を忘れるかもしれない。
「さっきもやったように、機能を集約して適切に呼び出せることが目的のひとつだよ」
そしてもうひとつ。
彼女はそう言って、人差し指をピンと伸ばした。それはメソッドを呼び出すときに、あらかじめ材料を引き渡すことだ。
「これは"ことりちゃん"が自己紹介しているメソッドだけど、皆が挨拶できるようにすることができる」
つまり、自己紹介をするメンバーを決めることで、より汎用的な自己紹介のメソッドに仕上げることができるという。
*───────────────────
void main(){
greeting("ことりちゃん"); //オープニングで自己紹介する
//-----歌を歌う-----
greeting("すずめ"); //アンコールにも自己紹介する
}
//自己紹介のメソッド
void greeting(string name){
Print("こんにちは!");
Print("自己紹介します~");
Print("私は" + name + "です");
}
────────────────────
「greetingのメソッドを呼び出すときに、string型の変数nameを材料として設定する。
この時の変数を<
実行するときに呼び出される度にnameに別の文字が設定されるため、オープニングとアンコールでは違う結果になる。
(オープニング)
* こんにちは!
* 自己紹介します~
* 私はことりちゃんです
(アンコール)
* こんにちは!
* 自己紹介します~
* 私はすずめです
またひとつ勉強になった。
彼女は僕の気持ちを代弁する一言を告げてくれた。
「メソッドは奥深いよ。
どんな処理で切り分けたらよいか、最初は難しいかもしれない。
最初はまとめて書いてしまっても良いと思う」
その中から重複しているところを発見したり、戻り値を決めたり出来れば良い。
まさしくプログラムの無限の可能性を見ることができた。
・・・
授業が終わって、一緒に喫茶店を出た。
少し熱を帯びた夏風にハトが飛んでいる。
ことり先輩は少し立ち止まって、空を仰いだ。ハトの軌跡の方へ瞳を投げかけている。
「いつか、私も飛んでみたいなって」
"ことり"という名前から思ったのだろうか、意外とロマンチックことを言うものだ。
たしかに、今日の夕焼け空はきれいだ。
僕も空を見上げてみる。
今まで学んだことが空に浮かぶように、きらめいている気がした。空の知識だったものが、日々楽しんでいるって素直に思える。
僕も写真を撮りたくなった。
スマートフォンのカメラを起動して僕も天をのぞいた。カメラのスコープが美しいグラデーションを映し出していた。
シャッターボタンをタップした瞬間、撮影していることに気づかなかった彼女が割り込んでしまう。彼女の姿がスコープに収められた、幻想的な一枚だった。
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます