Ruby on Rails
do Básico ao Avançado
Aula 01
Introdução ao Ruby,
Instalação e Linguagem 1
Curso online de Ruby On Rails
Se você se inscreveu neste curso, obviamente está interessado em aprender
ou avançar seu conhecimento sobre Rails e a linguagem sobre qual o mesmo
foi criado. O nosso objetivo é ajudar você a alcançar este objetivo.
Ruby on Rails: Do Básico ao Avançado é um curso voltado tanto para
programadores que não possuem qualquer conhecimento de Rails, quanto para
aqueles programadores que já utilizam o Rails de alguma forma e querem
avançar o seu conhecimento em áreas nas quais talvez não estejam
aproveitando bastante o que o framework oferece.
O material que você começa a ler agora é inteiramente novo e preparado
especificamente para o curso. Tendo se matriculado no curso, você já sabe que
o mesmo é composto de aulas com material para estudo próprio que incluem
tanto partes teóricas como partes práticas, e aulas online, onde estaremos
interagindo para esclarecer dúvidas, explicar partes mais espinhosas do Ruby e
do Rails, e, de uma maneira geral, expandir sobre o que foi introduzido na aula
de estudo próprio anterior.
Esperamos que você não só aprenda como também se divirta bastante. Tanto
o Ruby quanto o Rails foram inventados por seus criadores não só para facilitar
suas vidas, mas também para retornar aos programadores o conceito de que a
programação, mesmo sendo o seu trabalho diário, pode ser divertida.
Sendo assim, abra o seu editor, escreva algum código e tenha um bom tempo
conosco!
História
Um curso de Ruby on Rails não poderia começar em outro lugar que não seja a
própria linguagem no qual o mesmo foi escrito. Sendo assim, começamos pelo
Ruby.
De uma linguagem basicamente desconhecida em 2004 a uma das linguagens
mais utilizadas atualmente, o Ruby percorreu um rápido e espetacular
caminho. Criada por Yukihiro “Matz” Matsumoto em 1993, a linguagem cresceu
rapidamente no Japão, terra de seu inventor, mas nunca chegou a ter
reconhecimento internacional até que um framework novo, chamado Rails,
conquistasse o mundo do desenvolvimento Web em meados de 2003.
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
2
Curso online de Ruby On Rails
Chamado simplesmente de Ruby on Rails, esse novo framework fazia um uso
inovador do Ruby e de suas características de meta-programação para
encaixar as peças do desenvolvimento Web em um todo coerente que poucas
vezes surgira no mercado. Desnecessário dizer, o Rails se tornou um sucesso
instantâneo trazendo o Ruby para a frente das câmeras e mostrando que
existiam outras linguagens, além das tradicionais, que podiam oferecer muito
ao programador interessado.
No Japão, o Ruby já era, inclusive, mais popular do que o Python. Sua
brilhante aplicação no Rails lhe deu um reconhecimento maior e o tornou a
ferramenta de escolha de milhões de programadores, não só para
desenvolvimento Web como basicamente para qualquer tarefa que exija uma
linguagem dinâmica e produtiva.
O sucesso atual do Ruby se deve, sem dúvida ao Rails. Sem o Rails, é provável
que o Ruby tivesse surgido eventualmente no cenário central das linguagens
de programação, mas sem todo o hype e visibilidade que o mesmo possui
atualmente. O que teria sido uma pena já que o Ruby, como mencionado
acima, é uma ferramenta fantástica não só para desenvolvimento Web mas
também para a miríade de tarefas que um programador precisa executar do
seu dia-a-dia.
Um dos motivos da criação do Ruby, segundo o seu inventor, foi o foco no
programador e na necessidade de maior produtividade com menor stress. De
acordo com Matz, as linguagens de programação são focadas em extrair o
máximo de performance da máquina na qual estão rodando, enquanto o Ruby
privilegia o máximo de performance para o programador.
Tudo isso dito, não se pode extrair a conclusão de que o Ruby seja a
linguagem perfeita. Como qualquer linguagem, o Ruby tem suas vantagens e
desvantagens e deve ser usada apropriadamente. Ainda assim, como
esperamos mostrar durante o curso, escolher o Ruby como uma linguagem a
mais para o seu currículo é algo que pode beneficiar qualquer programador.
Características
Até o momento não falamos das características do Ruby. Para isso, vamos usar
as palavras do seu próprio criador. Em uma tradução livre, ele diz o seguinte:
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
3
Curso online de Ruby On Rails
“O Ruby é uma linguagem de scripting interpretada cujo objetivo é tornar a
programação orientada a objetos simples e rápida. Como Perl, ela possui
muitas características de processamento de textos e acesso ao sistema. É
simples, direta, extensível e portável.”1
Quebrando isso em partes, o Ruby é antes de tudo uma linguagem de
propósito geral voltada para scripting, ou seja, para a realização daquelas
tarefas rápidas que tomariam um tempo enorme em outras linguagens não
específicas como C ou Pascal. Apesar disso, o Ruby é completamente orientado
a objetos, o que o torna extremamente poderoso e facilita a vida do
programador em muitos sentidos. É uma linguagem prática, como Perl, que
possui características inerentes para processamento de texto e acesso as
vários objetos do sistema operacional de modo a ajudar o programador em
todos os aspectos do seu uso diário. Finalmente, possui uma sintaxe simples e
extensível que ajuda programadores iniciantes e capacita programadores
experientes a extrair o máximo da mesma.
Ruby herdou quase todas suas características de duas linguagens díspares:
Perl e Smalltalk. Como Perl, Ruby possui as características práticas
mencionadas acima, e, como Smalltalk, Ruby possui características de
programação orientada a objetos e meta-programação que a levam a um nível
superior a muitas linguagens aparentemente equivalentes como PHP. Além de
Perl e Smalltalk, Ruby também tem um quê de Eiffel e Ada em sua sintaxe,
gerando código legível e de fácil manutenção.
Usando ainda o mesmo texto do qual a citação anterior foi extraída, Matz diz o
seguinte sobre as características do Ruby:
−
Possui sintaxe simples, inspirada em Eiffel e Ada;
−
Possui recursos para a captura de exceções, como Java e Python, que
tornam o tratamento de erros simples e direto;
−
Tudo na linguagem é um objeto. Isso significa que todo e qualquer dado
representado na linguagem é um objeto, como em Smalltalk. Não há
exceções. De tipos primitivos a objetos a classes, a representação é
coerente.
1 http://www2.ruby-lang.org/en/20020101.html
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
4
Curso online de Ruby On Rails
−
Sendo completamente orientada a objetos, Ruby não possui funções ou
procedimentos. Todos objetos possuem métodos (ou mensagens) que
recebem determinados parâmetros e causas mudanças de estado nesses
objetos. Mesmo os operadores como + e / são simplesmente métodos
disfarçados sintaticamente.
−
Todas as classes e objetos são abertos. Isso significa que mesmo as classes
básicas como String (que representa informação textual) e Fixnum (que
representa números inteiros) podem ser alteradas pelo programador.
Significa também que instâncias de uma classe podem ser modificadas para
se comportar diferentemente de outras instâncias. Finalmente, significa que
qualquer coisa pode ser redefinida. É possível, por exemplo, redefinir
operações matemáticas e criação de instâncias.
−
Ruby possui herança simples. Objetos são estendidos via módulos
conhecidos como mixins que são coleções de métodos. Isso significa que os
métodos de uma classe são apenas mensagens e que objetos diferentes
podem responder às mesmas mensagens facilitando o uso por parte do
programador.
−
Ruby possui closures 2 reais. Closures são funções que carregam consigo o
contexto no qual foram criadas. Isso permite programação e metaprogramação em um nível muito acima da maioria das linguagens
imperativas comuns. Significa também que você pode passar funções como
parâmetros, aumentando a capacidade da linguagem da forma que for
necessária.
−
Ruby possui blocos de execução de código que podem ser passados para
métodos como parâmetros ou convertidos em closures.
−
Ruby possui um garbage collector3 eficiente. Isso significa que
programadores não precisam se preocupar com gerenciamento de memória
de uma maneira geral.
−
Ruby pode ser estendido via C ou qualquer outra linguagem compilada se
necessário.
2 http://en.wikipedia.org/wiki/Closure_%28computer_science%29
3 http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
5
Curso online de Ruby On Rails
−
Variáveis em Ruby não precisam ser declaradas e são dinâmicas como o
resto da linguagem.
−
Ruby roda em basicamente qualquer sistema operacional de amplo uso
atualmente, incluindo qualquer Linux, Windows, e Mac OS X.
Existem outras características notáveis, mas essas já dão um bom exemplo do
que torna o Ruby uma linguagem interessante.
Todas as características acima serão exploradas ao longo do curso, de modo
que você poderá se familiarizar com as mesmas e extrair o máximo do que o
Ruby oferece.
Vantagens e Desvantagens
As características acima mostram que o Ruby possui bastante vantagens sobre
linguagens de longo uso do mercado.
Por exemplo, ao contrário de usuários de C ou Pascal, usuários de Ruby não
precisam se preocupar em alocar memória—o Ruby toma conta dessa
necessidade e, com raras exceções, o programador pode se esquecer de que
memória real está sendo alocada, usada e descartada na execução de seus
programas.
Sendo completamente orientado a objetos, o Ruby fornece uma interface
comum para o programador que nunca o confunde. Todos objetos se
comportam da mesma maneira, todos objetos respondem a mensagens e
mesmo o “açúcar sintático” é coerentemente empregado ao longo da
implementação do Ruby.
O Ruby é dinâmico e reflexivo. O primeiro atributo significa que não há
restrições na linguagem sobre o tipo e a movimentação de dados ao longo da
execução de um programa. O segundo significa que é possível explorar todas
as características de um objeto, independentemente do mesmo ter sido criado
internamente pelo Ruby ou externamente pelo programador.
Todas essas vantagens não significam que o Ruby seja destituído de
desvantagens.
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
6
Curso online de Ruby On Rails
Para citar duas delas, o Ruby possui sua própria implementação interna de
threading4 . Embora isso a torne portável a todas plataformas onde o Ruby
está, significa também o Ruby não consegue aproveitar tão bem sistemas
multi-processados sem esforço por parte do programador e que certas
condições de travamento e concorrência são mais difíceis de serem prevenidas.
É importante recordar que esta limitação ocorre somente quando se utiliza o
interpretador padrão do Ruby (que estaremos utilizando no curso e que é o
mais utilizado atualmente). Existem diversos projetos, que serão discutidos
mais tarde, que trabalham para melhorar esta implementação interna de
threading, como o JRuby (do qual o Ruby utiliza a máquina virtual do Java para
ser executado), IronRuby (utilizando o framework .Net como base) e o MagLev
(do qual utiliza a máquina virtual GemStone de Smalltalk).
Uma outra desvantagem está no fato de que existem certas construções da
linguagem, como a sobrecarga de operadores, que são limitadas pela
implementação em C do Ruby, impedindo que algumas características
avançadas da linguagem sejam exploradas.
Essas duas e as outras desvantagens do Ruby (como, por exemplo, o fato de
que hoje sua máquina virtual é mais lenta que as equivalentes de Python e
Perl) não devem ser um motivo de impedimento para o uso da linguagem.
Primeiro porque poucas vezes elas impactam o desenvolvimento e, quando
impactam, soluções alternativas existem para uso no Ruby ou em conjunção
com outras linguagens. Segundo, porque – como já foi explicado sobre as
threads – as mesmas já estão sendo resolvidas em novas implementações do
Ruby como JRuby, IronRuby, MagLev e Ruby 1.9 (que já foi lançado em 2009 e
pronta para produção).
Agora que conhecemos mais do Ruby, podemos passar para o aspecto prático
que é a instalação do mesmo. Aqui começa a nossa aventura. Mais uma vez,
divirta-se!
4 http://en.wikipedia.org/wiki/Green_threads
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
7
Curso online de Ruby On Rails
Instalação
Vamos caminhar passo a passo sobre as formas de instalar o interpretador do
Ruby nas principais plataformas: Mac OS X, Linux e Windows. Além de
conhecer algumas ferramentas de edição do código Ruby.
Atualmente o Ruby se encontra na versão 1.9, que é totalmente estável e
pronta para ser utilizada em ambientes de produção. Porem nosso tutorial será
para a instalação do Ruby 1.8.7, que ainda é a versão mais utilizada. Vamos
optar por esta versão pois como estamos em momento de transição da
linguagem, é mais fácil para os iniciantes encontrarem material na internet,
livros e código de terceiros que ainda não estão na versão mais atual.
Mac OS X
Vamos começar pelo mais simples, o sistema operacional da Apple. Em um
esforço de tornar o Mac OS uma excelente plataforma de desenvolvimento, a
Apple já inclui o Ruby, Rails e diversas outras bibliotecas (chamadas de Gems)
em seu sistema. Não é necessário instalar nada, apenas fazer as devidas
atualizações.
Primeiro vamos atualizar o RubyGems, que é algo semelhante a um
gerenciador de pacotes mas voltado exclusivamente para bibliotecas Ruby de
terceiros. Abra o Terminal que se encontra em Applications/Utilities e execute:
sudo gem update --system
Agora podemos atualizar as Gems. O Rails é uma Gem, então com o comando
baixo também baixamos e atualizamos o Rails para sua última versão
(atualmente 2.3.5):
sudo gem update
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
8
Curso online de Ruby On Rails
Linux
Para a instalação do Ruby no Linux utilizamos os gerenciadores de pacote que
acompanham o sistema. Estou utilizando o Ubuntu 9.10 Karmic Koala. Em
Applications/Acessories/Terminal execute os dois comandos abaixo:
sudo apt-get update
sudo apt-get dist-upgrade
O comando acima apenas atualiza o nosso Ubuntu. Agora é hora de instalar o
Ruby, mas como algumas gems (bibliotecas de terceiros) importantes precisam
ser compiladas é necessário que você execute o comando abaixo:
sudo apt-get install build-essential
Com o “campo preparado” podemos instalar o Ruby:
sudo apt-get install ruby ri rdoc mysql-server libmysql-ruby ruby1.8-dev irb1.8
libdbd-mysql-perl libdbi-perl libmysql-ruby1.8 libmysqlclient15off libnetdaemon-perl libplrpc-perl libreadline-ruby1.8 libruby1.8 mysql-client-5.1 mysqlcommon mysql-server-5.1 rdoc1.8 ri1.8 ruby1.8 irb libopenssl-ruby libopensslruby1.8 libhtml-template-perl mysql-server-core-5.1 libmysqlclient16
libreadline5 psmisc
Parece muita coisa porém apenas 4 destes pacotes são obrigatórios, mas já
estou instalando os que provavelmente você irá utilizar no dia a dia do
desenvolvimento Ruby. Um dos pacotes instala o mysql, caso você ainda não o
tenha feito ele irá pedir para escolher uma senha.
Concluído o passo acima, agora precisamos instalar o RubyGems, que não vem
por padrão no pacote. Execute os comandos a baixo, um a cada vez:
wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
tar xvzf rubygems-1.3.5.tgz
cd rubygems-1.3.5
sudo ruby setup.rb
Agora você pode remover o arquivos de instalação com:
rm -rf rubygems-1.3.5.tgz rubygems-1.3.5/
Agora é necessário criar alguns links para que o comando gem esteja acessível
de qualquer local do sistema:
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
9
Curso online de Ruby On Rails
sudo
sudo
sudo
sudo
sudo
ln
ln
ln
ln
ln
-s
-s
-s
-s
-s
/usr/bin/gem1.8 /usr/local/bin/gem
/usr/bin/ruby1.8 /usr/local/bin/ruby
/usr/bin/rdoc1.8 /usr/local/bin/rdoc
/usr/bin/ri1.8 /usr/local/bin/ri
/usr/bin/irb1.8 /usr/local/bin/irb
Agora basta executar
sudo gem install rails
Windows
Para o windows vamos utilizar um instalador, já que o sistema operacional não
possui um compilador GCC e nem um gerenciador de pacotes.
Para solucionar este problema do sistema operacional existem vários projetos
que já compilam o Ruby para o Windows. O mais famoso é Ruby One Click
Installer, basta acessar o site do projeto (http://rubyinstaller.org/) e fazer
download do arquivo ruby186-27_rc2.exe. Também existe a versão para
Ruby 1.9 mas como eu disse anteriormente, vamos instalar o 1.8.
Basta executar o arquivo, e avançar até concluir a instalação, porém é muito
importante que na tela de escolha dos componentes (choose components)
você não se esqueça de marcar a opção Enable RubyGems. Para o restante
da instalação não é necessário mudar nada.
Mas existe o pequeno porem que o One Click Installer instala o Ruby 1.8.6. Se
você desejar atualiza-lo para o 1.8.7 acesse o site do Ruby em Downloads
(http://www.ruby-lang.org/en/downloads/) e baixe o Ruby 1.8.7 binário, em
seguida descompacte-o na pasta onde o Ruby One Click Installer colocou o
Ruby, sobre-escrevendo seu conteúdo.
Agora precisamos instalar o Rails. Abra o Prompt do MS-DOS( iniciar/executar/
cmd ) e digite:
gem update --system
Depois de atualizado o RubyGems vamos atualizar as gems o One Click já
trouxe instalado, execute:
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
10
Curso online de Ruby On Rails
gem update
Agora é hora de instalar o Rails:
gem install rails
Concluido este passo também precisamos instalar o SQLite, que para facilitar
prototipagem rápida, é o banco escolhido por padrão pelo Rails.
Baixe os arquivos binários para windows sqlite-XXXX.zip e sqlitedll-XXXX.zip
(onde XXXX é a versão) em http://www.sqlite.org/download.html e
descompacte ambos os arquivos
em c:\windows\system32 e execute o comando abaixo no prompt:
gem install sqlite3-ruby -v=1.2.5 --no-ri --no-rdoc
Concluindo o passo acima tanto o Ruby quanto o Rails estarão instalados.
Também existem outras formas de instalação no Windows, e uma que merece
ser lembrada é o projeto brasileiro Easy-Rails (http://rubyforge.org/projects/
easy-rails/) que permite instalar Ruby e o Rails apenas descompactando um
arquivo, o que torna o projeto perfeito para instalação em faculdades,
laboratórios ou até mesmo carregar o eco-sistema Ruby no pendrive.
Testando a Instalação
Depois de instalado o Ruby e Rails, podemos começar os estudos. Execute os
comandos abaixo no console:
ruby -v
A resposta será versão do Ruby que acabamos de instalar, você pode também
checar a versão do Rails com o comando rails -v .
Para testes com a linguagem, o Ruby possui o IRB, um console interativo.
Basta digitar irb no console, como abaixo:
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
11
Curso online de Ruby On Rails
Para sair do IRB digite quit ou exit. Agora vamos criar o primeiro aplicativo
Rails, também no console digite o comando abaixo:
rails nome_do_projeto
Se você instalou tudo corretamente o Rails vai gerar uma série de arquivos
dentro da pasta do nome_projeto que você escolheu. Navegue para dentro
desta pasta e digite:
ruby script/server
Como no Rails não é necessário instalar um servidor web para começar a
desenvolver, o que o comando acima faz é iniciar o servidor que já vem por
padrão no Ruby e que o Rails tira proveito.
No navegador acesse http://localhost:3000/ e você verá algo como abaixo:
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
12
Curso online de Ruby On Rails
Editores e IDE’s
Agora que já temos o Ruby e o Rails instalados, só precisamos de uma forma
de editar o código fonte de nossos projetos.
Qual ferramenta utilizar é um tema que sempre gera bastante discussão, pois
diferente de outras linguagens o Ruby não exige o uso de uma IDE. No
desenvolvimento Ruby, a única coisa que é realmente essencial é uso do
console para fazer chamadas simples como fizemos acima.
No mundo Ruby o uso de IDE’s não é comum pois como a linguagem é bem
simples, você não terá dificuldades para decorar os comandos e conhecer a API
do Ruby. Outro fator que diminui a popularidade de IDE’s é que por ser uma
linguagem interpretada não é necessário compilar e nunca será possível
conseguir um auto-complete perfeito por ser dinâmica. IDE’s no mundo Ruby
também perdem o valor rapidamente pois tanto a linguagem como os
frameworks estilo o Rails são atualizados com frequencia, o que faz com que
as IDE’s parem de funcionar.
Mas o que é mais importante entender que principalmente para o iniciantes as
IDE’s atrapalham o aprendizado já que abstraem a necessidade de usar
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
13
Curso online de Ruby On Rails
console, criando wizards que fazem o mesmo que os comandos simples que
executamos no terminal, tornando o desenvolvedor dependente da IDE e sem
entender o que realmente está acontecendo.
O que a maioria dos Rubistas mais experientes utilizam são editores de textos
mais robustos que permitem colorização, snippets e automatização de tarefas.
Para usuários do Mac OS X recomendo o uso do Textmate, mas também são
populares o Emacs, GVim e GEdit. No Linux os mais utilizados são GEdit, GVim
e Emacs. Para os usuários do Windows recomendo os mesmos navegadores
(GEdit, GVim e Emacs), também existe o E-TextEditor que é muito bom.
A opção mais simples e que funciona em qualquer um dos sistemas
operacionais é o GEdit com o plugin brasileiro GMate, basta baixar o GEdit em .
E para mais informações sobre o GMate acesse: http://blog.siverti.com.br/
gmate/ e para download http://github.com/lexrupy/gmate/tarball/master
(instruções de instalação no arquivo Readme)
Mas se você não abre mão de uma IDE a mais recomendada é o RubyMine
(http://www.jetbrains.com/ruby/) mas também pode ser usado o Netbeans,
Aptana ou Eclipse.
A Linguagem
Classes, Objetos e Variáveis
Considerando que o Ruby é completamente orientado a objetos, nada mais
apropriado que começar nossa exploração do mesmo por essa parte. A
primeira coisa que precisamos no nosso processo de compreensão do Ruby é
entender como variáveis funcionam. No Ruby, como na maior parte das
linguagens orientadas a objeto, as variáveis são simplesmente referências a
objetos. Veja o exemplo abaixo:
irb(main):001:0> a = 1
=> 1
irb(main):002:0> a = "1"
=> "1"
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
14
Curso online de Ruby On Rails
No exemplo acima, atribuímos o valor inteiro 1 à variável a e depois atribuímos
à mesma variável, o valor “1”, que é uma seqüência de caracteres. Isso, e o
fato de que nenhum erro ocorreu, demonstram duas coisas sobre o Ruby.
Primeiro variáveis simplesmente apontam para os valores atribuídos à mesma,
e, por causa disso, podem ser re-atribuídas de acordo com necessidade;
segundo variáveis não precisam ser declaradas.
Um exemplo posterior poderia ser:
irb(main):001:0>
=> 1
irb(main):002:0>
=> Fixnum
irb(main):003:0>
=> "1 "
irb(main):004:0>
=> String
a = 1
a.class
a = "1 "
a.class
Note que mesmo tipos primitivos como o número inteiro 1 são membros de
uma classe—no caso Fixnum, que é a classe que define números com
representação fixa.
Considere agora o seguinte trecho de código:
irb(main):001:0> 1.class
=> Fixnum
irb(main):002:0> 1.class.class
=> Class
irb(main):003:0> 1.class.superclass
=> Integer
irb(main):004:0>
Note que 1 é uma instância da classe Fixnum. A classe Fixnum, por sua vez, é
também um objeto, uma instância da classe Class, que define todas as classes
em Ruby. Class é chamada a metaclasse de Fixnum, ou seja, é uma classe que
descreve uma classe. Na terceira linha temos outro conceito de orientação a
objetos que é a superclasse de uma classe, ou seja, a classe da qual a mesma
é derivada. No caso de Fixnum, temos a seguinte hierarquia: Object =>
Numeric => Integer => Fixnum.
Esses dois conceitos, metaclasses e superclasses, são importantes em
qualquer linguagem orientada a objeto e precisam ser compreendidos por
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
15
Curso online de Ruby On Rails
qualquer programador. Para entender melhor esses conceitos, responda as
seguintes questões:
Exercício 1
1. Qual é a classe base de todos objetos Ruby?
2. Qual é a metaclasse base de todas as classes Ruby?
Agora que já vimos um pouco de variáveis em Ruby, podemos começar a
utilizá-las com maior confiança. Como mencionado anterior e demonstrado
acima, todo valor em Ruby é uma instância de uma classe e possui os
métodos próprios dessa classe. Por exemplo:
irb(main):001:0>
=> "1"
irb(main):002:0>
=> 2
irb(main):003:0>
=> 2
irb(main):004:0>
=> 1
irb(main):005:0>
=> 3
1.to_s
1 + 1
1.+(1)
-1.abs
"123".length
No exemplo acima, temos várias invocações de métodos de determinados
objetos. O primeiro método invocado, to_s, converte um valor númerico em
uma string correspondente. O segundo exemplo é ainda mais interessante.
Note que fizemos uma operação, somando dois números. Mas, como podemos
ver logo abaixo, a operação é simplesmente uma invocação de um método do
objeto.
Obviamente que, para uso diário, utilizaremos a primeira sintaxe. É
importante, porém, compreender que isso é válido para basicamente todos os
métodos do Ruby e que isso pode ser usado em suas próprias classes.
Uma maneira fácil de visualizar os métodos que uma classe possui é chamar o
seu método methods, como pode ser visto abaixo:
~$ irb
irb(main):001:0> 1.methods
=> ["%", "inspect", "<<", "singleton_method_added", "&", "clone", ">>", "ceil",
"public_methods", "instance_variable_defined?", "div", "equal?", "freeze",
"times", "*", "+", "to_i", "methods", "respond_to?", "-", "upto", "between?",
"prec", "round", "/", "method", "dup", "instance_variables", "__id__", "divmod",
"chr", "succ", "|", "eql?", "integer?", "~", "id", "to_f", "singleton_methods",
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
16
Curso online de Ruby On Rails
"send", "prec_i", "taint", "truncate", "to_int", "frozen?",
"instance_variable_get", "__send__", "^", "instance_of?", "modulo", "to_a",
"object_id", "+@", "zero?", "-@", "type", "**", "<", "protected_methods", "<=>",
"instance_eval", "==", "prec_f", "quo", ">", "===", "step", "id2name", "size",
"instance_variable_set", "kind_of?", "remainder", "extend", ">=", "nonzero?",
"next", "to_s", "<=", "coerce", "hash", "floor", "class", "tainted?", "=~",
"private_methods", "display", "fdiv", "nil?", "untaint", "downto", "to_sym",
"[]", "is_a?", "abs"]
Esses são todos os métodos públicos compartilhados pelas instâncias da classe
Fixnum. Como classes podem possuir métodos públicos, protegidos e privados,
a distinção pode ser obtida invocando os métodos public_methods,
protected_methods e private_methods de uma instância qualquer.
Incidentemente, classes são objetos também, com seus próprios métodos.
Você pode observar isso invocando o método acima em uma classe, usando,
por exemplo:
~$ irb
irb(main):001:0> String.public_methods
=> ["inspect", "private_class_method", "const_missing", "clone",
"public_methods", "public_instance_methods", "instance_variable_defined?",
"method_defined?", "superclass", "equal?", "freeze", "included_modules",
"const_get", "autoload?", "methods", "respond_to?", "module_eval",
"class_variables", "method", "dup", "protected_instance_methods",
"instance_variables", "public_method_defined?", "__id__", "eql?", "const_set",
"id", "singleton_methods", "send", "class_eval", "taint", "frozen?",
"instance_variable_get", "include?", "private_instance_methods", "__send__",
"instance_of?", "private_method_defined?", "to_a", "object_id", "name", "type",
"new", "<", "protected_methods", "instance_eval", "<=>", "==", ">", "===",
"instance_variable_set", "kind_of?", "extend", "protected_method_defined?",
"const_defined?", ">=", "ancestors", "to_s", "<=", "public_class_method",
"autoload", "allocate", "hash", "class", "instance_methods", "tainted?", "=~",
"private_methods", "class_variable_defined?", "display", "nil?",
"instance_method", "untaint", "constants", "is_a?"]
Aqui cabe uma explicação sobre uma diferença do Ruby para outras linguagens
orientadas a objetos.
Métodos públicos são métodos acessíveis a todo o programa. Métodos
protegidos são acessíveis somente a instâncias da própria classe e subclasses
da mesma. Em Ruby, porém, métodos privados possuem uma distinção sutil:
eles somente podem ser chamados com um receptor explícito, ou seja, dentro
do próprio objeto. Isso significa que subclasses podem também chamar os
métodos privados de sua superclasse, mas somente dentro do seu próprio
contexto de execução.
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
17
Curso online de Ruby On Rails
Objetos, como instâncias de classes, podem ser criados implicitamente ou
explicitamente em Ruby. Acima, vimos alguns exemplos de criação implícita,
que é comum a todos os tipos primitivos. A criação explícita, porém, é feita
através da invocação do método new:
~$ irb
irb(main):001:0> a = "Uma string qualquer"
=> "Uma string qualquer"
irb(main):002:0> b = String.new("Uma string qualquer")
=> "Uma string qualquer"
irb(main):003:0> a == b
=> true
irb(main):004:0> require 'date'
=> true
irb(main):005:0> d = Date.new(2007, 1, 1)
=> #<Date: 4908203/2,0,2299161>
irb(main):006:0> d.day
=> 1
irb(main):007:0> d.year
=> 2007
Note que nas primeiras declarações criamos uma string de maneira implícita e
de maneira explícita. Uma comparação entre as duas revela que não há
diferença na criação, ou seja, a criação implícita é essencialmente o mesmo
que uma chamada ao método new seguida de uma atribuição.
No exemplo seguinte, temos a criação de um objeto que não possui criação
implícita. Note também que o objeto não faz parte do núcleo do Ruby, mas é
implementado em uma biblioteca externa que é adquirida para o contexto
atual através do método require. Esse método, embora seja invocado
aparentemente sem um objeto receptor, é na verdade um método do módulo
Kernel, incluindo na classe Object, que provê uma série de métodos comuns
para o ambiente de execução Ruby. Veremos mais sobre módulos em seções
seguintes.
Como podemos notar de tudo o que foi visto acima, o Ruby é realmente uma
linguagem orientada a objetos em toda a sua extensão. Todo valor criado é
uma instância de uma classe qualquer, mesmo as próprias classes.
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
18
Curso online de Ruby On Rails
Exercício 2
1. O Ruby possui um método chamado object_id, comum a todas as classes
e objetos. O que esse método faz?
2. Faça um teste, criando duas variáveis inteiras atribuindo o mesmo valor
númerico. Compare os object_id das mesmas. Qual é o resultado?
3. Faça o mesmo teste com duas variáveis String. Qual é o resultado
agora?
Agora que trabalhamos um pouco com os conceitos básicos de classes, objetos
e variáveis, é hora de criar as nossas próprias classes, experimentando um
pouco mais com o sistema de objetos do Ruby. Criar uma classe é bem simples
em Ruby. Basta fazer o seguinte:
class Entity
def initialize(type, name)
@type = type
@name = name
end
end
O código acima define uma classe chamada Entity que possui um método
chamado initialize. Esse método possui uma conotação especial em Ruby,
sendo o método que é invocado quando a instância de uma classe é criada
(também conhecido como construtor). Vejamos isso em um exemplo:
samwise = Entity.new(:hobbit, "Samwise Gamgi")
gandalf = Entity.new(:istari, "Galdalf, the Grey")
O código acima cria duas instâncias da classe Entity, atribuindo os parâmetros
a variáveis de instância da classe (identificadas pelo sinal @ na frente dos
seus nomes). Note que new é usado e não initialize, sendo que este último é
invocado automaticamente. Esse é um detalhe de implementação do Ruby,
sendo que o método initialize é automaticamente marcado com private.
Explorando essas classes no irb, teríamos algo assim:
irb(main):001:0> samwise = Entity.new(:hobbit, "Samwise Gamgi")
=> #<Entity:0xb7d634c4 @name="Samwise Gamgi", @type=:hobbit>
Caso você não queira ficar colando o código a todo momento, salve um arquivo
com um nome qualquer e a extensão .rb e use o método load para carregar
esse arquivo, lembrando que load requer o nome completo do arquivo a
carregar, incluindo a extensão.
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
19
Curso online de Ruby On Rails
Note que o Ruby fornece uma representação interna do objeto para fácil
visualização. Na representação acima, a classe do objeto é exibida, seguida de
seu endereço em memória. Depois, temos as variáveis internas do objeto com
seus valores. Você deve estar se perguntando o que os dois pontos na frente
de um nome—como :hobbit, por exemplo—significam. Nomes atribuídos assim
são chamados de símbolos e veremos mais sobre eles adiante. Por hora, basta
dizer que são representações eficientes de um valor qualquer.
Note que se você tentar extrair o valor de uma variável de instância acima,
você verá um erro. Por exemplo:
irb(main):001:0> samwise.name
NoMethodError: undefined method `name' for #<Entity:0xb7d634c4 @name="Samwise
Gamgi", @type=:hobbit>
from (irb):11
from :0
Variáveis de instância são automaticamente internas(privadas) e você só pode
extrair o valor das mesmas publicamente criando um método específico para
isso.
Falando em métodos, podemos criar um método para a nossa classe para ver
com os mesmos funcionam. Para isso, vamos substituir a inconveniente
representação textual acima por uma de nosso interesse. Isso é feito criando
um método chamado to_s, que já mencionamos anteriormente. Esse método
converte um objeto qualquer em sua representação textual. Todos objetos em
Ruby possuem esse método, embora sua implementação inicial seja bem
limitada.
Vejamos para o objeto acima:
irb(main):001:0> samwise.to_s
=> "#<Entity:0xb7d634c4>"
Podemos sobrescrever o método assim:
class Entity
def initialize(type, name)
@type = type
@name = name
end
def to_s
"#{@name} is a #{@type}"
end
end
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
20
Curso online de Ruby On Rails
O código acima apresenta algumas características interessantes. Primeiro, ele
retorna a representação textual do objeto, mas sem invocar qualquer
expressão de retorno. Ruby possui, realmente, uma expressão return, mas a
mesma não precisa ser usada na maior parte dos casos. Isso acontece porque
qualquer expressão em Ruby retorna automaticamente um valor. Se o valor
não é explicitamente retornado, o valor nil é usado implicitamente. Isso
significa que um método retorna o resultado de sua última expressão, sem
necessidade de chamar return.
No método acima, estamos retornando também uma string, usando o que é
chamado de interpolação de valores. Qualquer expressão entre os
delimitadores #{} dentro de uma string será executada e seu valor
representacional retornado—isto é—o método to_s do valor resultante é
invocado automaticamente. Veja o resultado do método acima:
irb(main):001:0> samwise = Entity.new(:hobbit, "Samwise Gamgi")
=> #<Entity:0xb7dc0958 @name="Samwise Gamgi", @type=:hobbit>
irb(main):002:0> samwise
=> #<Entity:0xb7dc0958 @name="Samwise Gamgi", @type=:hobbit>
irb(main):003:0> samwise.to_s
=> "Samwise Gamgi is a hobbit"
irb(main):004:0> "#{samwise}"
=> "Samwise Gamgi is a hobbit"
irb(main):005:0> puts samwise
Samwise Gamgi is a hobbit
=> nil
Note que to_s agora é usado implicitamente onde uma representação textual
de um objeto é exigida. Uma pequena exceção é a exibição do objeto no irb,
onde to_s não é invocado diretamente para prover detalhes de implementação.
Note que no final, ao invocarmos puts, o valor é impresso na tela e nil é
retornado. Isso ocorre porque puts envia seus parâmetros à saída padrão e
retorna nil, ou seja, não retorna nada específico.
Voltando à questão dos atributos, se quisermos torná-los manipuláveis,
podemos usar a seguinte implementação:
class Entity
def initialize(type, name)
@type = type
@name = name
end
def to_s
"#{@name} is a #{@type}"
end
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
21
Curso online de Ruby On Rails
def name
@name
end
def type
@type
end
def name=(value)
@name = value
end
def type=(value)
@type = value
end
end
Isso permite o seguinte código:
irb(main):001:0> samwise = Entity.new(:hobbit, "Samwise Gamgi")
=> #<Entity:0xb7da02d4 @name="Samwise Gamgi", @type=:hobbit>
irb(main):002:0> samwise.name
=> "Samwise Gamgi"
irb(main):003:0> samwise.type
=> :hobbit
irb(main):004:0> samwise.name = "Samwise, the Brave"
=> "Samwise, the Brave"
irb(main):005:0> samwise.name
=> "Samwise, the Brave"
irb(main):006:0> samwise.to_s
=> "Samwise, the Brave is a hobbit"
Note que agora temos métodos que podemos usar para obter ou mudar o valor
de um atributo do objeto. Os métodos que mudam o valor possuem um sinal
de igual (=) em seu nome e são usados automaticamente pelo Ruby em caso
de atribuição como o exemplo demonstra.
Exercício 3
1. Existe alguma diferença entre “objeto.atributo = valor” e
“objeto.atributo=(valor)”?
2. Repetir o código acima para cada atributo de um objeto seria tedioso.
Existe uma forma do Ruby de evitar a repetição?
Obviamente, pela maneira como atributos são implementados em Ruby, a
representação externa não precisa corresponder à interna. É o caso da classe
Date por exemplo, que guarda uma representação interna da data informada,
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
22
Curso online de Ruby On Rails
mas permite que as instâncias seja manipuladas em termos de diversos
atributos.
Como classes também são instâncias, elas podem ter métodos e atributos.
Digamos que precisamos saber todas os tipos já usados em entidades.
Podemos ter algo assim:
class Entity
@@types = []
def initialize(type, name)
@type = type
@name = name
@@types << @type unless @@types.include?(@type)
end
# ...
def self.types
@@types
end
end
A implementação acima cria uma variável de classe chamada types e registra,
a cada criação, se um novo tipo foi adicionado ao “universo” do mesmo. A
linha final do método initialize executa o seguinte: adiciona o type informado à
variável types a menos (unless) que o mesmo já exista na lista. Note também
o uso de self para especificar que o método pertence à classe e não a uma
instância (estamos criando um método de classe, semelhante aos métodos
static do Java).
Um exemplo de uso seria o seguinte:
irb(main):001:0> samwise = Entity.new(:hobbit, "Samwise Gamgi")
=> #<Entity:0xb7d94ca4 @name="Samwise Gamgi", @type=:hobbit>
irb(main):002:0> Entity.types
=> [:hobbit]
irb(main):003:0> gandalf = Entity.new(:istari, "Galdalf, the Grey")
=> #<Entity:0xb7d8cba8 @name="Galdalf, the Grey", @type=:istari>
irb(main):004:0> Entity.types
=> [:hobbit, :istari]
irb(main):005:0> frodo = Entity.new(:hobbit, "Frodo Baggins")
=> #<Entity:0xb7d86bb8 @name="Frodo Baggins", @type=:hobbit>
irb(main):006:0> Entity.types
=> [:hobbit, :istari]
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
23
Curso online de Ruby On Rails
Dois detalhes a serem observados aqui. Primeiro, variáveis de classes são
compartilhadas entre todas subclasses e a própria classe, o que significa que
se você mudá-la em uma subclasse, o valor será mudado, por assim dizer, em
todas outras, já que meramente aponta para a mesma variável. Esse é um
detalhe em que Ruby é diferente de outras linguagens. Segundo, variáveis de
classe usam @@ antes do seu nome. Se você declarar uma dessas variáveis
usando somente @, um caso especial de variável da instância da classe será
criado, com semântica diferente. Essa variável pertence somente àquela
instância e não é compartilhada.
Podemos agora nessa seção especificar o controle de acesso de uma classe.
Veja o seguinte:
class Test
public
def method1
end
protected
def method2
end
private
def method3
end
end
Ao contrário da maioria das linguagens orientadas a objeto, em Ruby public,
protected e private não simplesmente marcadores sintáticos. são métodos que
modificam a classe dinamicamente e mantém o escopo de acesso até que
outro escopo seja invocado. A classe acima poderia ser especificada assim com
o mesmo resultado:
class Test
def method1
end
def method2
end
def method3
end
public :method1
protected :method2
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
24
Curso online de Ruby On Rails
private :method2
end
Herança simples em Ruby é bastante trivial:
class B < A
end
A declaração acima indica que a classe B herda os métodos da classe A.
Variáveis de classe, variáveis de instância, e variáveis de instância de classe
seguem as regras descritas anteriormente. O mesmo para métodos públicos,
privados e protegidos.
No momento, não entraremos em detalhes sobre a herança porque ela é usada
minimamente da forma acima em Ruby, servindo mais para propagação rápida
de tipos. O método mais usado para estender classes díspares em Ruby é
chamado de mixin e será assunto de uma aula próxima.
Exercício 4
1. O que acontece se um método de uma superclasse for redeclarado em
uma subclasse?
2. Como em Ruby, pode-se invocar o método de uma superclasse em uma
subclasse ?
Respostas
Exercício 1
1. Object
2. Class
Exercício 2
1. Retorna um identificador numérico único para o objeto.
2. Temos o mesmo object_id para cada variável, isso ocorre pois
números inteiros são Fixnum’s com o mesmo id.
3. Cada objeto possui um object_id diferente pois cada instância da
class String faz referência para uma posição diferente.
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
25
Curso online de Ruby On Rails
Exercício 3
1. Não
2. Poderia ser utilizado o método attr_accessor para criar getter e
setter para os valores passados. Como abaixo:
attr_acessor :name, :type
Exercício 4
1. Este método será sobre-escrito.
2. Basta chamar o método normalmente de dentro da subclasse.
Criado por e-Genial Soluções Inteligentes – Todos os direitos reservados.
26
Download

01 - IntroducaoAoRuby