時をかける引数

今回は引数をサマーウォーズで例えてみたいと思います。
時かけの千秋ファンの皆さま、期待させてしまいすみません。

サマーウォーズとは、、
”オズ”と呼ばれる仮想世界が世界中の人々の暮らしに深く浸透している近未来を舞台に、数学以外には何のとりえもない高校生・健二と、彼の先輩・夏希とその親戚たちが、世界を救うために立ちはだかる!

作中で登場する人気キャラに「かずま」と呼ばれる13歳の引きこもりの少年がいます。
彼はオズの世界で「キングカズマ」というウサギ型のアバターを操り、なんと格闘技のチャンピオンなんです!

今回は、そんな

  • 仮想世界「オズ」
  • 引きこもり少年「かずま」
  • 最強アバター「キングカズマ」

を用いて、引数についてお話ししたいと思います。

作成するプログラムは、
「キングカズマが過去に戦った相手の名前と年齢を登録、管理するアプリ」です。
ちなみに、彼は負けなしなので勝敗は記録しません。最強ですからね。

まず引数を一言で説明すると、「引数はメソッドに渡す値のこと」です。
そして、引数にも2種類あって「実引数」と「仮引数」があります。

それぞれ、
メソッド:point_right:オズ
実引数:point_right:かずま
仮引数:point_right:キングカズマ
で考えていきますね。

まず「かずま」を誕生させます。データ登録するためには本人がいないと始まらないですよね。

summerWars.rb
kazuma = []

これは配列と呼ばれるものです。データを保管するための大きい箱だと思ってください。

次に「かずま」が「オズ」にログインするためのログイン画面を作ってあげないといけませんね。

summerWars.rb
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) :point_right: メソッド名(実引数)

続けて、オズの世界を作ります。

summerWars.rb
def oz(kingKazuma)
  battle = {}  #対戦相手を登録するためのハッシュを生成

end

これはメソッドと呼ばれるものです。
「oz」というメソッド名が呼ばれたらここに「kazuma」が転送されます。

ここでポイントがあります。

さっきまでoz(kazuma)だったのに、メソッド内ではoz(kingKazuma)になっています。
これは「かずま」が「キングカズマ」となって「オズ」の世界へログインしたということです。

お察しの良い方ならお気づきだと思いますが、
実引数と仮引数の中身は同じだが、メソッド内では呼び方を変えることができるんです。

例えば「かずま」がアバター名を「キングカズマ」ではなく「かずま」のままにしても問題ないですし、「とっとこハム太郎」という名前にしても同じ値を渡すことができます。
最強のとっとこハム太郎の誕生ですね。

そして、battle = {}という記述があります。
これはハッシュと呼ばれるもので、1つのデータを保管する小さい箱だと思ってください。
今回だと、1人の対戦相手を登録するための箱です。

次に、対戦相手の情報を入力する必要がありますね。名前と年齢です。
それぞれ、battle[:name] battle[:age]という名前をつけて保存しましょう。
これらの名前をキーといい、実際に中に入る値をバリューと呼びます。
基本的には「ハッシュの中にはキーとバリューがセット」で入っている、と覚えましょう。

情報を入力する時は、下記の方法を使います。
gets.chomp :point_right: 文字列で入力
gets.to_i :point_right: 整数で入力
これらを合わせると、

summerWars.rb
  battle[:name] = gets.chomp  #文字列を代入
  battle[:age] = gets.to_i    #整数を代入

という風に登録できますね。

データ自体の登録ができたら、今度は「キングカズマ」の戦歴にそれを登録する必要があります。

summerWars.rb
  kingKazuma << battle  #キングカズマの戦歴に登録

これは、配列にハッシュを登録しています。

このメソッドをまとめると、このようになります。

summerWars.rb
def oz(kingKazuma)
  battle = {}
  puts "対戦相手の名前を入力してください"
  battle[:name] = gets.chomp
  puts "対戦相手の年齢を入力してください"
  battle[:age] = gets.to_i

  kingKazuma << battle
  puts "登録完了しました!"
end

これで、「キングカズマ」の戦歴に数多の挑戦者たちの情報が刻まれるようになります。

次に、登録したデータを一覧で見たいですよね。
今回はその時のメソッドも作っちゃいましょう。

summerWars.rb
def battleResult(kingKazuma)
  puts "過去に対戦した一覧です"
  kingKazuma.each_with_index do |battle, index|
    puts "[#{index + 1}]名前:#{battle[:name]}\n"
  end

end

まず、先ほどと同じように「かずま」が「キングカズマ」として、今度は「battleResult」という世界にログインしました。
ここで見慣れないコードがありますが、きちんと説明しますのでタイムリープで逃げないでくださいね。

多分みなさんがよく見るのはこれですよね:point_down:

summerWars.rb
  kingKazuma.each do |battle|

そして今回登場したのはこれ:point_down:

summerWars.rb
  kingKazuma.each_with_index do |battle, index|

まず、each文は、「配列の中身を1つずつ取り出し、繰り返す」というものでしたよね。
しかし、今回はeach_with_indexという名前になってます。
これは基本的にやってることは同じなんですが、
取り出すと同時に要素の番号も引っ張ってきてくれる便利なやつなんです!
その代わり、引数の2つ設定してあげる必要があります。

summerWars.rb
  配列.each_with_index do |第一引数, 第二引数|

ちなみに、ここでも第一・第二引数の名前は何でもOKですが、わかりやすい名前にしておきましょう。

ここで第二引数を各要素に割り振る番号として設定しています。
それでは、もう一度先ほどのコードを見てみましょう。

summerWars.rb
  kingKazuma.each_with_index do |battle, index|
    puts "[#{index + 1}]名前:#{battle[:name]}\n"
  end

「ん???何でindexに + 1 してるの???」

これには理由があります。
配列の中に入っている要素は元々0から順番に番号が振られています。
つまり順番に取り出したら、0から始まってしまうのです。Re:ゼロからh

0から始まるリストよりも、1から始まった方が自然ですよね?
だから、初回のindexから1を足してるのです。
以下が、実際に出力される内容です。

summerWars.rb
過去に対戦した一覧です
[1]名前:タロウ
[2]名前:ジロー
[3]名前:サブロー

そして、このリストの番号を入力すれば、その詳細が見れるようにしたいです。
その場合は、下記のようにします。

summerWars.rb
  input = gets.to_i  #番号を入力し、inputへ代入

  battle = kingKazuma[input - 1]  #配列の中の要素番号を指定し、battleへ代入
  puts "名前:#{battle[:name]}、年齢:#{battle[:age]}"

ここで、inputを - 1してるのは、
元々の割り振られている番号は0のままだからです。
先ほど、+1した分をここで引かないといけませんからね。

このメソッドをまとめると、このようになります。

summerWars.rb
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

そして、最初のログインの画面で、戦歴一覧も選択できるようにしましょう。

summerWars.rb
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

これで、タイトル画面で、ログインと戦歴一覧を選択できるようになりました。

全てまとめると、下記のようなプログラムになります。おさらいしましょう。

summerWars.rb
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

以上で、キングカズマの戦歴管理アプリが完成しました。
今回のまとめは、

  • 実引数と仮引数は同じ値だが、メソッド先では名前を任意で変更できる
  • 各メソッド先でわかりやすい名前にする

ということでした。

私がプログラミング学習で最初につまづいたところが引数でした。
なので、私世代の人たちならみんな知ってるもので例えてみました。
値渡しと参照渡しの話もしたかったのですが、今回は割愛します。
一人でも多くの人に伝わると嬉しいです。
今後とも、よろしくおねがいしまーーーーーーーーーす!!!!!!!!

yuy_ns
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
コメント
この記事にコメントはありません。
あなたもコメントしてみませんか :)
すでにアカウントを持っている方は
ユーザーは見つかりませんでした