You define a keyword argument in a method by specifying the name in the method definition:
def say(message: "Hello World")
puts message
end
say
# => "Hello World"
say message: "Today is Monday"
# => "Today is Monday"
You can define multiple keyword arguments, the definition order is irrelevant:
def say(message: "Hello World", before: "<p>", after: "</p>")
puts "#{before}#{message}#{after}"
end
say
# => "<p>Hello World</p>"
say message: "Today is Monday"
# => "<p>Today is Monday</p>"
say after: "</p><hr>", message: "Today is Monday"
# => "<p>Today is Monday</p><hr>"
Keyword arguments can be mixed with positional arguments:
def say(message, before: "<p>", after: "</p>")
puts "#{before}#{message}#{after}"
end
say "Hello World", before: "<span>", after: "</span>"
# => "<span>Hello World</span>"
Mixing keyword argument with positional argument was a very common approach before Ruby 2.1, because it was not possible to define required keyword arguments.
Moreover, in Ruby < 2.0, it was very common to add an Hash
at the end of a method definition to use for optional arguments. The syntax is very similar to keyword arguments, to the point where optional arguments via Hash
are compatible with Ruby 2 keyword arguments.
def say(message, options = {})
before = option.fetch(:before, "<p>")
after = option.fetch(:after, "</p>")
puts "#{before}#{message}#{after}"
end
# The method call is syntactically equivalent to the keyword argument one
say "Hello World", before: "<span>", after: "</span>"
# => "<span>Hello World</span>"
Note that trying to pass a not-defined keyword argument will result in an error:
def say(message: "Hello World")
puts message
end
say foo: "Hello"
# => ArgumentError: unknown keyword: foo