Mó

Módulos em Crystal

1 exercício

Sobre Módulos

Os módulos em Crystal servem dois propósitos:

O primeiro é criar um espaço de nomes para evitar colisões de nomes. No entanto, também agrupam o código, o que facilita perceber para que serve.

O segundo é definir mixins para partilhar código entre tipos.

Os módulos são semelhantes às classes, mas a principal diferença é que não podem ser instanciados e, por isso, não têm variáveis de instância.

Para declarar um módulo, usas a palavra-chave module seguida do nome do módulo.

module Foo
end

Espaço de nomes

Um espaço de nomes é uma forma de agrupar código. Isso evita colisões de nomes e facilita perceber para que serve o código. Quando queres aceder a uma constante ou a uma classe que foi colocada dentro de um espaço de nomes, usas o operador ::.

module Foo
  class Bar
  end
end

Foo::Bar.new

Usá-lo como mixin

Isto pode ser útil quando, por exemplo, várias classes precisam da mesma funcionalidade "base" ou quando é preciso partilhar código entre classes não relacionadas. Ou quando queres partilhar código entre classes que não estão relacionadas.

Há duas formas diferentes de usar um módulo como mixin: a primeira é usar a palavra-chave include e a segunda é usar a palavra-chave extend.

Ambos os métodos tornam as constantes disponíveis para o tipo que inclui ou estende o módulo.

Include

O include disponibiliza todos os métodos do módulo como métodos de instância no tipo que inclui o módulo. A palavra-chave include deve ficar no início do tipo, seguida do nome do módulo.

module Foo
  def foo
    "foo"
  end
end

class Bar
  include Foo
end

Bar.new.foo # => "foo"

Extend

O extend funciona de forma semelhante ao include, mas em vez de disponibilizar os métodos como métodos de instância, disponibiliza-os como métodos de classe. A palavra-chave extend deve ser escrita no início do tipo, seguida do nome do módulo.

module Foo
  def foo
    "foo"
  end
end

class Bar
  extend Foo
end

Bar.foo # => "foo"

Extend self

Um padrão típico em Crystal usa o padrão extend self num módulo. Isto torna todos os métodos do módulo disponíveis como métodos de classe no próprio módulo. Isto significa que não precisas de atribuir cada método ao módulo com a sintaxe def self.method_name.

module Foo
  extend self

  def foo
    "foo"
  end
end

Foo.foo # => "foo"
Editar via GitHub A ligação abre numa nova janela ou separador

Aprende Módulos

A prática está bloqueada

Desbloqueia mais 2 exercícios para praticares Módulos