Sonu Oommen
Sonu Oommen

Reputation: 1183

Is there a way to define a method that will accept one parameter or none at all

I was writing a program such that it checks if a file is passed in as argument to a method or function, if no argument is passed then it accepts string through gets. I know about the * operator, but as i said i dont need an array of arguments. Either one or none and also no defaults. Is there any way thats possible ?

Upvotes: 3

Views: 323

Answers (3)

Mark Thomas
Mark Thomas

Reputation: 37517

An optional argument can be simulated by a default value:

def my_method(arg = nil)
  #do something with arg
end

You can call it as my_method() or my_method(arg). If the parameter isn't given, it's the same as if you passed in a nil value. Though I recommend a more meaningful default value if possible.

If you want a truly optional parameter, yet still require raising an exception when it is called with too many, you can use the splat and insert a guard clause:

def my_method(*args)
  raise ArgumentError if args.length > 1
  #do something with args.first
end

This way it behaves exactly the way you describe.

Upvotes: 6

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230346

Here's a little abuse of default parameter. Don't try this at home.

def foo(bar = gets)
  puts "Got this: #{bar}"
end

foo('a param')
foo

Output

% ruby script.rb
Got this: a param
from gets
Got this: from gets

Upvotes: 2

sawa
sawa

Reputation: 168121

If there is a value that an argument never takes, say nil, then, you can use that as a default value:

def foo arg = nil
  if arg.nil?
    # argument was not given
  else
    # argument was given
  end
end

You can define your original module as a constant, which may free you from such restriction:

module NeverUsedValue; end
def foo arg = NeverUsedValue
  if arg == NeverUsedValue
    # argument was not given
  else
    # argument was given
  end
end

Otherwise, there is probably no way to do it without using the splat.

def foo *args
  case args.length
  when 1
    # argument was given
    arg = args.first
  when 0
    # argument was not given
  end
end

I don't know why you are refusing to use the splat. The solution using is free of the restriction, and is hence better.

Upvotes: 3

Related Questions