Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have required named parameters in Ruby 2.x?

Ruby 2.0 is adding named parameters, like this:

def say(greeting: 'hi')   puts greeting end  say                     # => puts 'hi' say(greeting: 'howdy')  # => puts 'howdy' 

How can I use named parameters without giving a default value, so that they are required?

like image 754
Nathan Long Avatar asked Nov 06 '12 11:11

Nathan Long


People also ask

How do you pass keyword arguments in Ruby?

So when you want to pass keyword arguments, you should always use foo(k: expr) or foo(**expr) . If you want to accept keyword arguments, in principle you should always use def foo(k: default) or def foo(k:) or def foo(**kwargs) .

What are keyword arguments in Ruby?

What are keyword arguments? Keyword arguments are a feature in Ruby 2.0 and higher. They're an alternative to positional arguments, and are really similar (conceptually) to passing a hash to a function, but with better and more explicit errors.


2 Answers

There is no specific way in Ruby 2.0.0, but you can do it Ruby 2.1.0, with syntax like def foo(a:, b:) ...

In Ruby 2.0.x, you can enforce it by placing any expression raising an exception, e.g.:

def say(greeting: raise "greeting is required")   # ... end 

If you plan on doing this a lot (and can't use Ruby 2.1+), you could use a helper method like:

def required   method = caller_locations(1,1)[0].label   raise ArgumentError,     "A required keyword argument was not specified when calling '#{method}'" end  def say(greeting: required)   # ... end  say # => A required keyword argument was not specified when calling 'say' 
like image 92
Marc-André Lafortune Avatar answered Oct 08 '22 15:10

Marc-André Lafortune


At the current moment (Ruby 2.0.0-preview1) you could use the following method signature:

def say(greeting: greeting_to_say)   puts greeting end 

The greeting_to_say is just a placeholder which won't be evaluated if you supply an argument to the named parameter. If you do not pass it in (calling just say()), ruby will raise the error:

NameError: undefined local variable or method `greeting_to_say' for (your scope) 

However, that variable is not bound to anything, and as far as I can tell, cannot be referenced from inside of your method. You would still use greeting as the local variable to reference what was passed in for the named parameter.

If you were actually going to do this, I would recommend using def say(greeting: greeting) so that the error message would reference the name you are giving to your parameter. I only chose different ones in the example above to illustrate what ruby will use in the error message you get for not supplying an argument to the required named parameter.

Tangentially, if you call say('hi') ruby will raise ArgumentError: wrong number of arguments (1 for 0) which I think is a little confusing, but it's only preview1.

like image 28
Adam Avatar answered Oct 08 '22 15:10

Adam