How can I declare a method with keyword arguments just like rails do. some examples may be
Person.find(:all, :conditions => "...").
How can I use symbols to create methods similar开发者_如何学运维 to the above?
I am very new to ruby. Thanks in advance!
Ruby doesn't actually have keyword arguments. Rails is exploiting a feature of Ruby which lets you omit the braces around a hash. For example, with find
, what we're really calling is:
Person.find(:all, { :conditions => "...", :offset => 10, :limit => 10 } )
But if the hash is the last argument of the method, you can leave out the braces and it will still be treated as a hash:
Person.find(:all, :conditions => "...", :offset => 10, :limit => 10)
You can use this in your own methods:
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
And then call it:
explode :message => "Meh.", :count => 3
Or call it without an argument, resulting in all default values being used:
explode
Since Ruby 2.0, ruby does have keyword arguments.
def my_method(arg1, name: 'defaultName', number: 0)
puts arg1, name, number
end
I agree with accepted answer given by Samir Talwar and christopherwright. The only potential downside is that you get no warnings if you use an incorrect keyword symbol as an argument or when looking up an option, it just ends up ignored. If that's something you're concerned about, the gem hash_keyword_args addresses it. The idiom would be
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
Notice the use of accessor methods so you'll get a NoMethodError if you mistype a keyword. And the calling behavior is:
explode(:message => "Okay") # works
explode(:msg => "Oops") # raises ArgumentError
The gem also provides a few other features you might or might not care about, such as being able to indicate that a keyword is required. I've been using it happily for a while now.
(Disclaimer: I'm the author of the gem.)
You just need to define a method where one of the parameters is a hash. It's actually pretty simple.
def method(arg1, params)
name = params[:name]
number = params[:number]
And then call it like:
method(arg1, :name => 'Eric', :number => 2)
Two notes:
- In Ruby, you don't need to surround the parameters hash in {} when you call the method in most cases, unless you have something complicated going on like passing multiple hashes. In that case, make sure you surround those parameters with {}
- Ruby is dynamically typed, so you don't need to say that params is a hash when you define the method.
Ruby 2.0 introduced real keyword arguments, and Ruby 2.1 added required keyword arguments.
There's a nice article up at https://chriszetter.com/blog/2012/11/02/keyword-arguments-in-ruby-2-dot-0/ on this, I've borrowed the examples from there:
Ruby 2.0+:
def exclaim(text, exclamation: '!', number: 7)
text + exclamation * number
end
exclaim('hello', number: 4) #=> 'hello!!!!'
# equivalent:
exclaim('hello', {:number => 4}) #=> 'hello!!!!'
Ruby 2.1+:
def exclaim(text, exclamation: '!', number:)
text + exclamation * number
end
exclaim('Yo', number: 5) # => 'Yo!!!!!'
exclaim('Yo') # raises: ArgumentError: missing keyword: number
Since Ruby is typed dynamically, just do :
def my_method(arg1, arg2)
#things
end
example:
my_method(:test, {:somehash => "yay"})
or
my_method :test, :somehash => "yay"
or
my_method(:test, :somehash => "yay")
精彩评论