Reputation: 22535
Is there a way to pass a single argument to a ruby function that has only optional parameters?
For instance, I want to pass ignoreAlreadyCrawled = true in the method below, and use the default parameter values for everything else. But since it's the last parameter, I have to do call crawl(nil, nil, nil, false, nil, false, nil, false, [], true), which is verbose, and ugly.
Method:
def crawl(url = nil, proxy = nil, userAgent = nil, post = false, postData = nil, image = false, imageFilename = nil, forceNoUserAgent = false, ignoreSubDomains = [], ignoreAlreadyCrawled = false)
#..logic here
end
Upvotes: 0
Views: 728
Reputation: 32955
When you have more than two or three arguments, the preferred pattern is to use a Hash of options instead.
I would redefine this method as follows: this is similar to Pawel's but more readable, i think:
def crawl(options={})
defaults = { url: nil,
proxy: nil,
userAgent: nil,
post: false,
postData: nil,
image: false,
imageFilename: nil,
forceNoUserAgent: false,
ignoreSubDomains: [],
ignoreAlreadyCrawled: false
}
options = defaults.merge(options)
#..logic here
end
You could omit from defaults all options that have nil
as their default, as an undefined option will come out as nil anyway. But, having them there acts as documentation for which options can be passed.
Upvotes: 1
Reputation: 9649
This is possible for ruby >= 2.0 with keyword arguments. In that case, you have to modify the method signature as follows (basically change =
to :
):
def crawl(url: nil, proxy: nil, userAgent: nil, post: false, postData: nil, image: false, imageFilename: nil, forceNoUserAgent: false, ignoreSubDomains: [], ignoreAlreadyCrawled: false)
#..logic here
end
And it will work as expected:
crawl(ignoreAlreadyCrawled: true)
Please see article for more examples: https://robots.thoughtbot.com/ruby-2-keyword-arguments
Upvotes: 8