Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Ruby Dictionary

  1. Home
  2. Ruby Dictionary
  3. def (Method Definition) (Ruby)

def (Method Definition) (Ruby)

Methods in Ruby are defined with the def keyword. This page covers flexible argument styles — default values, keyword arguments, variadic arguments, and block arguments — as well as naming conventions for the ? and ! suffixes.

Syntax

# Basic method definition.
def method_name(arg1, arg2)
  expression  # The last expression is automatically the return value.
end

# Default value argument.
def method_name(arg1, arg2 = default_value)
  expression
end

# Keyword arguments (name: format).
def method_name(key1:, key2: default_value)
  expression
end

# Variadic arguments (received as an array).
def method_name(*args)
  expression
end

# Keyword variadic arguments (received as a hash).
def method_name(**kwargs)
  expression
end

# Explicitly receive a block.
def method_name(&block)
  block.call
end

Argument & Naming Convention Reference

Syntax / ConventionDescription
def / endKeywords that open and close a method definition.
arg = valueDefault value argument. The default is used when the caller omits the argument.
key:Keyword argument. The caller must specify the key name. Order does not matter.
*argsVariadic argument. Collects all positional arguments passed into an array.
**kwargsKeyword variadic argument. Collects keyword arguments passed into a hash.
&blockReceives a block explicitly as a Proc object. More explicit than yield.
method_name?Naming convention for methods that return a boolean. e.g. empty?, include?.
method_name!Naming convention for destructive methods (those that mutate the receiver). e.g. sort!, gsub!.

Sample Code

Basic method definition and default value arguments.

def_basic.rb
def greet(name)
  "Hello, #{name}!"
end

puts greet("Akane Tsunemori")
puts greet("Nobuchika Ginoza")

def introduce(name, division = "Criminal Investigation")
  "#{name} (#{division})"
end

puts introduce("Akane Tsunemori")
puts introduce("Shogo Makishima", "Civilian")
ruby def_basic.rb
Hello, Akane Tsunemori!
Hello, Nobuchika Ginoza!
Akane Tsunemori (Criminal Investigation)
Shogo Makishima (Civilian)

Keyword arguments allow callers to specify argument names explicitly, which improves readability.

def_keyword_args.rb
def register_inspector(name:, hue_value:, rank: "Inspector")
  "#{rank} #{name} (Hue Value: #{hue_value})"
end

puts register_inspector(name: "Akane Tsunemori", hue_value: 42)
puts register_inspector(hue_value: 75, name: "Mika Shimotsuki", rank: "Inspector")
puts register_inspector(name: "Nobuchika Ginoza", hue_value: 60, rank: "Enforcer")
ruby def_keyword_args.rb
Inspector Akane Tsunemori (Hue Value: 42)
Inspector Mika Shimotsuki (Hue Value: 75)
Enforcer Nobuchika Ginoza (Hue Value: 60)

Variadic arguments with *args and keyword variadic arguments with **kwargs.

def_splat_args.rb
def report_latent_criminals(*names)
  puts "Latent criminals (#{names.size}):"
  names.each { |name| puts "  - #{name}" }
end

report_latent_criminals("Shogo Makishima", "Shinya Kogami", "Nobuchika Ginoza")

def show_profile(**attributes)
  attributes.each { |key, value| puts "  #{key}: #{value}" }
end

puts "--- Shogo Makishima ---"
show_profile(name: "Shogo Makishima", occupation: "Latent Criminal", crime_coefficient: 256, hobby: "Reading")
ruby def_splat_args.rb
Latent criminals (3):
  - Shogo Makishima
  - Shinya Kogami
  - Nobuchika Ginoza
--- Shogo Makishima ---
  name: Shogo Makishima
  occupation: Latent Criminal
  crime_coefficient: 256
  hobby: Reading

Receiving a block explicitly with &block.

def_block_arg.rb
def execute_judgment(inspector_name, &block)
  puts "#{inspector_name} begins judgment."
  result = block.call
  puts "Judgment result: #{result}"
end

execute_judgment("Akane Tsunemori") { "Suspended sentence" }
execute_judgment("Mika Shimotsuki") { "Forced isolation" }

def inspect_all(inspectors, &block)
  inspectors.each(&block)
end

inspect_all(["Akane Tsunemori", "Nobuchika Ginoza", "Mika Shimotsuki"]) do |name|
  puts "  #{name}: scan complete"
end
ruby def_block_arg.rb
Akane Tsunemori begins judgment.
Judgment result: Suspended sentence
Mika Shimotsuki begins judgment.
Judgment result: Forced isolation
  Akane Tsunemori: scan complete
  Nobuchika Ginoza: scan complete
  Mika Shimotsuki: scan complete

The ? and ! naming conventions in action.

def_naming_convention.rb
def latent_criminal?(crime_coefficient)
  crime_coefficient >= 100
end

def enforcer?(name, enforcers)
  enforcers.include?(name)
end

enforcers = ["Shinya Kogami", "Nobuchika Ginoza"]

puts latent_criminal?(80)
puts latent_criminal?(150)
puts enforcer?("Akane Tsunemori", enforcers)
puts enforcer?("Shinya Kogami", enforcers)

def normalize_name!(inspector)
  inspector[:name] = inspector[:name].strip
  inspector[:rank] = inspector[:rank].upcase
end

officer = { name: "  Akane Tsunemori  ", rank: "inspector" }
puts "Before: #{officer}"
normalize_name!(officer)
puts "After: #{officer}"
ruby def_naming_convention.rb
false
true
false
true
Before: {:name=>"  Akane Tsunemori  ", :rank=>"inspector"}
After: {:name=>"Akane Tsunemori", :rank=>"INSPECTOR"}

Notes

Ruby methods are defined with def and end. The last expression in a method body is automatically the return value. return is used only when you need to exit the method early.

Arguments can combine positional, default-value, variadic (*args / **kwargs), and block (&block) styles. When mixing these, the required order is: positional → default-value → variadic (*args) → keyword → keyword variadic (**kwargs) → block (&block). A different order causes a SyntaxError.

By convention, methods ending in ? return a boolean, and those ending in ! perform a destructive (mutating) operation. These are conventions, not Ruby requirements, but they are widely observed in the Ruby community. For more on blocks, see block / yield. For Proc and Lambda, see Proc / Lambda.

Common Mistakes

Mistake 1: Wrong argument order causes SyntaxError

When mixing positional, default-value, and variadic arguments, placing the variadic argument before the default-value argument is a typical mistake that causes a SyntaxError.

def_order_ng.rb
def register(*names, division = "Criminal Investigation")
  names.each { |name| puts "#{name} (#{division})" }
end
ruby def_order_ng.rb
def_order_ng.rb:1:in `<main>': syntax error, unexpected local variable or method (SyntaxError)

The correct order is: positional → default-value → *args → **kwargs → &block.

def_order_ok.rb
def register(division = "Criminal Investigation", *names)
  names.each { |name| puts "#{name} (#{division})" }
end

register("Criminal Investigation", "Akane Tsunemori", "Nobuchika Ginoza", "Mika Shimotsuki")
register("Enforcer", "Shinya Kogami")
ruby def_order_ok.rb
Akane Tsunemori (Criminal Investigation)
Nobuchika Ginoza (Criminal Investigation)
Mika Shimotsuki (Criminal Investigation)
Shinya Kogami (Enforcer)

Mistake 2: Misunderstanding the meaning of ? / ! suffixes

The ? suffix does not force Ruby to return a boolean — it is purely a naming convention. Likewise, ! does not automatically mutate the receiver; the behavior depends entirely on the method's implementation. Adding ! to a name does not make it destructive.

def_suffix_ng.rb
def latent_criminal?(name)
  puts "Checking #{name}..."
end

result = latent_criminal?("Shogo Makishima")
puts result.class
ruby def_suffix_ng.rb
Checking Shogo Makishima...
NilClass

The method named with ? returns nil. To follow the convention, the method should return a boolean.

def_suffix_ok.rb
LATENT_CRIMINALS = ["Shogo Makishima", "Shinya Kogami"]

def latent_criminal?(name)
  LATENT_CRIMINALS.include?(name)
end

puts latent_criminal?("Shogo Makishima")
puts latent_criminal?("Akane Tsunemori")
puts latent_criminal?("Shogo Makishima").class
ruby def_suffix_ok.rb
true
false
TrueClass

Mistake 3: Overusing return when the last expression already returns

Ruby automatically returns the value of the last expression in a method body, so writing return in every branch is unnecessary. return is typically used only to exit a method early.

def_return_ng.rb
def get_rank(crime_coefficient)
  if crime_coefficient >= 300
    return "Execution target"
  elsif crime_coefficient >= 100
    return "Latent criminal"
  else
    return "Normal"
  end
end

puts get_rank(350)
puts get_rank(150)
puts get_rank(50)
ruby def_return_ng.rb
Execution target
Latent criminal
Normal

The code works correctly, but every return is redundant. The last expression in each branch is returned automatically.

def_return_ok.rb
def get_rank(crime_coefficient)
  if crime_coefficient >= 300
    "Execution target"
  elsif crime_coefficient >= 100
    "Latent criminal"
  else
    "Normal"
  end
end

puts get_rank(350)
puts get_rank(150)
puts get_rank(50)
ruby def_return_ok.rb
Execution target
Latent criminal
Normal

If you find any errors or copyright issues, please .