Sumário
- Histórico
- Principais características
- Palavras reservadas, variáveis e escopo
- Tipos de dados
- Estruturas de control
- Módulos
- Abstração
- Paradigmas
Histórico
A linguagem teve sua criação iniciada em fevereiro de 1993 por Yukihiro Matsumoto, mais conhecido como Matz, que pretendia criar uma nova linguagem misturando programação funcional com programação imperativa e que fosse mais poderosa do que Perl e mais orientada a objetos do que Python. Assim, em 1995, Ruby foi apresentada ao público.
Após o lançamento da versão 1.9 em 1993, iniciou-se a primeira lista de discussão em inglês, chamada Ruby-Talk. E com a ajuda de Dave Thomas e Andy Hunt foi lançado em setembro de 2000 o primeiro livro em inglês, programming ruby, que foi impresso e posteriormente liberado gratuitamente para o público, ajudando a popularizar o ruby.
Características
- Orientação a objetos - Tudo em Ruby é um objeto, não existindo tipos primitivos.
- Herança simples - Uma classe pode herdar estados e comportamentos apenas de uma única classe.
- Metaprogramação - É a capacidade de escrever ou manipular outros programas em tempo de execução.
- Interpretada - O código não necessita de compilação, é interpretado por uma máquina virtual.
Palavras reservadas, variáveis e escopo
BEGIN | case | if | or |
break | else | not | self |
do | for | return | unless |
false | nil | undef | begin |
next | retry | yield | defined? |
rescue | true | and | ensure |
then | while | def | module |
when | alias | end | redo |
END | class | in | until |
Variáveis
Variáveis locais começam com letra minúscula ou underscore:
- alpha
- _ident
- some_var
Variáveis globais começam com $:
- $beta
- $B12Vitamin
- $NOT_CONST
Variáveis de instância começam com @:
Variáveis de classe começam com @@:
- @@my_var
- @@NOT_CONST
- @@name
Constantes começam com letra maiúscula ou em UpperCase:
- K9chip
- MAX_VALUE
- VALUE
Escopo
A delimitação do escopo se dá por meio das palavras reservadas “def” e “end”, para começo e término do escopo respectivamente.
Declaração em paralelo
Tipos de dados
Como dito antes, em ruby não exite tipo primitivo. Por isso, nesta seção veremos os tipos de dados existentes na linguagem e algumas peculiaridades.
Tipagem Forte
- O interpretador ruby diferencia operações em variáveis de tipos diferentes, ondeo tipo é determinante para o sucesso da operação.
Tipagem Dinâmica
- A linguagem permite que o tipo da variável possa ser alterado durante a execução do programa.
Fixnum
-
São números inteiros de 31 bits de comprimento, sendo 1 bit para armazenar o sinal e 1 bit para indicar que a referência corrente é um Fixnum.
-
Tipos Fixnum tem uma característica interessante que ajuda na manipulação mais rápida pela linguagem, que os define como immetiate values, que são tipos de dados apontados por variáveis que armazenam seus valores na própria referência e não em um objeto que teve memória alocada para ser utilizado agilizando bastante o uso.
Bignum
-
São números que excedem o limite do Fixnum.
-
Bignums alocam memória, diferente do tipo Fixnum e outros tipos que são immediate values.
Podemos ver isso, criando algumas variáveis apontando para o mesmo valor de Bignum e observar que cada uma tem um object_id distinto.
Ponto Flutuante
Nas referências que encontrei, o Float não era um immediate values, porém nos testes feitos por mim ele se comportou como tal. Uso a versão 2.3 do Ruby, talvez nessa versão ele já possua tal característica.
Racionais
- Ao contrários dos outros tipos, declaramos números racionais usando a classe Rational.
Booleanos
String
-
São uma cadeia de caracteres que podemos criar delimitando-os com aspas simples ou duplas: “Gleidson”, ‘gleidson’.
-
Podemos criar strings com várias linhas, usando o conceito de heredoc.
- Para cada string criada teremos espaço alocado em memória, tendo um object_id distinto para cada.
Substring
São pedaços de uma String. Podemos tratar a string com um array.
Array
Podemos definir como objetos que contém coleções de referências para outros objetos. E ainda, conter tipos de dados diferentes.
Existe um atalho que nos permite economizar digitação com as aspas.
É possível criar arrays com tamanho inicial pré-definido utilizando o tamanho na criação do objeto.
Hashes
Estruturas de controle
Condicionais
-
if
Caso o interesse seja apenas o resultado verdadeiro do if, podemos usar a sintaxe que permite uma ‘leitura’ do código.
-
unless (a menos que)
Forma negativa do if
Loops
-
while
-
for
Temos algumas maneiras de interagir dentro de um loop:
-
break - Sai do loop;
-
next - vai para a próxima iteração;
-
return - sai do loop e do método onde o loop está contido;
-
lambda
Blocos de códigos que podem ser associados à uma variável.
Módulos
Ruby possui herança simples, mas conta com o conceito de módulos, mais conhecidos como Mixins. Dessa forma podemos mixar várias características de módulos em uma classe.
Mídia, que representa a classe ‘mãe’.
Módulo FormatadorMoeda, que possui um método de interesse da classe livro.
A classe livro, ‘filha’ de Mídia. Herda o comportamento da classe mídia e inclui o módulo FormatadorMoeda para ter acesso às suas características.
Abstração
É uma visualização ou representação de uma entidade que inclui somente atributos de importância em um contexto particular.
- Varia de acordo com o contexto.
- É uma vantagem conta a complexidade da programação.
- Simplifica o desenvolvimento.
- É necessário na realização de uma modelagem conceitual.
Tipos de abstração
- Abstração de processos - São referentes ao fluxo de controle.
- Abstração de dados</string> - São referentes às estruturas de dados.
Tipos abstratos de dados
- Nativos - Ponto flutuante, Fixnum, Bignum, etc.
- Definidos pelo usuário - Estruturas de dados propriamente ditas. Pilhas, Filas, Árvores, etc.
Implementação de uma pilha
Implementação de uma fila
Implementação de uma Árvore
Paradigma
É um modelo que o programador possui para estruturar e executar um programa. Tal modelo determina uma forma de abordar os problemas e de formular respectivas soluções.
Ruby obedece vários paradigmas diferentes, como orientação a objetos, concorrência e funcional.
Paradigma concorrente
- Dois ou mais fluxos de execução sequenciais podem ser executados concorrentemente.
- Existe a necessidade de comunicação entre os fluxos, em virtude da troca de informações e sincronização.
- O sincronismo serve para evitar a condição de disputa, tornando a computação um pouco mais determinística.
Existem dois tipos de concorrência: Programas separados, a nível de programas e Threads, a nível de subprogramas.
Implementação de uma Thread
Paradigma de orientação a objetos
Os objetos se comunicam através de mensagem. A mensagem é uma chamada de um método e podemos caracterizá-la por:
- Receptor - estados
- Método - add, remove
- Argumentos - est1, id, name
Os principais conceitos de orientação objetos são Classes, Objetos, Herança
Classes
Uma coletânea ou coleção de objetos que tenham algo comum entre si. O critério de similaridade é definido previamente pelo programador durante a modelagem.
É necessário a definição de atributos e métodos para formatação do “perfil” do objeto (estado e comportamento).
-
Atributo - Referente às características do objeto.
-
Métodos - Referente ao comportamento do objeto.
Classes funcionam como um modelo para gerar objetos.
Herança
É um mecanismo existente em programação orientada a objetos que permite o reuso de uma estrutura e do comportamento de uma classe, ao definir novas classes. Pode ocorrer a nível de atributo/método e relacionamento.
Classe a ser herdada.
Observe que o método to_s, já existente na classe Carro, foi sobrescrito com uma pequena alteração.
O objeto carro1 é do tipo Carro, enquanto o objeto novo_carro é do tipo CarroNovo, que também é um carro. Mas possui o método to_s diferente do tipo Carro. Podemos verificar isso executando o método de ambos os objetos e vendo o resultado impresso.
Paradigma funcional
- O Objetivo principal é imitar funções matemáticas, recebendo um argumento como entrada e retornando um valor.
- Os mesmos parâmetros sempre produzem o mesmo resultado.
- Não utiliza variáveis ou instruções de atribuição, sendo assim, o programador se abstrai do gerenciamento de memória.
- Simplifica a semântica da linguagem funcional.
- Não existe estado do programa em termos operacionais.
each
A forma mais simples de iterar sobre um array, ou vários objetos. No entanto ele faz uso de funções como parâmetros, o que pode deixar o nosso código mais interessante.
inject
Ainda temos uma variável temporária no nosso código que mantém o total da soma dos elementos array. Podemos usar o inject para nos livrarmos dela.
O inject, assim como outras funções que aceitam funções como parâmetro, pode ser simplificado utilizando um recurso do ruby que transforma um símbolo em uma função.
select/reject
Ruby provê duas funções bem interessantes chamadas select e reject. Como o nome diz, elas vão selecionar ou rejeitas os elementos do conjunto baseado em um determinado critério.
O código abaixo retorna um novo array contendo apenas os elementos em que a chamada do método even? retorna verdadeiro.
Mas, podemos reduzir esse código utilizando a mesma técnica.
Com o reject seria a mesma coias. Para obeter apenas os números pares, podemos rejeitar os números ímpares.
Bibliografia
- Conhecendo Ruby, Eustáquio Rangel
- The Ruby Way 3ª edição, Hal Fulton
- Ruby - Aprenda a programar na linguagem mais divertida, Casa do Código
O arquivo em PDF desta apresentação se encontra aqui.