updated: 3rd of August 2021
published: 29th of July 2021
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")
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)
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)
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)
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)
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")
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)
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
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