Working with modules
Modules, like abstract classes, don't represent concrete classes that you can create objects from. Instead, modules are fragments of the implementation class that can be included in a class when you're defining it. Modules can define instance variables, methods, class variables, class methods, and abstract methods, all of which get injected into the class that includes them.
Let's explore an example of a module that defines a say_name method based on some existing name method:
module WithSayName
  abstract def name : String
  def say_name
    puts "My name is #{name}"
  end
end
This can be used with your Person class:
class Person   include WithSayName   property name : String   def initialize(@name : String)   end end
Here, the name method that's expected by WithSayName is produced by the property macro. Now, we can create a new...