0

I have an object that allows users to connect to HDFS. One method allows them to download data, and the other upload data. The initialize method looks something like this:

def initialize(file=nil,set=nil,action)
end

How can I change the way arguments are passed to be more efficient? The action param is required every time, but file and file_set are only required depending on the action. I.e., if they want to upload data they need to pass set, if they want to download data, they just pass file.

3 Answers 3

2

Since Ruby 2.0 you can use keyword parameters:

def initialize(action, file: nil,set: nil)
  unless file.nil?
    # do stuff with file
  end
end

So you can call it:

MyClass.new(some_action)
MyClass.new(some_action, set: some_set)
MyClass.new(some_action, file: some_file)
MyClass.new(some_action, set: some_set, file: some_file)
...
Sign up to request clarification or add additional context in comments.

Comments

1

First of all you should pass requred parameter first e.g.:

def initialize(action, file = nil, set = nil)
end

Then you may want to use hash to pass optional params:

def initialize(action, options = {})
end

The passing hash is a common way when you need to pass more than one optional parameter. When you need to pass file, set or both you may call initialize method as follow (assume that this method is defened in the class MyModel):

MyModel.new(action, {file: ''})
MyModel.new(action, {set: ''})
MyModel.new(action, {file: '', set: ''})

Or when you don't want to pass any optional params, simply call:

MyModel.new(action)

In this case you will have empty options hash passed in you initialize method.

4 Comments

Well, in this case the file or set will also always be required (one of the two will have to be provided), so they aren't really options per say. See what I mean?
@GrahamJackson I have added some further explanation.
In modern Ruby, required arguments can come after optional ones.
And modern Ruby has named parameters.
1

Quite common is to use positional parameters when they are mandatory, and an options hash for the rest. You just need to check action to verify given params are then present:

def initialize(action, opts={})
  if action == 'foo'
    raise ArgumentError, "requires either :file or :set" unless 
      ([:file, :set] & opts.keys).size == 1
  end
  ...
end

1 Comment

That is old fashioned.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.