Escolhi tratar sobre esse assunto hoje simplesmente porque foi uma das primeiras coisas que me perguntei "como eu faço isso?" no mundo ruby. Acredito que muita gente se pergunte a mesma coisa e espero que eu possa ajudar em algo para elas. 😀
Bem, se você é um programador java, você chama sua gem de jar, se você é um programador C#, você chama de dll. Resumindo, é uma lib, uma biblioteca contendo códigos que você pode reaproveitar importando em outros projetos.
E usar gems no ruby é muito fácil, se você já deu uma brincada com rails por exemplo, é só você adicionar o código gem 'nome_da_gem'
no arquivo Gemfile
que está no root, depois executar o comando bundle install
para baixar sua gem do repositório e pronto, só sair usando a biblioteca!
Para mais detalhes do que é e como funciona uma gem, veja os guias no site do rubygems, que é o repositório global de gems ruby! Aliás, nesses guides você encontra tudo o que vou falar, mas vou tentar falar de uma maneira mais resumida pra você mandar ver bem rápido!
Então, vou seguir uma linha de tutorial relâmpago para você criar uma gem, pulando vários steps que seriam interssantes, como testes com rspec ou coisas assim, mas vou deixar isso para um próximo post.
Mas primeiro vamos aos pré-requisitos né. Para esse "tutorial" você deve ter ao menos uma instalação básica do ruby, que consiste do ruby em si, do RubyGems e do Bundler. Todos estes vem instalados normalmente com os pacotes que você baixa por aí do ruby.
Tendo isto instalado, aqui vamos nós:
O primeiro passo claro é criar o diretório do projeto. Para isso o Bundler tem um helper que ajuda muito a seguir as boas práticas que são citadas nos guias do RubyGems. Apenas execute o comando:
PS.: Troque o kelvinst no commando pelo seu nickname se quiser postar a gem no repositório global! Lá o nome da sua gem deve ser único. 😁
$ bundle gem hello_kelvinst
create hello_kelvinst/Gemfile
create hello_kelvinst/Rakefile
create hello_kelvinst/.gitignore
create hello_kelvinst/hello_kelvinst.gemspec
create hello_kelvinst/lib/hello_kelvinst.rb
create hello_kelvinst/lib/hello_kelvinst/version.rb
Initializating git repo in /Users/kelvinst/hello_kelvinst
Pronto! 🎉 Você gerou um diretório para sua gem. Sinta-se livre para botar isso em um repositório no Github. 😉
Como você já deve ter percebido, foi criado um arquivo com a extensão .gemspec
dentro do root do seu projeto. Esse arquivo contém basicamente as especificações da gem, nele você configura qual o nome da gem, um resuminho e tudo mais.
Se você abrir o arquivo, você vai ver que nele tem vários TODOs para alguns itens da especificação. Então vamos fazer o que ele está pedindo! Vamos atribuir as especificações!
Olha como ficou o meu:
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'hello_kelvinst/version'
Gem::Specification.new do |spec|
spec.name = "hello_kelvinst"
spec.version = HelloKelvinst::VERSION
spec.authors = ["kelvinst"]
spec.email = ["[email protected]"]
spec.summary = "A hello gem to the ruby world"
spec.description = "I just created this gem to say hello for the ruby gems world, okay."
spec.homepage = ""
spec.license = "MIT"
spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.7"
spec.add_development_dependency "rake", "~> 10.0"
end
Se quiser copiar as descrições, está tudo bem, a licensa é MIT que é bem permissiva, hehehe. 😆
Você deve ter visto que tem um monte de coisa neste .gemspec
que eu não falei né. Então, vou deixar isso para uma próxima, vou focar primeiro em como criar a gem e publicar ela pro mundo.
Agora ao que interessa! Uma gem só é uma gem se tiver algo que ela faça, e a nossa até agora não passa de uma mera especificação. Então vamos por a mão na massa de verdade.
Todo o código ruby de uma gem é por padrão colocado dentro da subpasta lib
. Se você abrir ela verá que lá tem basicamente:
- Uma pasta com o nome
hello_kelvinst
, que é a pasta onde você deve colocar todo e qualquer arquivo a mais que vá existir na sua gem. - Um arquivo com o nomehello_kelvinst.rb
, que é o único arquivo que deve existir no root da lib. Isso porque alib
do sua gem vira oroot
de qualquer outro projeto que tenha importado ela, logo se você colocar arquivos na sua lib que conflite com nomes de arquivos que já existem, como por exemploerb.rb
, quando um usuário tentar executar umrequire 'erb'
para carregar o arquivo da lib erb, ele estará carregando o seu arquivo, o que é um comportamento inesperado.
Agora voltando: vamos editar o arquivo hello_kelvinst.rb
e colocar nele o código que a nossa gem deve ter! O meu eu fiz assim:
require "hello_kelvinst/version"
class Hello
def say!
puts 'hello'
end
end
Simple enough! Nada mais nada menos, isso que eu ainda compliquei deixando em uma classe, mas tudo bem, assim vai.
Bom, agora nosso projeto está terminado. Todo o código está pronto, só falta entregar (e testar, mas isso eu já disse que não vou fazer).
E pra empacotar sua gem é mais complicado, temos que executar o comando:
$ gem build hello_kelvinst.gemspec
WARNING: no homepage specified
WARNING: See http://guides.rubygems.org/specification-reference/ for help
Successfully built RubyGem
Name: hello_kelvinst
Version: 0.0.1
File: hello_kelvinst-0.0.1.gem
🎉🎉🎉
É, é só isso. 😁 Um arquivo .gem
foi gerado no root do seu projeto, e essa é sua gem.
Para usar a gem também é bem difícil! hehehe...
Primeiro tem que instalar ela:
$ gem install hello_kelvinst-0.0.1.gem
Successfully installed hello_kelvinst-0.0.1
Parsing documentation for hello_kelvinst-0.0.1
Installing ri documentation for hello_kelvinst-0.0.1
Done installing documentation for hello_kelvinst after 0 seconds
1 gem installed
E depois podemos usá-la na linha de comando interativa mesmo:
$ irb
2.1.3 :001 > require 'hello_kelvinst'
=> true
2.1.3 :002 > hello = Hello.new
=> #<Hello:0x00000001e49e30>
2.1.3 :003 > hello.say!
hello
=> nil
Viu que para usá-la você primeiro tem que dar require né? A não ser que você esteja importando ela pelo Bundler, que é assunto para outro post, mas basicamente, para importar a sua gem em um projeto rails, é necessário apenas colocar a linha gem 'hello_kelvinst'
no Gemfile
do seu projeto.
Aaaaah! Mas daí ele vai baixar a minha gem daonde quando eu rodar um bundle 'install'
? Calma lá, é esse o último tópico!
O repositório global de gems é o rubygems.org, que eu já referenciei no post (lá estão os guides também). E para botar a sua gem lá é tão difícil quanto tudo o que já foi feito até agora!
Primeira coisa que você deve fazer, é acessar o site e se registrar. Depois de registrado é só executar o comando gem push hello_kelvinst-0.0.1.gem
e informar o email e senha do rubygems.org:
$ gem push hello_kelvinst-0.0.1.gem
Enter your RubyGems.org credentials.
Don't have an account yet? Create one at https://rubygems.org/sign_up
Email: [email protected]
Password:
Signed in.
Pushing gem to https://rubygems.org...
Successfully registered gem: hello_kelvinst (0.0.1)
E pronto! Sua gem está no repositório global! Agora sempre que alguem quiser pode executar o comando gem install hello_kelvinst
e vai baixar a sua gem! PS.: Só lembrando, a gem tem que ter um nome único para poder estar no repositório, logo hello_kelvinst
já não dá mais.
Espero que tenha gostado do tutorial e que você se empolgue para montar mais e mais gems! O mundo ruby agradece!
O projeto com a gem hello_kelvinst
que criei neste tutorial está publicado no github neste repositório. Se não quiser seguir o tutorial mas mesmo assim dar uma olhada em como é um diretório de uma gem, já vale a pena pra ter uma noção. 😉
Obrigado quem leu até aqui e até mais!
Muito bom Kelvin!
Obrigado pelo gist