(4)10/19の授業内容
- メソッドとは
- メソッドの定義方法
- def shohizei(a):shohizeiという名前のメソッドを定義しています。()の中に書くのは引数リストといい、aとだけかいてあります。これはメソッドshohizeiを実行するためには引数が1つ必要ということを意味しています。別の場所でメソッドshohizeiを使用する際にはshohizei(100)のように必ず1つの引数が必要となります。なお、メソッド定義の引数リストにかく変数は仮引数と呼び、メソッドを呼んだときに与えた値が代入されます。shohizei(100)の場合はaに100が代入されます。
- a * 1.05:def-endの間に書くのがメソッドの定義本体です。ここでは数式が書かれていますが、printf ("税込み価格は%d円です\n",price)のようなRubyのメソッドを書いても構いません。
- end:メソッド定義の終了を示します。
- shohizei(item):ここで先ほど定義したshohizeiメソッドを呼び出しています。引数にはitemを与えています。itemはユーザーが入力した任意の値です
- def tax(x):taxという名前のメソッドを定義しています。tax(x)となっているので引数が1つ必要になります。
- price = x * 1.05:今度は定義が2行になっています。1行目はメソッドtaxを呼び出す際に与えられた引数を1.05倍した値をpriceに代入するというものです
- printf ("税込み価格は%d円です\n",price):2行目はprintfを使って「税込み金額は○円です」とpriceの値を表示するというものです。def-endの中に複数行の文がある場合、上から順番に処理が実行され、一番最後の行が返り値となります
- end:メソッド定義の終了を示します。
- tax(item):ここで先ほど定義したtaxメソッドを呼び出しています。引数にはitemを与えています。itemはユーザーが入力した任意の値です。なおtaxメソッドには最後に結果を表示するprintfの文も含まれているので、shohizeiメソッドとは呼び出し方が異なっています
- def-end利用上の注意
これまで使用してきたprint、gets、to_iなどは、決められた手順を実行し、その結果を返してくれるものでした。このような働きをするものをメソッドと呼んできました。
メソッドは自分で作ることもできます。今日は、自分でメソッドを作る方法について学びます。
メソッドを定義するにはdefを利用します。
def メソッド名(引数リスト) 定義本体 end
簡単なメソッドを定義した例を見てみましょう
消費税を計算するメソッド:shohizei(shohizei.rb)
#!/usr/koeki/bin/ruby def shohizei(a) a * 1.05 end STDERR.print "金額を入力してください" item = gets.chomp!.to_i printf ("税込み金額は%d円です\n", shohizei(item))
上記について順を追って説明します。
消費税を計算するメソッド:tax(tax.rb)
#!/usr/koeki/bin/ruby def tax(x) price = x * 1.05 printf ("税込み価格は%d円です\n",price) end STDERR.print "金額を入力してください" item = gets.chomp!.to_i tax(item)
突然新しい表現方法が出てくると戸惑うかもしれません。でも、実際は下記のプログラムを書き直しただけなのです。
#!/usr/koeki/bin/ruby STDERR.print "金額を入力してください" item = gets.chomp!.to_i price = item * 1.05 printf ("税込み価格は%d円です\n",price)
なぜこんな手間のかかる作業が必要なのでしょうか。あえてメソッドを定義しなくても、そのまま素直に書けばいいのにと思うかもしれません。確かにこのような単純で短いプログラムではdef-endを使う意味はあまりありません。
では、1000行程度の長いプログラムを書くことを考えてみましょう。長いプログラムを書く際には、同一の処理が複数の場所で出てくることがあります。また、できる限りすっきりと書いて、全体の流れをわかりやすくしたいとも思います。def-endを使うことで、複数箇所における同一処理は1つにまとめることができます。これによりプログラムを短く書くことができます。また、インターネットの掲示板を作ることを考えてみましょう。掲示板の主要な働きは投稿されたコメントを表示するというものです。しかし、これ以外にも細かな処理として(1)記述されたURLに自動的にリンクを貼る、(2)画像付き掲示板の場合画像のサイズを調べ、大きすぎる場合はエラー表示を出す、(3)コメントを投稿者が削除しようとした時に入力時のパスワードと、削除処理時のパスワードを照合する、等があります。これらも全てプログラムの中に書いていくわけですが、そのまま書くととてつもなく長いプログラムになり、プログラムの全体像を把握するのが難しくなります。URLkinkメソッドを定義して、プログラム本体にはURLlinkとだけ明記しておき、実際にURLの自動リンクを行う処理はdef-endの中で定義しておけば、プログラム本体はすっきりし、流れがわかりやすくなります。
呼び出す前に定義をする
def-endで定義をしたメソッドを呼び出す場合、呼び出す前に定義が行われている必要があります。定義が下に書かれていても呼び出せません
引数は1つとは限らない
shohizeiやtaxは引数が1つしかありませんでしたが、0の場合や2つ以上の場合もあります。
引数が0の場合(単にこんにちはと表示するだけのメソッド:hello)
#!/usr/koeki/bin/ruby
def hello()
print "こんにちは!\n"
end
hello
引数が不要な場合は、引数リストのカッコ内は空にします。
引数が2の場合(三角形の面積を求めるメソッド:triangle)
#!/usr/koeki/bin/ruby
def triangle(x,y)
menseki = x * y / 2
printf ("面積は%4.2f平方センチメートルです\n",menseki)
end
STDERR.print "底辺をcm単位で入力してください"
teihen = gets.chomp!.to_f
STDERR.print "高さをcm単位で入力してください"
takasa = gets.chomp!.to_f
triangle(teihen, takasa)
引数が2の場合(三角形の面積を求めるメソッド:sankaku)
#!/usr/koeki/bin/ruby
def sankaku(x,y)
x * y / 2
end
STDERR.print "底辺をcm単位で入力してください"
teihen = gets.chomp!.to_f
STDERR.print "高さをcm単位で入力してください"
takasa = gets.chomp!.to_f
printf ("面積は%4.2f平方センチメートルです\n",sankaku(teihen, takasa))
メソッドの返り値は最後の行の結果とは限らない
#!/usr/koeki/bin/ruby
def sankaku(x,y)
x * y / 2
end
STDERR.print "底辺をcm単位で入力してください"
teihen = gets.chomp!.to_f
STDERR.print "高さをcm単位で入力してください"
takasa = gets.chomp!.to_f
printf ("面積は%4.2f平方センチメートルです\n",sankaku(teihen, takasa))
メソッドの返り値は最後の行の結果とは限らない
if-endを使った場合には最後の行の結果が返り値とはならないことがあります。
#!/usr/koeki/bin/ruby
def min(x,y)
if x < y
(return) x #returnは省略可能
else
(return) y #returnは省略可能
end
end
def-end部分のみですが、これは2つの引数を比較して小さい方を返り値とするというメソッド(min)です。最後の行ではなく、途中で値を返す場合にはreturnを使いますが省略可能です。
引数にはデフォルト値を指定することができる
引数が必要なメソッドにおいて、引数が省略された場合に適用される値(デフォルト値)を指定しておくことができます
#!/usr/koeki/bin/ruby
def sankaku(x,y=10)
x * y / 2
end
printf ("面積は%4.2f平方センチメートルです\n", sankaku(5)) #=>5*10/2=25
printf ("面積は%4.2f平方センチメートルです\n", sankaku(5,8)) #=>5*8/2=20
上記の例ではyのデフォルト値として10が与えられている。sankaku(5)で呼び出した場合は、xの値しか指定していないのでyには自動的に10が代入される。sankaku(5,8)で呼び出した場合はx、yいずれも値が指定されているのでデフォルト値は代入されない。
なお、定義したメソッドを呼ぶときは引数を順番に与えていくため、前の引数を省略して後ろの引数を指定することはできません。具体的に言うと、上記の例でsankaku(5)となっている場合、5は自動的にxに与えられます。このため、xにデフォルト値を与え、yには与えていない場合はエラーになってしまいます。したがって、
○ def sankaku(x=10, y=8) ○ def sankaku(x, y=8) × def sankaku(x=10, y)
となります。
メソッドに配列を渡すこともできる
2回目の授業のbokin.rbを改良してみましょう。募金の合計額を算出するtotalというメソッドを定義します。
#!/usr/koeki/bin/ruby def total(yen) #yenは数値の入っている配列 sum = 0 x = 0 while x < yen.length-1 #.lengthで配列の中のデータの個数を調べる sum += yen[x] x += 1 end sum #最終行が返り値となるので単にsumと書いている end bokin = [] i = 0 while true STDERR.print "募金お願いします" bokin[i] = gets.chomp!.to_i if bokin[i] == 0 then break end i += 1 end printf ("募金の合計は%d円でした\n",total(bokin))
本日の課題
引数を2つ以上必要とするメソッドをdef-endを用いて定義し、それを利用するプログラム書いてください。面白いものや日常生活で役に立ちそうなものを題材とするとよい
作成したプログラムや実行結果をメールでnaoya@e.koeki-u.ac.jp宛に送る
課題の提出期限は10月25日(火)23:59までです
メール送信時の注意
- Subjectは「学籍番号-1019」とすること
- メール本文は下記の構成で記載すること
- プログラム(メールに貼り付ける)
- プログラムの実行結果
- プログラムの説明
- 感想
説明のポイント:今回は人によって全く内容が異なるプログラムが出来上がるはずです。何をするプログラムなのか、定義したメソッドが行う処理は何かについて説明しているかどうかを中心に評価します。
レポート採点基準:期限内提出(2点)、プログラムの正誤(3点)、説明(2点)、役立ち度や面白さ、オリジナリティ(2点)、指示通りにメールを送っているか(1点)
Tips
emacsについて
- emacsで新しいファイルを作成する場合は,C-x C-fを押し,ミニバッファにkensaku/kadai2.rbのようにファイル名を入力する
- ファイルの保存はC-x C-s
- 日本語入力のオンオフの切り替えはC-o
Mewについて
- emacsを起動する
- Escとxを押し,mewと入力しReturn(Escとxを押すことを,一般にM-xと表記します)%<--これでMewが起動します
- Mewを起動するとパスワードがたずねられるので入力しReturn
- 新着メールの確認およびパスワードを間違えた場合はiと入力しReturn
- メールを読む場合は,カーソルキー(矢印キー)で読みたいメールを選びReturn
- メールの新規作成はwと入力
- e-mailの本文にテキストファイルを読み込むには,新規送信メール画面の本文を記入するエリアにカーソルを移動し,Ctrl+x,iとすると,ミニバッファにInsert file: ~/と表示されるので,読み込みたいファイル名を入力する。
- プログラムの実行結果の貼り付けは,kterm上の出力結果部分をマウスで選択し,Mewの本文の貼り付け位置にカーソルを移動し,マウスの真ん中ボタンをクリックする
- メールの送信はC-c C-cと入力するか,もしくはメニューのsendアイコンをクリックする
- Mewを終了するにはqと入力
- emacsを終了する