Vitor Pamplona

Innovation on Vision: Imaging , Enhancement and Simulation

Ruby para Programadores Java

Você sabia que há mais informação sobre Rails do que sobre Ruby na internet? Interessante, não? Na verdade, Ruby só é conhecido por causa do Rails, mesmo que grande parte da simplicidade do Rails seja proveniente do Ruby.

Como há pouca documentação sobre a linguagem propriamente dita, este post apresentará o ruby para programadores java de maneira bem rápida. Esta documentação não é completa, visto que aspectos semelhantes entre java e ruby não são tratados. Este post será atualizado frequentemente.

Estrutura da linguagem

Ruby aceita, mas não necessita de "; " para terminar uma instrução. O "; " normalmente é usado para mais de uma instrução na mesma linha.

metodo1(); metodo2()

A barra no final de uma linha indica que a expressão não terminou.

soma = 8\
+ 5

Embora que, em alguns casos, não há necessidade de indicar a continuação como, por exemplo:

soma = 8 + 
5

Comentários

Comentários de linha em ruby são feitos com #

# Comentário

E comentários de bloco com " = begin " e " = end "

=begin
Comentário em Bloco
=end

Comentários podem ser hierarquizados para gerar o rdoc:

=begin
= Alguma biblioteca
== Novidades
.....
....
== Instalação
.....
....
== Uso
....
=end

Literais

Números

123      # 123
4_123.45 # 4123.45
1.2e-3 # 0.0012
0xffff # hexadecimal
0b01011 # binário
0377 # octal
?a # valor em ASCII do caractere
?\C-a # Control-a
?\M-a # Meta-a
?\M-\C-a # Meta-Control-a

Strings

Ruby possui uma forma de templates usando strings, chamada de interpolação.

a = 7
"Número #{a}" # Saída é: Número 7.

Strings em ruby podem ser descritas de várias formas:

'Número\t#{a}'   # Número\t#{a}
"Número\t#{a}" # Número 7
%q(Número\t#{a}) # Número\t#{a}
%Q(Número\t#{a}) # Número 7
%(Número\t#{a}) # Número 7

Caracteres especiais:

\t      # tab
\n # newline
\r # carriage return
\f # form feed
\b # backspace
\a # bell
\e # escape
\s # whitespace
\nnn # octal
\xnn # hexadecimal
\cx # control x
\C-x # control x
\M-x # meta x
\M-\C-x # meta control x

Variáveis

Não há declarações de variáveis. A variável é declarada em sua inicialização, portanto, Ruby não inicializa variáveis automaticamente. O seu tipo é definido por Duck Typing: " Se tem bico como um pato, se anda como um pato e se faz quack como um pato, então é um pato ". Assim se você inicializar com um inteiro, a variável é um FixNum, se inicializar com boleano pode ser um TrueClass ou FalseClass.  

Tudo é objeto.

1.nil?        # false
nil.nil? # true
1.3.class # Float
1.is_a? Float # false
'0'.to_i + 1 # 1
Float.class # Class

Você pode inicializar três variáveis com valores diferentes na mesma linha:

var1, var2, var3 = 'um', 'dois', 'tres'

Como não há definição, caracteres especiais determinam o scopo da variável

$var               # variável global
@@var # Variáveis de classe
@var # Variáveis de instância
var # variáveis local
:var # símbolo
[OtherClass::]VAR # constante

Não existem operadores + + e - -.

As seguintes pseudo-variáveis estão definidas em ruby.

self     # objeto dono do método corrente. 
nil # objeto da classe NilClass semelhante ao null e responde como um false.
__FILE__ # nome do arquivo fonte atual.
__LINE__ # linha do arquivo fonte atual.

Estruturas de dados

Colchetes criam Arrays, Chaves criam Maps. Cada elemento é separado por vírgula e o índice dos Arrays inicia de zero. O Par chave-valor do map é definido usando " igual maior ".

hash = {1 => 'one', 2 => 'two', 3 => 'three'}

Para evitar o uso intensivo de aspas, você pode criar um Array de strings usando o " % w ". Com % W a criação da lista aceitará interpolações.

lista = %w(feminino masculino) # lista = ["feminino", "masculino"] 
lista2 = %w(item\ 1 item\ 2 #{lista[0]}) # lista2 = ["item 1", "item 2", "\#{lista[0]}"]
lista3 = %W(item\ 1 item\ 2 #{lista[0]}) # lista2 = ["item 1", "item 2", "feminino"]

Você pode usar do recurso de Ranges para criar Arrays. Os valores para o Range são sempre inclusivos

nums = (0..9).to_a   # num = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Iteradores

" each " é um iterador

('A' .. 'Z').each { |char| puts char }

A variável entre as barras | char | vai receber cada uma das letras do range. Você pode iterar sobre arrays facilmente.

arr =  get_list # preeche o array
(0 ... arr.size).each { |index| print arr[index] }

Usando times:

5.times do
puts 'hello'
end

Por range, utiliza-se dois pontos para inclusive no segundo argumento e três pontos para exclusive.

for x in 1..10 do
puts x
end

do e end determinam um bloco, mas podem ser trocados por chaves

1..10.each { |x| puts x }
["a", "b", "c"].each { |x| puts x }
["hi", "there"].collect { |word| word.capitalize }

Funções

Funções são definidas usando a contração " def "

def foo(*list_expr, &block_expr)
... # Código da função
end

* list_expr está pedindo uma lista de expressões, enquanto &block_expr pede um bloco de código ruby.

Valores default para parâmetros em funções.

def metodo(primeiro = 1, segundo = [], terceiro = {})
# implementação
end

O valor de retorno é a expressão após a palavra return, ou a última expressão executada.

def assert_equal(expected, actual)
if expected != actual
"FAILURE!" // Valor de retorno se expected != actual.
else
"OK!" // Valor de retorno se expected == actual
end
end

Ao contrário do Python, o ruby não utiliza a indentação como forma de definir blocos. Um bloco é definido via {} ou de uma palavra reservada até o seu "end"

Não é necessário usar parênteses para invocar métodos em ruby:

metodo
metodo()
metodo(2)
metodo(2, [:abc, :def])
metodo(2, [:abc, :def], :abc => ' abc ',: def = > ' def ')
metodo 2, [: abc,: def],: abc = > ' abc ',: def = > ' def '
metodo 2, [: abc,: def], {: abc = > ' abc ',: def = > ' def '}

Ruby também tem varargs, listas variáveis de parâmetros:

def meu_metodo_com_parametros_ilimitados *params
# params é um Array
end

O método acima pode ser chamado destas maneiras:

meu_metodo_com_parametros_ilimitados # params vazio
meu_metodo_com_parametros_ilimitados 'string', :symbol, {}

Utilize dois pontos ao invés do ponto simples para acessar um método estático (de classe ou de módulo)

Class::metodo() 

Controles de fluxo.

Ruby tem elsif:

if <condition>
<statements>
elsif <condition>
<statements>
else
<statements>
end

Ruby tem switch, mas não se usa o break após cada condição.:

case foo
when <condition1>
<statements>
when <condition2>
<statements>
else
<statements>
end

Ruby tem unless, que é equivalente ao if not & lt; condition & gt;

unless <condition>
<statement>
end

O If e o unless podem ser utilizados no fim da instrução. A instrução só é executada se a condição for verdadeira.

<expression> if     <condition1>
<expression> unless <condition1>

Exemplo:

print item.valor unless item.invalido?

Palavras chave dentro de controles de fluxo:

break     # termina o loop
redo # repete a iteração atual, re-executando a condicional
next # inicia a próxima iteração do loop.
retry # reinicia o loop, re-executando a condicional

Exceções

Exceções são tratadas com rescue:

begin
<statements>
rescue FooError => e
<statements>
rescue BazError => e2
<statements>
rescue
<statements>
end

Expressões Regulares  

Demarcadas por

/<pattern>/ 

ou

%r{} 

e são testadas com

=~ 
/a/ =~ 'a string' # retorna 0, a posição do primeiro caracter encontrado. 
/a/ é a expressão regular

Bibliotecas

Para utilizar alguma função definida em outro arquivo use o require. Não é necessário escrever a extensão do arquivo.

require 'my_math' 

Se ela não estiver no PATH do ruby, adicione o diretório onde ela se encontra antes do require

$LOAD_PATH << '<novo caminho>' 

Herança

Heranças são definidas com sinal de menor

class Obj < BaseObj 
...
end

Convenções

Classes e módulos iniciam com letras maiúsculas, e não se usa o underscore

class Raster
class Raster::ImageSprite

Métodos devem ser verbos, devem usar apenas caracteres ASCII e sempre em minúsculo, com o underscore separando as palavras.

run()
run_fast()
obj.background_color()

Variáveis são descritas como as funções:

i = 1
some_char = SomeChar.new()
table_width = 0.0

Fontes:
http://wtr.rubyforge.org/s101/doc/Ruby-cheat-sheet.doc
http://ruby.cenophobie.com/rubycheat.php
http://www.zenspider.com/Languages/Ruby/QuickRef.html

Posted in Feb 26, 2008 by Vitor Pamplona - Edit - History

Showing Comments

Opa,

Herança é definida com apenas um sinal de menos
class Foo < Bar
end

" < < " faz shift left pra inteiros, concatena string ou adiciona elementos em um array.

Abraço

- - Rafael Mueller

- - Posted in Feb 23, 2008 by 201.67.164.142

Corrigido! Valeu.

- - Posted in Feb 23, 2008 by Vitor Pamplona

Por que será que a herança é definida com o sinal < (menor) se a classe derivada é " maior-ou-igual " à classe base? O sinal deveria ser > =, então, hehehehe.: - D: - P

- - Marcus Aurelius

- - Posted in Feb 24, 2008 by 189.6.239.84

Parabéns pelo post Vitor.

- - Werner

- - Posted in Feb 25, 2008 by 201.47.87.98

Oi Vitor! Excelente post! Parabéns mesmo! Só faltou dizer que nos Ranges quando usamos (0... 9) (3 pontos) o valor final não é inclusivo, isto é o Range vai de 0 a 8. Abraços

- - Leonardo

- - Posted in Feb 25, 2008 by 200.225.216.225

Vitor, muito bem explicado:) €

- - Rubem

- - Posted in Mar 3, 2008 by 189.32.121.205

Add New Comment

Your Name:


Write the code showed above on the text below.