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 / Convention | Description |
|---|---|
| def / end | Keywords that open and close a method definition. |
| arg = value | Default 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. |
| *args | Variadic argument. Collects all positional arguments passed into an array. |
| **kwargs | Keyword variadic argument. Collects keyword arguments passed into a hash. |
| &block | Receives 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 contact us.