##改訂履歴
- タイトル変更:タイトルを「特別な変数selfについて(覚書)」にしました。
- self(クラス)について頂戴したコメントと参考書を参考しながら加筆・修正しました。
- self(インスタンス)について頂戴したコメントと参考書を参考しながら修正しました。
##self(クラス)
- クラスメソッドはクラスそのもの(クラスオブジェクト)をレシーバとするメソッド。
- クラスメソッドは
class << クラス名 ~ end
という特殊なクラス定義の中にインスタンスメソッドの形式で定義する。
class << HelloWorld
def hello(name)
puts "#{name} said hello"
end
end
HelloWorld.hello("John")
#=> "John said hello"
上記の方法ではなくクラス定義の中でクラスメソッドを追加することもできる。
クラス文の中のselfはそのクラス自身を参照するので次のようにclass << self ~ end
として
その中にメソッドを記述する。こちらの方法が一般的に使われている。
class HelloWorld
class << self
def hello(name)
p "#{name} said hello"
end
end
end
HelloWorld.hello("John")
#=> "John said hello"
また、class << self ~ end
を使わずにdef クラス名.メソッド名 ~ end
の形式で
クラスメソッドを定義することもできる。
class HelloWorld
def HelloWorld.hello(name)
p "#{name} said hello"
end
end
HelloWorld.hello("John")
#=> "John said hello"
上記形式の場合もselfを使って次のように書くことができる。
class HelloWorld
def self.hello(name)
p "#{name} said hello"
end
end
HelloWorld.hello("John")
#=> "John said hello"
###特異クラス
class << self ~ end
という書き方のクラス定義を「特異クラス定義」という。
また、特異クラス定義で定義したメソッドを特異メソッドという。
##self(インスタンス)
1. selfはインスタンスメソッド内で使用するとそのメソッドを呼び出している**「インスタンス」**の事を指す。
2. 他のインスタンスメソッドを呼び出したい時にselfを使う
インスタンスメソッドの中で、メソッドのレシーバ自身を参照するには「self」を使う。
アクセスメソッドで作成したcolorメソッドを「別のインスタンスメソッドから呼ぶ」ことを以下で考えてみる。
class Car
attr_accessor :name,:color
def initialize(name,color)
@name = name
@color = color
end
def put_color
puts "車の色は#{self.color}です" #このselfはCarインスタンスを指す。
end
end
car = Car.new("vezel","black")
car.put_color
# => 車の色はblackです
put_colorメソッドで利用している「self.name」はput_colorメソッドを呼んだ時の「レシーバ」を参照している。また、レシーバを省略してメソッドを呼ぶと暗黙にselfをレシーバとする。
そのため、次のようにselfを省略してもcolorメソッドが呼ばれることになる。
class Car
attr_accessor :name,:color
def initialize(name,color)
@name = name
@color = color
end
def put_color
puts "車の色は#{color}です" #selfを省略しているがメソッドを呼ぶ時に暗黙にselfをレシーバとしてくれている
end
end
car = Car.new("vezel","black")
car.put_color
#結果: 車の色はblackです