【Ruby】メソッドの基本について

スポンサーリンク

Rubyのメソッドの基本についてです。ブロック付きメソッドも一緒にまとめたかったのですが、分量が多くなってしまいましたので、また別記事にしたいと思います。

メソッドの定義

メソッド定義の構文は次の通りです。メソッド名は数字で初めてはいけません。大文字で始める事は出来ますが、小文字で始めるのが一般的です。

def メソッド名(引数1, 引数2, ...)
    実行する処理
end

メソッドの呼び出し

メソッドの呼び出し方は次の通りです。

オブジェクト.メソッド名(引数1, 引数2, ...)

オブジェクトはレシーバとも呼ばれます。引数の数と順番はメソッドに合わせて指定します。引数の括弧「( )」は省略可能ですが、引数がある場合は括弧を記述し、ない場合は括弧を省略するのが一般的なようです。Javaに慣れてる身としては括弧を省略しない方がわかりやすいのですが慣れるしかないですね。

同じクラス内のメソッド呼び出しの場合は次の通りです。

class Test
    def hoge
        fuga(引数1, 引数2, ...)
    end
    def fuga(引数1, 引数2, ...)
        ...
    end
end

ただし、このようにレシーバを省略している場合は、暗黙的にselfがレシーバとなっています。selfとはメソッドのレシーバ自身を参照するため、hogeメソッドを呼び出したレシーバの事を指しています。

デフォルト引数

引数にはdef hoge(a=10)のように「=」を使ってデフォルト値を指定することができます。こうすることで引数を省略してメソッドを呼び出した場合は、デフォルト値が使われるようになります。

また、複数の引数がある場合、デフォルト値は右側の引数から指定します。1番目の引数だけや、途中の引数だけデフォルト値を指定するということはできません。

def hoge(a, b=10)
    puts a + b
end
hoge(10)
#=>20

可変長引数

引数の数が不特定な場合、「*変数名」の形式で定義します。

def hoge(a, *b)
    p a
    p b
end
hoge(1,2,3,4,5,6)
#=>1
#  [2, 3, 4, 5, 6]

こうすることで最初の引数1を除いて b には配列として格納されます。可変長引数は引数の中に1つだけ含める事ができます。def hoge(*a, *b)こういうことはできません。

キーワード引数

メソッドの呼び出し時、引数の順番はメソッドの定義と合わせる必要がありますが、キーと値のペアで渡せるようになります。

def hoge(a: 0, b: 1, c: 2)
    p a * b * c
end
hoge(c: 5, a: 2, b: 10)
#=>100

引数にはデフォルト値を指定しておく必要がありますが、引数を省略したり、順番は関係なく呼び出す事が可能です。ただし、当然定義されていない引数を指定した場合はエラーになります。

定義されていない引数を受け取りたい場合は、「**変数名」の形式で定義します。そうすると引数リストに存在しないキーは変数名にハッシュオブジェクトの形式で格納されます。この時のキーはシンボルです。

def hoge(a: 0, b: 1, c: 2, **args)
    p args
end
hoge(c: 5, a: 2, b: 10, x: 100, y: 50)
#=>{:x=>100, :y=>50}

ハッシュで引数を渡す事もできます。

args = {c: 5, a: 2, b: 10, x: 100, y: 50}
hoge(args)

メソッドの戻り値

メソッドの戻り値を指定したい時はreturn文を使用します。return文を省略した場合は、メソッドの中で最後に得られる値が戻り値となります。また、returnの引数を省略した場合(returnのみ記述)は、nilが返されます。

メソッドの種類

Rubyのメソッドはレシーバによって以下の3種類に分類されます。

  • インスタンスメソッド
  • クラスメソッド
  • 関数的メソッド

インスタンスメソッド

オブジェクト (インスタンス) をレシーバとするメソッドのことです。クラスの中にメソッドを定義すると、基本的にそのクラスのインスタンスメソッドとなります。

class Test
    def name
    ....
end
test = Test.new  # インスタンスを生成
test.name("bar")  # 生成したインスタンスのメソッド呼び出し

例えば100.to_sという処理に関しては、100というIntegerクラスのオブジェクトから to_s メソッドを呼び出していることになります。

クラスメソッド

レシーバがインスタンスではなくクラスそのものであるメソッドのことです。

Array.new  # new が Arrayクラスのクラスメソッド

クラスメソッドを呼び出すときに、「 . 」の代わりに「 :: 」を使うこともできます。その代わり気を付けないといけないのが、【Ruby】変数と定数についてでもでてきた定数です。

定数のアクセスについても「 :: 」を使用するため、もし1文字目が大文字のメソッドを呼び出そうとした場合、定数とみなされてしまいます。その場合は明示的にメソッドであると表すため、Test::Count()のように括弧を付ける必要があります。

ただそれ以前にメソッドは小文字で始めるという暗黙のルールもありますから、従っていれば問題はないですね。

関数的メソッド

レシーバがないメソッドのことを関数的メソッドと呼びます。

print "test"
sleep(30)

これらのメソッドはKernelモジュールで定義されています。という事は、ObjectクラスはKernelモジュールをインクルードしているため、全てのクラスから参照できるメソッドということになります。そのため、最初にも述べましたが、レシーバが省略されているメソッドは self がレシーバとなるため、レシーバがなくても呼び出せるということです。(これ想像なんで違ってたらすみません)

alias

既に存在するメソッド、グローバル変数に別名をつけます。unixコマンドの alias と同じ感じです。メソッドの場合は引数にシンボルも指定できます。

alias 別名 元の名前
alias :別名 :元の名前

undif

定義されたメソッド定義をなかったことにします。

undif メソッド名
undif :メソッド名

defined?

式が定義されていなければ、偽を返します。定義されていれば式の種別 を表す文字列を返します。undifされたメソッドは偽を返します。

defined?