2013-05-15 43 views
27

Tôi thấy các đối số băm được sử dụng trong một số phương thức thư viện như tôi đã học.Làm thế nào để các phương thức sử dụng các đối số băm trong Ruby?

Ví dụ:

list.search(:titles, genre: 'jazz', duration_less_than: 270) 

Ai đó có thể giải thích làm thế nào một phương pháp sử dụng lập luận như thế này, và làm thế nào bạn có thể tạo ra một phương pháp mà làm cho sử dụng các đối số Hash?

Trả lời

40

Ví dụ:

def foo(regular, hash={}) 
    puts "regular: #{regular}" 
    puts "hash: #{hash}" 
    puts "a: #{hash[:a]}" 
    puts "b: #{hash[:b]}" 
end 

foo("regular argument", a: 12, :b => 13) 

tôi sử dụng hash={} để xác định rằng các đối số cuối cùng là một băm, với giá trị mặc định của băm rỗng. Bây giờ, khi tôi viết:

foo("regular argument", a: 12, :b => 13) 

Nó thực sự là một cú pháp đường cho:

foo("regular argument", {a: 12, :b => 13}) 

Ngoài ra, {a: 12} là cú pháp đường cho {:a => 12}.

Khi tất cả điều này được kết hợp với nhau, bạn sẽ nhận được một cú pháp trông giống như đối số được đặt tên bằng các ngôn ngữ khác.

+0

U rock man! Cảm ơn :) – facundofarias

+0

Cảm ơn, cũng đã giải thích: D +1 –

3

tôi sẽ làm một trong hai lựa chọn:

1- nếu có một số lượng lớn các đối số để truyền vào một phương pháp tôi sẽ sử dụng một hash như thế này:

some_method({titles => 'titulo', genre => 'jazz', duration_less_than => 270}) 

hoặc

my_hash = {titles => 'titulo', genre => 'jazz', duration_less_than => 270} 
some_method(my_hash) 

def some_method(hash_options) 
    #important code 
end 

2- tùy chọn sẽ có nhiều 'truyền thống'

some_method('titulo', 'jazz', 270) 

def some_method(titles, genre, duration_less_than) 
#important code 
end 
+0

Điều này cho phép nhiều dòng! Cảm ơn vì @ M.Octavio này! 'some_method ({title => 'titulo', thể loại => 'jazz', duration_less_than => 270})' – GatoCurioso

11

Khi danh sách đối số là một phương pháp của Ruby gọi của kết thúc bằng một hoặc nhiều cặp khóa-giá trị, như foo: 'bar' hay 'foo' => 1, Ruby thu thập tất cả chúng vào một hash đơn và đi mà băm như tham số cuối cùng. Bạn có thể thấy rằng chính mình trong irb:

irb(main):002:0> puts foo: 'bar', baz: 'quux' 
{:foo=>"bar", :baz=>"quux"} 
=> nil 

Vì vậy, bạn có thể thêm một tham số cuối cùng, bắt buộc đến một phương pháp bạn đang viết để nhận băm này. Bạn thường sẽ muốn mặc định nó thành một băm rỗng. Bạn có thể gọi bất cứ điều gì thông số bạn muốn, nhưng options là một tên gọi chung:

def my_method(a, b, c, options = {}) 
    ... 
end 

Một mẹo nhỏ hữu ích nếu bạn đang sử dụng Rails: Đó là thường tiện dụng để điều trị chuỗi đồng bằng và các ký hiệu như tương đương. Rails cho biết thêm một phương pháp symbolize_keys!-Hash để chuyển đổi tất cả các phím chuỗi biểu tượng:

def my_method(a, b, c, options = {}) 
    options.symbolize_keys! 
    ... 
end 
+0

+1 cho 'symbolize_keys!' – aL3xa

24

Trong Ruby 2.x, bạn có thể sử dụng ** băm splat:

def foo(ordered_argument, **named_arguments) 
    puts "Ordered argument: #{ordered_argument}" 
    puts "Named arguments: #{named_arguments}" 
end 

foo(:titles, genre: 'jazz', duration_less_than: 270) 
#=> Ordered argument: titles 
#=> Named arguments: {:genre=>"jazz", :duration_less_than=>270} 
1

Đây là cách tôi làm điều đó:

def my_method(title, args) 
    puts title 
    puts args 

thông số đi qua:

my_method('test title', a: 'foo', b: 'bar') 
    # => test title 
    # => '{:a => 'foo', :b => 'bar'} 
Các vấn đề liên quan