3.メソッドとプロパティ
1.メソッド
メソッドとは、各オブジェクトが自身を操作するために定義された処理のことです。
メソッドを実行することをメソッドを呼び出すといい、呼び出し元のオブジェクトをレシーバといいます。
メソッドの呼び出しは、必ずレシーバ.メソッド名(引数)という形になります。

レシーバとは、現在の処理の実行主体です。
レシーバを参照するためには、擬似変数selfを使用します。
もし、このレシーバが self であるなら、レシーバの記述を省略することができます。

メソッドが呼び出され処理が終わると、そのメソッドは値を返します。これを戻り値といいます。
戻り値は、return 文を使用することで指定することができますが、
明示的に指定しなかった場合は、最後に実行された式の値が使用されます。

命名の習慣として、サフィックス(接尾語)に真偽値を返すメソッドには疑問符
破壊的なメソッドには感嘆符を付けることになっています。
感嘆符に関しては、必ずそうなっているわけではなく、破壊的なメソッドでも付いていなかったり、
注意を促すために破壊的ではないメソッドにも使われています。
破壊的なメソッドとは、オブジェクト自身を変更する作用をもつメソッドのことです。
2.インスタンスメソッド
クラスに定義されたメソッドをインスタンスメソッドといいます。
このクラスのインスタンスから呼び出して使用します。
通常、メソッドというと、このインスタンスメソッドを指します。
class Hoge
  def method
    "instance method"
  end
end

hoge = Hoge.new
hoge.method   # => "instance method"

トップレベルに定義されたメソッドをグローバルメソッドといいます。
このメソッドは、Object クラスにプライベートメソッドとして定義されます。
そのため、すべてのオブジェクトから関数形式(レシーバを省略)で呼び出すことができます。
def method
  "global method"
end
class Hoge
  def test
    method
  end
end

hoge = Hoge.new
method        # => "global method"
hoge.test     # => "global method"
hoge.method   # => ERROR
3.特異メソッド
クラスではなく、特定のオブジェクトに定義されたメソッドを特異メソッドといいます。
class Hoge
end

hoge = Hoge.new
class << hoge
  def aaa
    "aaa"
  end
end
def hoge.bbb
  "bbb"
end

fuga = Hoge.new
hoge.aaa   # => "aaa"
hoge.bbb   # => "bbb"
fuga.aaa   # => ERROR

クラスオブジェクトに定義された特異メソッドをクラスメソッドといいます。
class Hoge
  def self.aaa
    "aaa"
  end
end
class << Hoge
  def bbb
    "bbb"
  end
end
def Hoge.ccc
  "ccc"
end

Hoge.aaa   # => "aaa"
Hoge.bbb   # => "bbb"
Hoge.ccc   # => "ccc"

プライベートメソッドであり、モジュールの特異メソッドでもあるようなメソッドをモジュール関数といいます。
実際には、この2つの同名のメソッドが定義されています。
module Moge
  module_function
  def aaa
    "aaa"
  end
end
include Moge

Moge.aaa   # => "aaa"
aaa        # => "aaa"
self.aaa   # => ERROR
4.引数
メソッドを定義するときに一緒に引数も定義することがあります。
def method(arg)
  arg
end
この括弧内に書かれたものが引数です。この引数を仮引数といいます。
method(3) # => 3
このようにメソッド呼び出しの際に記述する引数を実引数といいます。

引数は複数定義する事もでき、その場合はカンマ(,)で区切ります。
def method(arg1, arg2)
  arg1 + arg2
end
method(3, 2)  # => 5
引数にはデフォルト値を設定する事もできます。このとき、実引数を省略する事ができます。
def method(arg = 1)
  arg
end
method      # => 1
method(3)   # => 3
ヘルプなんかでよく見かける (arg1[, arg2]) などの[]という記述は、省略可能なことを表します。
arg2 という引数には、デフォルト値が設定されているので、省略できますということです。

メソッド内でオブジェクトに変更を加えると、呼び出し元の値も変更されることがあります。
def method(a, b)
  a[0] = 3
  b = 5
end

a = [0, 1, 2]
b = 1
method(a, b)
p a, b  # => [3, 1, 2] と 1
これは、変数に代入されているものがオブジェクトの参照だからです。
オブジェクト自身でもなく、オブジェクトのコピーでもありません。
メソッドの引数に変数を指定すると、このオブジェクトの参照が値渡しされます。
渡されるのがオブジェクトの参照のため、メソッド内でオブジェクトを書き換えると、
呼び出し元のものも変更されます。引数が参照渡しだからではありません。
3.プロパティ(属性)
オブジェクトが保持するデータ(インスタンス変数)を外部から変数のように操作するためのメソッドです。
このインスタンス変数を外部から参照や代入を行うメソッドを総称してアクセサメソッドといいます。
また、参照のみを行うメソッドをゲッターメソッド、代入のみを行うメソッドをセッターメソッドといいます。
# getter メソッド
def get
  @variable
end
# setter メソッド
def set=(value)
  @variable = value
end

# getter メソッド
attr_reader   :variable
# setter メソッド
attr_writer   :variable
# getter と setter の両方
attr_accessor :variable
これらは、どれも同じ定義を行います。
上記のように variable と variable= の2つのメソッドを持つとき、プロパティ variable を持っているといいます。

実際の使用例は次のようになります。
class Human
  attr_reader   :gender
  attr_accessor :family_name
  attr_accessor :first_name
  def initialize(family, first, gender)
    @family_name = family # 名字
    @first_name = first   # 名前
    @gender = gender      # 性別
  end
  def name
    return @family_name + " " + @first_name
  end
end

taro = Human.new("山田", "太郎", :man)
hana = Human.new("佐藤", "花子", :woman)
p hana.family_name        # "佐藤"
hana.family_name = taro.family_name
p hana.family_name        # "山田"
fson = Human.new(taro.family_name, "一郎", :man)
p fson.gender             # :man
fson.gender = :woman      # ERROR
定義時にプロパティを使用する場合は、ローカル変数との混同を避けるためselfを明示します。
class Hoge
  attr_reader :property
  def hoge
    self.property = 3   # セッターメソッド
    property = 6        # ローカル変数
  end
end

class Human
  def name
    return self.family_name + " " + self.first_name
  end
end
4.今回のポイント
・メソッドとは、オブジェクト自身を操作する処理である。
・プロパティとは、オブジェクトが保有する情報を外部から取得できるようにしたメソッドである。
・変数には、オブジェクトの参照が代入される。
・メソッドの引数は、参照渡しではなく、値渡し。