2010-03-17 30 views
18

Làm cách nào để khai báo một phương thức có đối số từ khóa giống như đường ray làm. một số ví dụ có thể làđối số từ khóa ruby ​​của phương thức

Person.find(:all, :conditions => "..."). 

Tôi có thể sử dụng biểu tượng để tạo phương pháp tương tự như trên không?

Tôi rất mới với ruby. Cảm ơn trước!

+0

Đây là những không phải đối số từ khóa. Thay vào đó, bạn có thể xem mã nguồn của các phương thức lấy các đối số này để tìm hiểu cách thực hiện kỹ thuật này. Hãy xem tài liệu về 'ActiveRecord :: Base.find' (http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002263) để biết các ý tưởng. – yfeldblum

Trả lời

37

Ruby không thực sự có các đối số từ khóa. Rails đang khai thác một tính năng của Ruby cho phép bạn bỏ qua các dấu ngoặc xung quanh một băm. Ví dụ, với find, những gì chúng tôi đang thực sự gọi là:

Nhưng nếu băm là đối số cuối cùng của phương pháp này, bạn có thể bỏ qua các dấu ngoặc và nó vẫn sẽ được coi như một hash:

Person.find(:all, :conditions => "...", :offset => 10, :limit => 10) 

bạn có thể sử dụng trong các phương pháp của riêng bạn:

def explode(options={}) 
    defaults = { :message => "Kabloooie!", :timer => 10, :count => 1 } 
    options = defaults.merge(options) 

    options[:count].times do 
     sleep options[:timer] 
     puts options[:message] 
    end 
end 

Và sau đó gọi nó là:

explode :message => "Meh.", :count => 3 

Hoặc gọi nó mà không có một cuộc tranh cãi, dẫn đến tất cả các giá trị mặc định được sử dụng:

explode 
+6

Câu trả lời này hiện nay (một phần) đã lỗi thời. Ruby 2.0 có các đối số từ khóa đúng. Tuy nhiên, chúng lén lút tương thích với quy ước sử dụng hashes đối số cuối cùng: nếu bạn chuyển băm với các phím biểu tượng cho một phương thức mong đợi từ khóa, Ruby sẽ tách chúng ra thành các đối số từ khóa. Rails vẫn chưa sử dụng các đối số từ khóa của Ruby 2.0 để duy trì khả năng tương thích với Ruby 1.9. – Peeja

0

Kể từ Ruby gõ động, chỉ cần làm:

def my_method(arg1, arg2) 
    #things 
end 

dụ:

my_method(:test, {:somehash => "yay"}) 

hoặc

my_method :test, :somehash => "yay" 

hoặc

my_method(:test, :somehash => "yay") 
1

Bạn chỉ cần xác định một phương pháp mà một trong những thông số là một hash. Nó thực sự khá đơn giản.

def method(arg1, params) 
    name = params[:name] 
    number = params[:number] 

Và sau đó gọi nó thích:

method(arg1, :name => 'Eric', :number => 2) 

Hai lưu ý:

  1. Trong Ruby, bạn không cần phải bao quanh các thông số băm trong {} khi bạn gọi phương thức trong hầu hết các trường hợp, trừ khi bạn có một cái gì đó phức tạp xảy ra như đi qua nhiều băm. Trong trường hợp đó, hãy đảm bảo rằng bạn bao quanh các thông số đó với {}
  2. Ruby được nhập động, vì vậy bạn không cần phải nói rằng thông số là băm khi bạn xác định phương thức.
6

Tôi đồng ý với câu trả lời được chấp nhận của Samir Talwar và christopherwright. Nhược điểm tiềm năng duy nhất là bạn sẽ không nhận được cảnh báo nếu bạn sử dụng một biểu tượng từ khóa không chính xác làm đối số hoặc khi tìm kiếm một tùy chọn, nó chỉ bị bỏ qua. Nếu đó là điều bạn quan tâm, đá quý hash_keyword_args sẽ giải quyết nó.Thành ngữ sẽ là

def explode(opts={}) 
    opts = opts.keyword_args(:message => "Kabloooie!", :timer => 10, :count => 1) 

    opts.count.times do 
     sleep opts.timer 
     puts opts.message 
    end 
end 

Lưu ý việc sử dụng phương thức truy cập để bạn sẽ nhận được NoMethodError nếu bạn nhập nhầm từ khóa. Và hành vi gọi điện là:

explode(:message => "Okay") # works 
explode(:msg => "Oops")  # raises ArgumentError 

Đá quý cũng cung cấp một vài tính năng khác mà bạn có thể quan tâm, chẳng hạn như có thể chỉ ra rằng từ khóa là bắt buộc. Tôi đã sử dụng nó một cách vui vẻ trong một thời gian.

(Disclaimer:. Tôi là tác giả của đá quý)

7

Kể từ của Ruby 2.0, ruby ​​does have keyword arguments.

def my_method(arg1, name: 'defaultName', number: 0) 
    puts arg1, name, number 
end 
0

Ruby 2.0 đã thêm đối số từ khóa thực và Ruby 2.1 đã thêm đối số từ khóa bắt buộc.

Có một bài viết tốt đẹp tại https://chriszetter.com/blog/2012/11/02/keyword-arguments-in-ruby-2-dot-0/ về vấn đề này, tôi đã mượn các ví dụ từ đó:

của Ruby 2.0+:

def exclaim(text, exclamation: '!', number: 7) 
    text + exclamation * number 
end 

exclaim('hello', number: 4) #=> 'hello!!!!' 

# equivalent: 
exclaim('hello', {:number => 4}) #=> 'hello!!!!' 

của Ruby 2.1 +:

def exclaim(text, exclamation: '!', number:) 
    text + exclamation * number 
end 

exclaim('Yo', number: 5) # => 'Yo!!!!!' 
exclaim('Yo') # raises: ArgumentError: missing keyword: number 
Các vấn đề liên quan