Crystal Notes: Methods
Published: 2021-07-29
Intro
A Method in Crystal is like a fuction in other languages.
## Define a method that accepts no arguments.
def print_stuff
puts "stuff"
end
# Call a method.
print_stuff()
# Define a method that accepts arguments.
# The parameter types will be inferred by the compiler.
def do_stuff(what, how)
puts "#{what} #{how}"
end
# Call a method with arguments.
do_stuff("Say hello", "speak")
# Call a method with named parameter arguments.
do_stuff(what: "Say hello", how: "speak")
Overloading
Methods in Crystal can be overloaded. This means that methods with the same name but different signatures are treated as different methods.
## Define a method and explicity define the types that are accepted.
def do_stuff(what : String, how : String)
puts "#{what} #{how}"
end
# Call a method with arguments defining the parameters.
do_stuff(what: "Say hello", how: "speak")
# Overload the do_stuff method with a different signature.
def do_stuff(x : Int32, y : Int32)
puts x + y
end
do_stuff(1, 2)
Default Parameters
Methods can have default parameters.
## Define a method with default parameters.
def do_stuff(x : Int32, y : Int32 = 1)
puts x + y
end
# Call a method with default parameters.
do_stuff(1)
Splat
A splat parameter is defined by prefixing a parameter with an asterix (*). A splat takes a variadic number of elements.
## Define a method with splat parameter.
# The splat items can be optionally type annotated.
def do_stuff(*args : String)
args.each do |a|
puts a
end
end
# Call method with N number of elements.
do_stuff("stuff", "things")
# A Tuple can be splatted into a method
stuff_and_things = {"stuff", "things"}
do_stuff(*stuff_and_things)
Double Splat
A double splat parameter is defined by prefixing a parameter with 2 asterixes (**). A double splat takes a variadic number of elements.
## Define a double splat method
def do_stuff(**kwargs)
kwargs.each do |key, value|
puts "Key: #{key} - Value: #{value}"
end
end
# Call a method with N number of named arguments.
do_stuff(stuff: "my stuff", things: "my things")
# A NamedTuple can be double splatted into a method.
stuff_and_things = {stuff: "my stuff", things: "my things"}
do_stuff(**stuff_and_things)
Return Values
The return type of a method can be specifically defined.
## Define a methods return type as a String.
def do_stuff(what : String, how : String) : String
"#{what} #{how}"
end
# Multiple return values, can be packed in a Tuple or Array.
def do_stuff(what : String, how : String) : Tuple(String, String)
Tuple(what, how)
end
# Unpack multiple return values
what, how = do_stuff("call glass guy", "on phone")
Block
A block lets you reuse code without creating a formal method.
## Example of using block.
stuff_and_things.map{ |item| item.upcase }
# (&) is syntastic sugar used to defind the captured object.
stuff_and_things.map(&.upcase)
Proc
A Proc, also know as a lambda or an anonymous function in other languages is a nameless function with a call method. Anonymous functions are defined with the -> operator.
## Define an anonymous function and assign it to a
# variable named fn.
fn = ->(stuff : String, things : String) { "#{stuff} - #{things}" }
# Call anonymous function
fn.call("my stuff", "my things") # => my stuff - my things
Considerations
- Methods are defined in snake_case by convention.
- A splat/double splat can appear only once in any position.
- The splat only accepts a tuple.
- The double splat only accepts a named tuple.
- Methods automatically return the value of the last expression. There is no need to declare the return statement.
- Type annotations are required for Procs.
- The return type of a Proc is inferred by the compiler.
- Crystal does not implement tail-call optimization. Therefore, recursive method calls are not infinitly scalable.
Links
https://pragprog.com/titles/crystal/programming-crystal/
https://crystal-lang.org/reference/syntax_and_semantics/splats_and_tuples.html
https://crystal-lang.org/reference/syntax_and_semantics/blocks_and_procs.html
https://crystal-lang.org/reference/syntax_and_semantics/capturing_blocks.html