簡體   English   中英

如何使用符號來標識 ruby​​ 方法中的參數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM