在 Ruby 裡的實體變數是有一個 @ 開頭的變數,顧名思義,是活在每個實體裡的變數,而且每個實體之間互不相影響。
前面這個範例來說,@name 跟 @gender 就是實體變數。
在 Rails 專案中,實體變數使用的頻率很高,最常用的地方應該是 Controller 與 View 之間的溝通,隨便舉一個 Controller 為例:
class PostsController < ApplicationController
def index
@posts = Post.all # 取得所有的 Post 資料
end
end
Ruby 的實體變數沒辦法直接從外部取用,像這樣直接取用會發生錯誤訊息:
kitty = Cat.new("kitty", "female")
kitty.name = "nancy" # 這會發生錯誤
puts kitty.name # 這也會發生錯誤
因為 Ruby 並沒有「屬性」(property/attribute)這樣的設計,要取用實體變數,需要另外定義的方法才行:
class Cat
def initialize(name, gender)
@name = name
@gender = gender
end
def say_hello
puts "hello, my name is #{@name}"
end
def name
@name
end
def name=(new_name)
@name = new_name
end
end
kitty = Cat.new("kitty", "female")
kitty.name = "nancy"
puts kitty.name # => nancy
這裡定義的 name 以及 name= 方法(是的,你沒看錯,等號 = 也是方法的一部份)就是負責回傳及設定 @name 這個實體變數的。
也許你會想,每次要這樣取用或設定實體變數的值都要這麼麻煩嗎?還好,Ruby 有幫我們定義了三個方法來解決這件事,分別是 attr_reader、attr_writer 以及 attr_accessor。這三個方法分別會做出「讀取」、「設定」以及「讀取 + 設定」的方法,所以原來的有點囉嗦的寫法就可使用 attr_accessor 改寫成這樣:
class Cat
attr_accessor :name
def initialize(name, gender)
@name = name
@gender = gender
end
def say_hello
puts "hello, my name is #{@name}"
end
end
[為你自己學Ruby on Rails]https://railsbook.tw/chapters/08-ruby-basic-4.html