2011-11-05 24 views
9

,並要回紅寶石瞭解軌方法如何(以及紅寶石真正發揮作用)。當我看到如下方法調用時:使用符號作爲參數傳遞給紅寶石我學習軌方法

validates validates :first_name, :presence => true 

我感到困惑。你如何在Ruby中寫入接受符號或哈希的方法。驗證方法的源代碼也很混亂。有人可以簡化這個話題使用符號作爲紅寶石類和實例方法的參數對我來說?

更新:

好@Dave!但我正在嘗試的是這樣的:

def full_name (:first_name, :last_name) 
    @first_name = :first_name 
    @last_name = :last_name 
    p "#{@first_name} #{last_name}" 
end 

full_name("Breta", "Von Sustern") 

這顯然會引發錯誤。我試圖理解:如果符號與其他任何值一樣,爲什麼將這樣的符號作爲參數傳錯?

+0

符號和散列值與其他任何值一樣 - 傳遞符號或散列比其他任何東西都沒有什麼不同。什麼特別讓你困惑? –

+0

讓我感到困惑的是,我從來沒有見過散列值被用作ruby方法的例子。所以我無法想象你在說什麼。 –

+1

您*傳遞*符號,參數名稱仍然是 - 參數名稱,並且不應該有前導':'字符。 –

回答

15

符號和哈希值是像任何其他值,並且可以像任何其他值類型被傳遞。

回想一下,ActiveRecord的模型接受一個哈希作爲參數;它最終被類似這樣的(它不是這個簡單,但它到底是同樣的想法):

class User 
    attr_accessor :fname, :lname 

    def initialize(args) 
    @fname = args[:fname] if args[:fname] 
    @lname = args[:lname] if args[:lname] 
    end 
end 

u = User.new(:fname => 'Joe', :lname => 'Hacker') 

這種利用不必把散在大括號{}除非你需要消除歧義的參數(還有一個塊解析的問題,以及當你跳過parens)。

同理:

class TestItOut 
    attr_accessor :field_name, :validations 

    def initialize(field_name, validations) 
    @field_name = field_name 
    @validations = validations 
    end 

    def show_validations 
    puts "Validating field '#{field_name}' with:" 
    validations.each do |type, args| 
     puts " validator '#{type}' with args '#{args}'" 
    end 
    end 
end 

t = TestItOut.new(:name, presence: true, length: { min: 2, max: 10 }) 
t.show_validations 

此輸出:

Validating field 'name' with: 
    validator 'presence' with args 'true' 
    validator 'length' with args '{min: 2, max: 10}' 

從那裏你可以開始看到這樣的事情工作。

+0

此外,當在散列內部獲取參數時,請考慮使用'fetch'方法來提供默認值。 –

4

在Ruby中,如果你在參數列表的末尾調用了一堆的name => value雙的方法,這些都會自動裹在Hash並傳遞給你的方法作爲最後一個參數:

def foo(kwargs) 
    p kwargs 
end 

>> foo(:abc=>"def", 123=>456) 
{:abc=>"def", 123=>456} 

>> foo("cabbage") 
"cabbage" 

>> foo(:fluff) 
:fluff 

關於如何編寫該方法沒有什麼「特別的」,這就是你如何稱呼它的方法。將傳統的哈希對象作爲參數kwargs傳遞將是完全合法的。這句法快捷鍵是用來實現命名參數的的API中。

Ruby的符號只是一個數值的任何其他,所以在你的榜樣,:first_name只是一個普通的位置參數。 :presence是用作哈希鍵的象徵 - 任何類型的可以作爲一個哈希鍵,但符號是一種常見的選擇,因爲它們是不可變的值。

+1

而且,更重要的是不可變的,他們更具溝通性,因爲他們專門作爲某物的名稱或標籤。 –

2

符號不限於哈希。它們是標識符,沒有額外的字符串存儲空間。這只是一種說法,「這是....「

爲只會驗證電話可能是一個可能的函數定義(只是爲了簡化,我不知道把我的頭頂部到底是什麼):

def validates(column, options) 
    puts column.to_s 
    if options[:presence] 
    puts "Found a presence option" 
    end 
end 

通知的第一個符號是如何一個參數都是自己的,其餘的就是哈希。

+0

它們仍然存儲,只是每個唯一標籤只存儲一次,就像一個interned字符串一樣。 OTOH,他們不符合GC(也許他們在1.9),所以他們堅持應用程序的一生。 –

+0

符號在1.9中也不是GC'd。 – sheldonh

+0

Ruby 2.2現在有符號GC – DGM

2

我覺得所有的回覆都沒有提到問題的地方;而這個問題被某個人問到 - 我想 - 不清楚符號是什麼?

作爲Ruby的新手,我有類似的困惑,對我來說,像下面的答案會更有意義

方法參數是由傳入的值填充的局部變量。

你不能使用符號作爲自己的參數,因爲你不能改變符號的值。

+2

我不確定你的意思是「你不能使用符號作爲自己的參數」,因爲你可以......「foo(:bar)」是一個完全合法的函數調用。也許我誤解了? –

9

我以爲我會爲Ruby 2+添加更新,因爲這是我找到的'符號作爲參數'的第一個結果。

由於Ruby 2.0.0在定義方法時也可以使用符號。在調用方法時,這些符號將與其他語言中的命名可選參數幾乎相同。見下面的例子:如在示例中所示

def variable_symbol_method(arg, arg_two: "two", arg_three: "three") 
    [arg, arg_two, arg_three] 
end 

result = variable_symbol_method :custom_symbol, arg_three: "Modified symbol arg" 

# result is now equal to: 
[:custom_symbol, "two", "Modified symbol arg"] 

,我們省略arg_two:調用方法時和在該方法中體我們仍然可以訪問它作爲變量arg_two。還要注意,變量arg_three確實被函數調用改變了。