[英]How are symbols used to identify arguments in ruby methods
我正在學習 rails 並回到 ruby 以了解 rails 中的方法(和 ruby 真正的工作原理)。 當我看到如下方法調用時:
validates :first_name, :presence => true
我有點迷惑不解了。 你如何在 ruby 中編寫接受符號或散列的方法。 validates 方法的源代碼也令人困惑。 有人可以為我簡化在 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")
這顯然會引發錯誤。 我試圖理解:如果符號與任何其他值一樣,為什么將這樣的符號作為參數傳遞是錯誤的?
符號和哈希值與其他任何值一樣,可以像任何其他值類型一樣傳遞。
回想一下 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')
這利用了不必將散列放在大括號{}
除非您需要消除參數的歧義(並且當您跳過括號時也存在塊解析問題)。
相似地:
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}'
從那里你可以開始看到這樣的事情是如何工作的。
我想我會為 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
確實被函數調用改變了。
在 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
您如何編寫方法並沒有什么“特別”之處,而是您如何調用它。 將常規 Hash 對象作為kwargs
參數傳遞是完全合法的。 此語法快捷方式用於在 API 中實現命名參數。
Ruby 符號只是一個值,因此在您的示例中, :first_name
只是一個常規的位置參數。 :presence
是一個用作散列鍵的符號——任何類型都可以用作散列鍵,但符號是一個常見的選擇,因為它們是不可變的值。
我認為所有的回復都沒有抓住問題的重點; 事實上,有人問過這個問題——我猜——不清楚符號是什么?
作為 Ruby 的新手,我也有類似的困惑,對我來說,像下面這樣的答案會更有意義
方法參數是由傳入的值填充的局部變量。
您不能單獨使用符號作為參數,因為您不能更改符號的值。
符號不限於哈希。 它們是標識符,沒有字符串的額外存儲空間。 這只是說“這是……”的一種方式
validates 調用的一個可能的函數定義可能是(只是為了簡化,我不知道它到底是什么):
def validates(column, options)
puts column.to_s
if options[:presence]
puts "Found a presence option"
end
end
請注意第一個符號是如何自己成為參數的,而其余的則是散列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.