[鼠年全馬鐵人挑戰22]為自己學Ruby on Rails [05- 類別vs實體及一推變數們]
|前言|
我們都知道Ruby是一個物件導向很測底的語言吧!常常在Ruby裡面看到很多人在講類別及實體的差別,以及Ruby常用的一些變數用法,那類別(class )其實就是模具,我們丟相同的材料進去,做出來的東西照理來說都一樣,而實體 (instance)就是那個模具做出來的東西。
1 |類別 (class)
class 類別的名字(通常是常數,字首大寫英文字母)
#...
end
- 類別名通常是常數,字首為大寫英文字母
- 有了 類別之後,就可以用這個類別的
new
方法來產生實體 - 如果兩個物件都是用同個類別做出來的,就可以有相同的方法
class Puppy
def eat(food)
puts "#{food} 太美味了吧~"
end
endCindy = Puppy.new
Cindy.eat "牛奶~" #=> 印出「牛奶~太美味了吧~」
Molly = Puppy.new
Molly.eat "罐罐~" #=> 印出「罐罐~太美味了吧~」
上方用Puppy
類別做了兩個不同的實體 Cindy
跟 Molly
,這兩個物件因為都是用 Puppy
類別做出來的,所以都有 eat
方法
常數 (Constant)
1. 大寫英文開頭
2. 覆寫會報警告,但是還是會被覆蓋
3. 任何model、class、module的名稱都是常數
2 |初始化 (initialize)
class 類別的名字
def initialize(參數1,參數2)
#...
end
end
- 想要透過
new
方法傳參數進來,在類別裡面就用initialize
的方法來接收傳進來的參數 initialize
常見的手法是會把參數傳進來給內部的實體變數(instance variable)
class Hello
def initialize(greet, name)
@greet = greet
@name = name
end
def morning
puts "#{@greet}, my name is #{@name}"
end
end
Sandra = Hello.new("Good morning", "Sandra~")
Sandra.morning # => Good morning, my name is Sandra~
先用實體變數做一個盒子@greet
跟@name
,之後參數就可以往裡面丟,然後設定呼叫時傳入的參數,就可以在預設的地方抓出對的參數#{@greet}、#{@name}
initialize
永遠是 private 的,只會被new
方法呼叫
3 |實體變數(instance variable)
- 前面加了 @ 符號的變數,沒有預設值
- 每個實體變數之間互不相影響
- 可以在同一個class的各種method之間互相傳遞
- 最常用的地方是 Controller 與 View 之間的溝通
- Ruby 的實體變數沒辦法直接從外部取用,要取用實體變數,需要另外定義的方法
class PostsController < ApplicationController
def index
@posts = Post.all # 取得所有的 Post 資料
end
end
=>這是一個Controller
設定取得所有Post的資料
class Hello
def initialize(greet, name)
@greet = greet
@name = name
end
def morning
puts "#{@greet}, my name is #{@name}"
end def name
@name
end def name=(new_name)
@name = new_name
endend
Sandra = Hello.new("Good morning", "Sandra~")
Sandra.morning # => Good morning, my name is Sandra~Sandra.name = "Ivy"
puts Sandra.name # => 新名字就會變成Ivy
=>這裡定義的 name
以及 name=
方法(等號也是方法的一部份)就是負責回傳及設定 @name
這個實體變數
class Hello
attr_accessor :name #讀取 + 設定
def initialize(greet, name)
@greet = greet
@name = name
end def morning
puts "#{@greet}, my name is #{@name}"
end
end
=>可使用 attr_accessor
改寫成這樣,即「讀取 + 設定」的方法
4 |實體方法(instance method)VS 類別方法(class method)
- 字面翻譯就是,作用在實體上的方法,以及作用在類別上的方法(一整個有講跟沒講一樣,直接看範例吧~)
Sandra = Hello.new("Good morning", "Sandra~")
Sandra.morning
=> morning
作用在Sandra
上面,所以morning
是實體方法
class PostsController < ApplicationController
def index
@posts = Post.all # 取得所有的 Post 資料
end
end
=>這裡的 all
是直接作用在 Post
這個「類別」上,所以就稱它為類別方法
2. 類別方法有幾種寫法,其中一種比較簡單的,就是在前面加上 self
class Cat
def self.all
# ...
end
end#當一個類別裡面有很多類別方法的時候,不需要在每個前面加上self
class Cat
class << self
def all
# ...
end
end
end
5 |類別變數
- 前面加了 @@ 符號
- 存在於類別裡面的變數
@@name
@@count
6 | 全域變數 (global variable)
- 前面加了$符號的變數
- 盡量少用,因為全域變數能夠編寫於任何地方,所以相對危險
- 指定一個描述性名稱 (descriptive name),以防之後重複使用
- 優點就是能夠追蹤,每當變數的值改變後,你都能夠指出呼叫出
trace_var :$x, Proc.new { puts “$x is now #{$x}” }$x = 5 # =>$x is now 5
7 | 區域變數 (local variable)
- 非大寫字母開頭的名字或 _開頭
- 不需要先宣告,沒有預設值,Ruby會自動指定一個nil值給他
- 有效範圍:class、module、def或do end {}
- 沒辦法跨method使用
def create_lv
local_var #=> "區域變數無法在方法外被提取"
@instance_var #=> "可以被任意提取"
endputs local_var #=> error:undefined local variable
puts @instance_var #=> get @instance_var in create_lv
|後記|
今天把類別及實體的一些觀念釐清後,更能清楚了解Ruby在寫的時候要注意的寫法,另外變數們也有很多觀念,例如$、@@、@、區域變數、常數(區域變數、常數須先宣告,其餘不用),讓我可以提升自己在看code時的速度~~