Ruby プログラミング

[Ruby]メソッドの定義と呼び出し

method

こんにちは!じゃいごテックのあつしです。
今回は自作メソッドの定義と呼び出しについてご紹介します。

プログラミングでは繰り返し処理や条件分岐を組み合わせて処理を書いていきますが、ある纏まった処理を使いまわしたい場合があります。

そのようなときに処理を事前に定義しておくことで、いつでも呼び出せるようになり便利です。また、処理を小分けにすることで、デバッグも楽になります。

Rubyでは「メソッドを定義する」と言いますが、他のプログラミング言語では「関数を定義する」と言われることもあります。

メソッドの定義と呼び出し

メソッドの定義方法

def メソッド名(仮引数 = 初期値)
  処理
  ・
  ・
  ・
  return 戻り値
end

def の後にメソッド名を記述して、 def ~ end の間に処理内容を記述し、メソッド名の後に (仮引数 = 初期値) を記述します。
引数と初期値を使わない場合、省略することが出来ます。
return があるとその後に処理が記述されていてもメソッドが終了し、戻り値を返します。 return が省略されている場合は、最後に評価された値が返ります。
※ 定義の方の引数を仮引数、呼び出しの引数を実引数といいます。

メソッドの呼び出し方法

メソッドを定義した行より後で メソッド名(実引数) で呼び出します。定義で仮引数が省略されている場合と初期値が設定されている場合は呼び出しの実引数を省略することが出来ます。

# 仮引数省略で定義できる

def say_hello
  return "Hello World!!"
end

p say_hello
# > "Hello World!!"
# return が無い場合は最後に評価された値が返る

def say_hola
  "Hello World!!"
  "Konnichiwa World!!"
  "Hola World!!"
end

p say_hola
# > "Hola World!!"
# return より後の処理は評価されない

def say_konnichiwa
  "Hello World!!"
  return "Konnichiwa World!!"
  "Hola World!!"
end

p say_konnichiwa
# > "Konnichiwa World!!"
# 引数ありの場合

def say_hello(name)
  "Hello, #{name}!!"
end

p say_hello("Hanako")
# > "Hello, Hanako!!"

# 仮引数が定義されているのに実引数を渡さないとエラー発生
p say_hello
# > ArgumentError (wrong number of arguments (given 0, expected 1))
# 仮引数に初期値を定義

def say_hello(name="Taro")
  "Hello, #{name}!!"
end

# 仮引数の初期値が定義されていれば実引数を省略してもエラーが出ない
p say_hello
# > "Hello, Taro!!"
# 複数の仮引数を定義(長方形の面積)

def rectangle_area(w, h)
  w * h
end

p rectangle_area(3, 8)
# > 24
メソッドを使ってpaiza練習問題を解いてみる
西暦の和暦変換 (paizaランク C 相当)

※ paiza レベルアップ問題集 日付セットより

問題:

西暦年y、月m、日付dが与えられるので、和暦の元号を表示してください。

和暦は、以下の条件を確認し、西暦から変換してください。

  • 明治は1912年7月29日まで
  • 大正は1912年7月30日から1926年12月24日まで
  • 昭和は1926年12月25日から1989年1月7日まで
  • 平成は1989年1月8日から2019年4月30日まで
  • 令和は2019年5月1日から

入力される値

整数y m dが次のように、スペース区切りで1行で入力されます。

y m d

期待する出力

G年m月d日

  • Gは"明治"、"大正"、"昭和"、"平成"、"令和"のいずれかの元号です。
  • 今回の問題では、元号のみで和暦年は表示しません。

条件

すべてのテストケースにおいて、以下の条件をみたします。

  • 1873≦y≦3000
  • 1≦m≦12
  • 1≦d≦31
  • 回答時点よりも未来の日付の元号が与えられた場合も「令和」として表示してください。
  • 西暦y年m月d日は、西暦1873年1月1日から、西暦3000年12月31日の間の有効な日付です。

入力例1
2019 5 1
出力例1
令和年5月1日

入力例2
1873 1 1
出力例2
明治年1月1日

ポイント

月・日が1桁のときは2桁になるように 0 で埋める 例: 5月 → 05 、1日 → 01

日付を yyyymmdd 8桁の整数型に変換すると比較できる 例: 20190430 < 20190501 → true

解答例:

# [解答例]

# 入力データを y, m, d の文字列に変換するメソッド
def get_ymd(input_line)
  input_line.split
end

# y, m, d を yyyymmdd 形式の日付の整数に変換するメソッド
def get_date(y, m, d)
  # 0埋めした2桁の月の文字列を作成
  if m.length < 2
    m = "0" + m
  end
  # 0埋めした2桁の日の文字列を作成
  if d.length < 2
    d = "0" + d
  end
  # 年、月、日の文字列を連結して整数型に変換して返す
  (y + m + d).to_i
end

# yyyymmdd 8桁での日付を与えると和暦の元号を返すメソッド
def get_era_name(date)
  if date <= 19120729
    "明治"
  elsif 19120730 <= date && date <= 19261224
    "大正"
  elsif 19261225 <= date && date <= 19890107
    "昭和"
  elsif 19890108 <= date && date <= 20190430
    "平成"
  else
    "令和"
  end
end

# 標準入力から y, m, d を取得する
y, m, d = get_ymd(gets)
# 8桁の年月日整数データを取得する
date = get_date(y, m, d)
# 元号を取得する
era_name = get_era_name(date)
# 元号年、月、日を出力する
puts "#{era_name}年#{m}月#{d}日"

今回のまとめ

  • まとまった処理を使いまわしたいときにメソッドを定義しておくといつでも呼び出せる
  • 最後に評価された値が戻り値で返る
  • 処理を小分けにすることが出来るのでデバッグしやすくなる
プログラムが小規模なうちはあまりメリットを感じませんが、paizaC級問題あたりからはメソッド定義を覚えておけば便利な場面が増えてくると思います!

【PR】Ruby学習でお世話になった本




【PR】アルゴリズム学習でお世話になった本


アルゴリズム関連の技術書は大抵C/C++で書かれていますが、ある程度プログラムが出来れば、処理の流れは理解することが出来ます。






通称: 螺旋本。C++で解説されています。AOJ(Aizu Online Judge)を運営している会津大学の渡辺准教授が書いた本です。データ構造や計算量の内容から丁寧に書いてありますのでアルゴリズム学習の最初の参考書としてオススメです。







通称: 蟻本。C++で解説されています。競技プログラミング中級者の定番書と言われていて、競技プログラミングで利用できる色々なアルゴリズムを学ぶことが出来ます。かなり高度な内容も含まれているので1冊分を完全に理解するのにはかなりの時間がかかりそうですが、手元に置いて何度も読み返しています。







通称: チーター本。C#, C++, JAVAでTopcoderの問題を解説しています。初心者~中級者向けに書かれているので解説が非常に丁寧です。







Python3でアルゴリズムを解説している本です。講義スタイルの本で、図やフローチャートを使ってアルゴリズムとデータ構造についてしっかりと説明されています。代わりにコードは少なめです。Pythonコードが読めなくても十分理解できると思います。


-Ruby, プログラミング
-,

© 2024 じゃいごテック