Ruby 入門

Ruby メソッド (Methods)

メソッドのディファインとコールは、Ruby プログラミングにおけるベーシックなコンセプトであり、コードを高効率にオーガナイズし、リユース(再利用)することを可能にします。メソッドのディファイン、パラメータのパッシング、およびリターン値のハンドリングを理解することは、ウェルストラクチャード(適切に構造化された)でメンテナブル(保守性が高い)な Ruby プログラムを記述する上で非常に有効です。

本章ではメソッドの各ディテールについて深く探求し、カスタマイズされたリユーザブルなコードブロックをクリエイトするために必要なナレッジとスキルを提供します。

1. メソッドのディファイン

Ruby において、メソッド (Method) は特定のタスクをエグゼキュート(実行)するためのコードブロックです。私たちは def キーワードをユースしてメソッドをディファインし、それに続いてメソッド名、括弧内のオプショナルなパラメータ、そして最後に end キーワードをユースしてメソッドのディファインの終了をマークします。

def greet(name)  # 'greet' という名前のメソッドをディファインし、'name' というパラメータをレシーブする
  puts "こんにちは、#{name}!" # その名前を含んだ挨拶をプリント(出力)する
end # メソッドのディファインの終了

上記のサンプルにおいて:

  • def greet(name):この行は greet という名前のメソッドをディファインしています。これは name というパラメータをレシーブします。
  • puts "こんにちは、#{name}!":これはメソッドのボディです。ストリング・インターポレーション(文字列展開)のテクノロジーをユースして、name の値を挨拶文にインサートしています。
  • end:このキーワードはメソッドのディファインの終了をマークします。

2. メソッドのネーミング・コンベンション

Ruby におけるメソッド名はディスクリプティブ(記述的)であるべきであり、以下のコンベンション(規約)に従う必要があります:

  • ロウワーケース(小文字)をユースする。
  • ワード間はアンダースコアでセパレートする(すなわちスネークケース snake_case)。
  • メソッドのファンクション(機能)をクリアに表すネームをセレクトする。

いくつかの優れたメソッド名のサンプル:

  • calculate_area
  • get_user_name
  • is_valid_email

3. パラメータなしのメソッド

メソッドは、いかなるパラメータもレシーブしないステータスでディファインすることも可能です。

def say_hello # 'say_hello' という名前のメソッドをディファインし、パラメータは何もレシーブしない
  puts "こんにちは!" # 挨拶をプリントする
end # メソッドのディファインの終了

4. メソッドのコール

メソッドをエグゼキュートするには、そのネームを通じてそれを「コール (Call)」する必要があり、通常は後に括弧が続きます。もしそのメソッドがパラメータをレシーブする必要がある場合、括弧内にこれらのパラメータをプロバイドしなければなりません。

4.1 ベーシックなコール

greet("Alice") # パラメータ "Alice" をパッシングして 'greet' メソッドをコールする
# アウトプット: こんにちは、Alice!

say_hello() # パラメータをパッシングせずに 'say_hello' メソッドをコールする
# アウトプット: こんにちは!

say_hello # メソッドがパラメータをレシーブしない場合、コール時に括弧を省略することも完全にアクセプタブル(許容可能)です
# アウトプット: こんにちは!

4.2 パラメータをパッシングするコール

パラメータを持つメソッドをコールする際は、メソッドのディファインで規定された正しい数量とデータタイプのパラメータを確実にプロバイドしてください。

def add(x, y) # 'add' メソッドをディファインし、x と y の2つのパラメータをレシーブする
  puts x + y # これら2つのパラメータのサム(合計)をプリントする
end # メソッドのディファインの終了

add(5, 3) # パラメータ 5 と 3 をパッシングして 'add' メソッドをコールする
# アウトプット: 8

5. メソッドのリターン値

5.1 インプリシット・リターン (Implicit Return)

Ruby において、メソッド内で最後にエバリュエート(評価)されたエクスプレッション(式)の値はインプリシット(暗黙的)にリターンされます。メソッドの途中からアーリーリターン(早期リターン)したい場合を除き、エクスプリシット(明示的)に return キーワードをユースする必要はありません。

def multiply(x, y) # 'multiply' メソッドをディファインし、x と y の2つのパラメータをレシーブする
  x * y # x と y の積をインプリシット・リターンする
end # メソッドのディファインの終了

result = multiply(4, 6) # 'multiply' メソッドをコールし、そのリザルトを 'result' バリアブル(変数)にストアする
puts result # result の値をプリントする
# アウトプット: 24

このサンプルにおいて、multiply メソッドは x * y のコンピューテーション(計算)のリザルトをインプリシット・リターンしています。

5.2 エクスプリシット・リターン (Explicit Return)

return キーワードをユースしてメソッドのリターン値をエクスプリシットに指定したり、メソッドをアーリーエグジット(早期退出)するためにユースしたりすることができます。

def divide(x, y) # 'divide' メソッドをディファインし、x と y の2つのパラメータをレシーブする
  return "ゼロで除算することはできません" if y == 0 # y が 0 の場合、エラーメッセージをリターンする(アーリーエグジット)
  x / y # y が 0 でない場合、x を y で除算した商をリターンする
end # メソッドのディファインの終了

puts divide(10, 2) # 10 と 2 をパッシングして divide をコールする
# アウトプット: 5

puts divide(8, 0) # 8 と 0 をパッシングして divide をコールする
# アウトプット: ゼロで除算することはできません

このサンプルにおいて、もし y0 と等しい場合、メソッドは return キーワードをユースしてストリング "ゼロで除算することはできません" をエクスプリシット・リターンし、ランを終了します。そうでない場合はエグゼキュートを継続し、x / y のリザルトをリターンします。

6. メソッドのパラメータ(アドバンスド)

メソッドはパラメータ(すなわちメソッドのコール時にパッシングされる値)をレシーブし、リターン値(すなわちメソッドがエグゼキュートされたリザルト)をリターンすることができます。パラメータとリターン値をフレキシブルに運用する方法を理解することは、ハイ・アダプタビリティ(高適応性)かつハイ・リユーザビリティ(高再利用性)を持つメソッドをクリエイトするためのキーとなります。

6.1 デフォルト・パラメータ

メソッドのパラメータに対してデフォルト値を指定することができます。コーラー(呼び出し元)がデフォルト値を持つパラメータに対して実際のアクチュアル・バリュー(実測値)をプロバイドしなかった場合、プログラムはこのデフォルト値をユースします。

def greet(name = "ゲスト") # 'greet' メソッドをディファインし、オプショナルなパラメータ 'name' をレシーブする(デフォルト値は "ゲスト")
  puts "こんにちは、#{name}!" # 名前を含んだ挨拶をプリントする
end # メソッドのディファインの終了

greet("Bob") # パラメータ "Bob" をパッシングして 'greet' メソッドをコールする
# アウトプット: こんにちは、Bob!

greet # いかなるパラメータもパッシングせずに 'greet' メソッドをコールする
# アウトプット: こんにちは、ゲスト!

このサンプルにおいて、name パラメータはデフォルト値 "ゲスト" を持っています。いかなるパラメータもプロバイドせずに greet メソッドをコールした際、name の値は自動的に "ゲスト" をアダプトします。

6.2 バリアブル・レングス・パラメータ (*args)

Ruby は *args(アスタリスク・シンタックス)をユースして、バリアブル・レングス(可変長)のパラメータをレシーブするメソッドをディファインすることを許可します。メソッドにいくつのパラメータがパッシングされるかを事前にプレディクト(予測)できない場合に、これは非常に有用です。

def sum(*numbers) # 'sum' メソッドをディファインし、パッシングされた可変長のパラメータを 'numbers' というアレイ(配列)としてコレクトする
  total = 0 # 'total' バリアブルを 0 にイニシャライズ(初期化)する
  numbers.each { |number| total += number } # 'numbers' アレイをトラバース(走査)し、各ナンバーを 'total' バリアブルにアキュムレート(累積)する
  total # 'total' のファイナル・バリュー(最終値)をリターンする
end # メソッドのディファインの終了

puts sum(1, 2, 3) # パラメータ 1, 2, 3 をパッシングして 'sum' メソッドをコールする
# アウトプット: 6

puts sum(4, 5, 6, 7) # パラメータ 4, 5, 6, 7 をパッシングして 'sum' メソッドをコールする
# アウトプット: 22

このサンプルにおいて、sum メソッドは任意のパラメーター数をレシーブできます。*numbers パラメータは、パッシングされたすべての値を numbers という名のアレイにコレクトします。その後、メソッドはこのアレイをトラバースし、ナンバーのサムをコンピュートします。

6.3 キーワード・パラメータ

キーワード・パラメータは、「キーバリュー・ペア (key-value pair)」のシンタックスをユースしてメソッドにパラメータをパッシングすることを許可します。これによりコードのリーダビリティが大幅に向上するだけでなく、メソッドが多数のオプショナル・パラメータを持つ場合に特に有効に機能します。

def create_user(name:, age:, city: "未定義") # 'create_user' メソッドをディファインし、キーワード・パラメータ 'name', 'age'、およびデフォルト値 "未定義" を持つオプショナルなキーワード・パラメータ 'city' をレシーブする
  puts "ネーム: #{name}, 年齢: #{age}, シティ: #{city}" # ユーザーインフォメーションをプリントする
end # メソッドのディファインの終了

create_user(name: "Charlie", age: 30, city: "ニューヨーク") # すべてのキーワード・パラメータをユースして 'create_user' メソッドをコールする
# アウトプット: ネーム: Charlie, 年齢: 30, シティ: ニューヨーク

create_user(name: "Diana", age: 25) # 'name' と 'age' キーワード・パラメータのみをユースして 'create_user' メソッドをコールする
# アウトプット: ネーム: Diana, 年齢: 25, シティ: 未定義

このサンプルにおいて、create_usernameage、および city をキーワード・パラメータとしてレシーブします。その中で city はデフォルト値 "未定義" を持っています。メソッドをコールする際、キー: バリュー のフォーマットに従っていれば、任意の順序でパラメータを指定することが可能です。

7. 実践デモンストレーション

より実践的な意義を持ついくつかのサンプルを通じて、理解をコンソリデート(強固に)していきましょう。

7.1 レクタングル(矩形)のエリア(面積)をコンピュートする

def calculate_rectangle_area(length, width) # 'calculate_rectangle_area' メソッドをディファインし、パラメータ 'length' (長さ) と 'width' (幅) をレシーブする
  length * width # 長さと幅の積、すなわちレクタングルのエリアをリターンする
end # メソッドのディファインの終了

area = calculate_rectangle_area(10, 5) # パラメータ 10 と 5 をパッシングして該当メソッドをコールし、リザルトをバリアブル 'area' にストアする
puts "レクタングルのエリアは: #{area} です" # レクタングルのエリアをプリントする
# アウトプット: レクタングルのエリアは: 50 です

7.2 ナンバーが偶数であるかチェックする

def is_even?(number) # 'is_even?' メソッドをディファインし、1つのパラメータ 'number' をレシーブする
  number % 2 == 0 # ナンバーが偶数(2で完全に除算可能で剰余がない)の場合は true をリターンし、そうでない場合は false をリターンする
end # メソッドのディファインの終了

puts is_even?(4) # 4 をパッシングして 'is_even?' メソッドをコールする
# アウトプット: true

puts is_even?(7) # 7 をパッシングして 'is_even?' メソッドをコールする
# アウトプット: false

7.3 ストリングのフォーマッティング

def format_string(string, uppercase: false, reverse: false) # 'format_string' メソッドをディファインし、1つのストリング・パラメータと、デフォルト値が false である2つのオプショナルなキーワード・パラメータをレシーブする
  string = string.upcase if uppercase # 'uppercase' パラメータが true の場合、ストリングをアッパーケース(大文字)にコンバートする
  string = string.reverse if reverse # 'reverse' パラメータが true の場合、ストリングをリバース(反転)させる
  string # モディファイ(変更)されたストリングをリターンする
end # メソッドのディファインの終了

puts format_string("hello", uppercase: true) # "hello" をパッシングし、'uppercase' を true にセットして該当メソッドをコールする
# アウトプット: HELLO

puts format_string("world", reverse: true) # "world" をパッシングし、'reverse' を true にセットして該当メソッドをコールする
# アウトプット: dlrow

puts format_string("ruby", uppercase: true, reverse: true) # "ruby" をパッシングし、両方を true にセットして該当メソッドをコールする
# アウトプット: YBUR