Rails新手易混淆的變數使用


對Rails新手來說,常常碰到各種莫名其妙的變數型態,而且只要閱讀高階開發者的程式碼,超容易被各種符號搞得暈頭轉向。本篇簡單介紹各種在新手接觸Rails時會碰到的變數型態,以及分別代表什麼意義。

local variable 區域變數

這沒什麼好說的,就只是一般的變數,如果是從其他語言跳來的朋友,記得Ruby的local variable並不需要先宣告才能使用。不過在呼叫時,如果是完全沒有提及過的變數,就會產生錯誤。例如:

number = 10

number
# => 10

所以在Ruby當中,使用變數前並不用先宣告。唯一需要注意的是在進行數值比較或變數指定變數時,也就是在『使用』時,必須要先宣告:

a = b
# => NameError: undefined local variable "b"

if a == b
    a = 10
end
# => NameError: undefined local variable "b"

c
# => NameError: undefined local variable "c"

記得使用先務必要先指定一個值。

@ instance variable 實例變數

說實在,我永遠記不得這中文名字,因為大家學Ruby非得閱讀英文資料,久而久之知道有個東西叫instance variable,卻永遠不知道中文叫什麼。

instance variable代表的是可以在同一個class的各種method之間互相傳遞,出現時前面會加上@符號,在學習Rails時一開始就一定會碰到。例如Xdite的Rails 101當中(在此使用線上版的Rails 101 S當作範本),建立controller的第一步index當中一定會看到:

def index
    @groups = Group.all
end

為啥要加上@呢?為什麼不能使用一般變數就好?因為只有這樣設定,才能夠把變數傳到view當中:

# group controller
def index
    @groups = Group.all
    groups = Group.all
end

在View當中撰寫:

<%= @group %>
# => 顯示所有groups

<%= group %>
# => 錯誤:NoMethodError

又例如像前一篇文章在建立service object時,會在initialize裡面定義好一個要使用的變數,這樣所有的method當中都可以使用。

class Service
    def initialize(value)
        @value = value
    end

    def plus_one
        @value + 1
    end
end

Service.new(2).plus_one
# => 3

像local variable就沒辦法跨method使用,instance variable才可以。另外,如果沒有先宣告過的instance variable直接使用,Ruby會自動套用給他一個nil值,這點和local variable就非常不同。

@variable
# => nil

3. : 符號 Symbol

符號並不是一個變數,但也是新手學習Rails時會有疑惑的部分。例如在一般show action中,都會指定一個要顯示的物件給變數:

def show
    post = Post.find(params[:id])
end

這裡頭有兩個需要解釋的地方,一個是params,一個是:id。

params是在瀏覽器發送http request給伺服器時,除了指定網址以外,也會帶一些參數給伺服器。例如使用者登入的時候,就要將帳號和密碼傳給伺服器。在Rails的controller裡面,就是用params這個變數來代表http request送出的參數。

由於params這個物件裡面包含非常多的資料,所以我們利用讀取物件的[]引號來指定:id。為什麼不是像一般javascript物件一樣用params["id"]讀取呢?很簡單,因為這不是javascript物件(什麼爛解釋),在Rails當中不管是從ActiveRecord資料庫當中查資料、或是從params中讀取資料,都是使用符號來查詢。

符號也可以在hash中套用變數來查詢,就跟一般物件的查詢一樣:

hash = {:name => "John", :email => "john@gmail.com"}
variable = :name
hash[variable]
# => "John"

在Ruby版本1.9以後,:name => "John"也可以簡化成將冒號放在後方:

hash = {name: "John", email: "john@gmail.com"}

完全看自己習慣而定,只要記得冒號在前面和在後面的差異即可,建議所有用法要統一。

4. Constant 常數

開頭大寫的變數就是常數,在Rails當中,任何model、class、module的名稱都是常數,所以才會看到這些很普遍的寫法:

class PostsController < ApplicationController
    def new
        @post = Post.new
        # 代表準備要從model裡面寫入新的一筆記錄
    end
end

幸好大部分編輯器都會幫我們將開頭大寫的常數給標示出來,不然光是一個開頭大寫,的確還蠻容易搞混的。

另外,常數的後方常會接上::符號,代表承接的意思。例如我們要在專案裡設定專門給管理員使用的各種controller,那放在同一個資料夾底下會比較容易管理,這時候若在終端機中開啟新的controller,就輸入:

$ rails new controller admin::posts 

就會看到 posts_controller.rb自動會歸類到admin這個資料夾裡面,代表承接的意思。


雖然這些變數和符號並不複雜,但像我在剛開始學時真的踢到不少鐵板,一度以為所有的變數都要以@開頭,也不知道為何有些東西要大寫有些不用。希望這些基本的小知識讓剛開始學習的朋友能有一些認識~

延伸閱讀

Ruby variables

Ruby Quick Reference