「引数って何だかよくわからない」
私がプログラミングを学習し始めて最初にぶち当たったのが、引数です。
今回はそんな引数を、映画:サマーウォーズで例えてみたいと思います。
時かけの千秋ファンの皆さま、タイトルで期待させてしまいすみません。
サマーウォーズとは、、
”オズ”と呼ばれる仮想世界が世界中の人々の暮らしに深く浸透している近未来を舞台に、数学以外には何のとりえもない高校生・健二と、彼の先輩・夏希とその親戚たちが、世界を救うために立ちはだかる!
作中で登場する人気キャラに「かずま」と呼ばれる13歳の引きこもりの少年がいます。
彼はオズの世界で「キングカズマ」というウサギ型のアバターを操り、なんと格闘技のチャンピオンなんです!
今回は、そんな
- 仮想世界「オズ」
- 引きこもり少年「かずま」
- 最強アバター「キングカズマ」
を用いて、引数についてお話ししたいと思います。
作成するプログラムは、
「キングカズマが過去に戦った相手の名前と年齢を登録、管理するアプリ」です。
ちなみに、彼は負けなしなので勝敗は記録しません。最強ですからね。
まず引数を一言で説明すると、「引数はメソッドに渡す値のこと」です。
そして、引数にも2種類あって「実引数」と「仮引数」があります。
それぞれ、
メソッドオズ
実引数かずま
仮引数キングカズマ
で考えていきますね。
まず「かずま」を誕生させます。データ登録するためには本人がいないと始まらないですよね。
kazuma = []
これは配列と呼ばれるものです。データを保管するための大きい箱だと思ってください。
次に「かずま」が「オズ」にログインするためのログイン画面を作ってあげないといけませんね。
while true do
puts "Welcome to oz!"
puts "[0]login"
input = gets.to_i #数字を入力する
if input == 0 #入力された値が0なら
oz(kazuma) #オズの世界へログイン
else
puts "入力された値は無効です"
end
end
ここでは0が入力されると、「かずま」を「オズ」の世界へ連れていきます。
oz(kazuma) メソッド名(実引数)
続けて、オズの世界を作ります。
def oz(kingKazuma)
battle = {} #対戦相手を登録するためのハッシュを生成
end
これはメソッドと呼ばれるものです。
「oz」というメソッド名が呼ばれたらここに「kazuma」が転送されます。
ここでポイントがあります。
さっきまでoz(kazuma)
だったのに、メソッド内ではoz(kingKazuma)
になっています。
これは「かずま」が「キングカズマ」となって「オズ」の世界へログインしたということです。
お察しの良い方ならお気づきだと思いますが、
実引数と仮引数の中身は同じだが、メソッド内では呼び方を変えることができるんです。
例えば「かずま」がアバター名を「キングカズマ」ではなく「かずま」のままにしても問題ないですし、「とっとこハム太郎」という名前にしても同じ値を渡すことができます。
最強のとっとこハム太郎の誕生ですね。
そして、battle = {}
という記述があります。
これはハッシュと呼ばれるもので、1つのデータを保管する小さい箱だと思ってください。
今回だと、1人の対戦相手を登録するための箱です。
次に、対戦相手の情報を入力する必要がありますね。名前と年齢です。
それぞれ、battle[:name]
battle[:age]
という名前をつけて保存しましょう。
これらの名前をキー
といい、実際に中に入る値をバリュー
と呼びます。
基本的には「ハッシュの中にはキーとバリューがセット」で入っている、と覚えましょう。
情報を入力する時は、下記の方法を使います。
gets.chomp
文字列で入力
gets.to_i
整数で入力
これらを合わせると、
battle[:name] = gets.chomp #文字列を代入
battle[:age] = gets.to_i #整数を代入
という風に登録できますね。
データ自体の登録ができたら、今度は「キングカズマ」の戦歴にそれを登録する必要があります。
kingKazuma << battle #キングカズマの戦歴に登録
これは、配列にハッシュを登録しています。
このメソッドをまとめると、このようになります。
def oz(kingKazuma)
battle = {}
puts "対戦相手の名前を入力してください"
battle[:name] = gets.chomp
puts "対戦相手の年齢を入力してください"
battle[:age] = gets.to_i
kingKazuma << battle
puts "登録完了しました!"
end
これで、「キングカズマ」の戦歴に数多の挑戦者たちの情報が刻まれるようになります。
次に、登録したデータを一覧で見たいですよね。
今回はその時のメソッドも作っちゃいましょう。
def battleResult(kingKazuma)
puts "過去に対戦した一覧です"
kingKazuma.each_with_index do |battle, index|
puts "[#{index + 1}]名前:#{battle[:name]}\n"
end
end
まず、先ほどと同じように「かずま」が「キングカズマ」として、今度は「battleResult」という世界にログインしました。
ここで見慣れないコードがありますが、きちんと説明しますのでタイムリープで逃げないでくださいね。
多分みなさんがよく見るのはこれですよね
kingKazuma.each do |battle|
そして今回登場したのはこれ
kingKazuma.each_with_index do |battle, index|
まず、each文は、「配列の中身を1つずつ取り出し、繰り返す」というものでしたよね。
しかし、今回はeach_with_index
という名前になってます。
これは基本的にやってることは同じなんですが、
取り出すと同時に要素の番号も引っ張ってきてくれる便利なやつなんです!
その代わり、引数の2つ設定してあげる必要があります。
配列.each_with_index do |第一引数, 第二引数|
ちなみに、ここでも第一・第二引数の名前は何でもOKですが、わかりやすい名前にしておきましょう。
ここで第二引数を各要素に割り振る番号として設定しています。
それでは、もう一度先ほどのコードを見てみましょう。
kingKazuma.each_with_index do |battle, index|
puts "[#{index + 1}]名前:#{battle[:name]}\n"
end
「ん???何でindexに + 1 してるの???」
これには理由があります。
配列の中に入っている要素は元々0から順番に番号が振られています。
つまり順番に取り出したら、0から始まってしまうのです。Re:ゼロからh
0から始まるリストよりも、1から始まった方が自然ですよね?
だから、初回のindexから1を足してるのです。
以下が、実際に出力される内容です。
過去に対戦した一覧です
[1]名前:タロウ
[2]名前:ジロー
[3]名前:サブロー
そして、このリストの番号を入力すれば、その詳細が見れるようにしたいです。
その場合は、下記のようにします。
input = gets.to_i #番号を入力し、inputへ代入
battle = kingKazuma[input - 1] #配列の中の要素番号を指定し、battleへ代入
puts "名前:#{battle[:name]}、年齢:#{battle[:age]}"
ここで、inputを - 1してるのは、
元々の割り振られている番号は0のままだからです。
先ほど、+1した分をここで引かないといけませんからね。
このメソッドをまとめると、このようになります。
def battleResult(kingKazuma)
puts "過去に対戦した一覧です"
kingKazuma.each_with_index do |battle, index|
puts "[#{index + 1}]名前:#{battle[:name]}\n"
end
input = gets.to_i
battle = kingKazuma[input - 1]
puts "名前:#{battle[:name]}、年齢:#{battle[:age]}"
end
そして、最初のログインの画面で、戦歴一覧も選択できるようにしましょう。
while true do
puts "Welcome to oz!"
puts "[0]login"
puts "[1]result"
input = gets.to_i
if input == 0
oz(kazuma)
elsif input == 1
battleResult(kazuma)
else
puts "入力された値は無効です"
end
end
これで、タイトル画面で、ログインと戦歴一覧を選択できるようになりました。
全てまとめると、下記のようなプログラムになります。おさらいしましょう。
def oz(kingKazuma)
battle = {}
puts "対戦相手の名前を入力してください"
battle[:name] = gets.chomp
puts "対戦相手の年齢を入力してください"
battle[:age] = gets.to_i
kingKazuma << battle
puts "登録完了しました!"
end
def battleResult(kingKazuma)
puts "過去に対戦した一覧です"
kingKazuma.each_with_index do |battle, index|
puts "[#{index + 1}]名前:#{battle[:name]}\n"
end
input = gets.to_i
battle = kingKazuma[input - 1]
puts "名前:#{battle[:name]}、年齢:#{battle[:age]}"
end
kazuma = []
while true do
puts "Welcome to oz!"
puts "[0]login"
puts "[1]result"
input = gets.to_i
if input == 0
oz(kazuma)
elsif input == 1
battleResult(kazuma)
else
puts "入力された値は無効です"
end
end
以上で、キングカズマの戦歴管理アプリが完成しました。
今回のまとめは、
- 実引数と仮引数は同じ値だが、メソッド先では名前を任意で変更できる
- 各メソッド先でわかりやすい名前にする
ということでした。
何となくイメージはつきましたでしょうか?
ついたなら、私はとても嬉しいです。
値渡しと参照渡しの話もしたかったのですが、今回は割愛します。
一人でも多くの人に引数とキングカズマの強さが伝わると嬉しいです。
これからもTwitterでプログラミング初学者に役立つ情報を発信していきますので、
今後とも、よろしくおねがいしまーーーーーーーーーす!!!!!!!!