Privacy Policy Cookie Policy Terms and Conditions Ruby (linguagem de programação) - Wikipédia

Ruby (linguagem de programação)

Origem: Wikipédia, a enciclopédia livre.

Nota: Para outros significados de Ruby, ver Ruby (desambiguação).
Logo do Ruby
Ampliar
Logo do Ruby

Ruby é uma linguagem de programação interpretada, com tipagem dinâmica e forte, orientada a objetos com vastas semelhanças com Perl, SmallTalk e Python.

Projetada tanto para a programação em grande escala quanto para codificação rápida, tem um suporte a orientação a objetos simples e prático. A linguagem foi criada pelo japonês Yukihiro Matsumoto, que aproveitou as melhores idéias das outras linguagens da época.

Ruby é bastante usada no mundo todo, com uma lista de discussão bastante ativa (ruby-talk). Possui vastos repositórios de módulos hospedados nos sites Ruby Application Archive (RAA) e Rubyforge. Existe, ainda, uma ferramenta bastante útil para instalação de bibliotecas, chamada Ruby Gems.

Ruby se tornou reconhecida no meio especializado desde que Dave Thomas, conhecido como um dos Pragmatic Programmers (Programadores Pragmáticos), adotou o Ruby como uma de suas linguagens preferidas, e acabou por escrever a bíblia da linguagem, o Programming Ruby, The Pragmatic Programmer's Guide. De lá pra cá, o número de adeptos do Ruby tem crescido vertiginosamente. Ultimamente, devido à grande exposição de um framework web feito em Ruby, o Ruby on Rails, a linguagem têm sido alvo de grandes elogios e grandes críticas, justamente pela sua praticidade.

A praticidade, inclusive, é um dos conceitos básicos desta linguagem. Você deve fazer códigos que resolvam seus problemas, e não os problemas da linguagem e/ou interpretador/compilador.

Para manter a praticidade, a linguagem possui algumas características interessantes:

  • A sintaxe é enxuta, quase não havendo necessidade de colchetes e outros caracteres que dificultam a leitura.
  • Orientação a Objetos pura (tudo são objetos, até mesmo os tipos mais básicos de variáveis)
  • Foram criados atalhos de código, como os "attr", "attr_reader" e "attr_writer".
  • Para instalar uma biblioteca nova, basta digitar "gem install biblioteca" na linha de comando do seu sistema operacional.
  • "Code blocks", ou blocos de código, ajudam o programador a passar um trecho de instruções para um método. A idéia é semelhante aos "callbacks" do Java, mas de uma forma extremamente simples e bem implementada.
  • "Mixin's", uma forma de emular a Herança Múltipla, sem cair nos seus problemas.
  • Tipagem dinâmica, mas forte. Isso significa que todas as variáveis devem ter um tipo (fazer parte de uma classe), mas a classe pode ser alterada dinamicamente. Os "atalhos" citados acima, por exemplo, se beneficiam da tipagem dinâmica para criar os métodos de acesso/alteração das propriedades.

Ruby está disponível para diversas plataformas, como Windows, .NET, Linux, Solaris, Java (JRuby) e MacOS X.


Índice

[editar] Interpretada ou compilada?

Antigamente, quando se falava que uma linguagem de programação era interpretada, vinha-nos à cabeça uma linguagem-ferramenta, daquelas simples que te possibilitam apenas agilizar um trabalho, como mover arquivos de um diretório a outro. Essas linguagens tinham falta de suporte à recursos do sistema operacional, que só podiam ser acessadas por linguagens compiladas, como C ou C++. Há algum tempo isso já não é mais verdade. Hoje, interpretada ou compilada é só uma característica da linguagem.

Pela natureza do Ruby (ser descomplicada), optou-se por não exigir a compilação, fazendo com que fosse uma linguagem interpretada. Por exemplo, não é preciso reiniciar o "application server" para instalar uma aplicação, que teve uma classe alterada. é só alterar e testar.

[editar] Orientada a objetos, prática e limpa

A orientação a objetos do Ruby pode ser comparada à do SmallTalk, uma vez que tudo o que se é manipulado é efetivamente um objeto, não havendo tipos primitivos. Em Ruby, temos tipos de literais que são objetos, como Strings ( "string" ), Fixnum’s (0, 1, 3, 345), comandos nativos ( `date` ), Ranges (1..10), Regexp's ( /\n\r/ ), Arrays ([1, "a", 3.14]) e Hashes ({"Versão" => "1.8.4"}). Essa característica nos possibilita escrever códigos como os abaixo:

0.upto(10) do | i |
  puts i
end
"alguma coisa".chomp!
/\r\n/.match("algumas\n linhas \r\n aleatórias\n ")

Isso demonstra que tudo é mesmo um objeto, possuindo seus próprios métodos. Operadores (+, -, *, /, ...) em Ruby são métodos também. Dessa forma, podemos afirmar que Ruby não possui “operadores” no sentido estrito do termo. Exemplo:

class MeuNumero < Fixnum
  def +(numero)
    42
  end
end

numero = MeuNumero.new(1)
# Repare como um operador de soma é um método em ruby, ao contrário de outras linguagens
puts numero+2 # 1+2 = 42 ??? Sim, sobrescrevemos o método de soma para retornar 42 sempre. 


[editar] Attribute Readers e Writers

Uma das funcionalidades mais úteis do Ruby são os attribute readers e writers. São como "atalhos" para os famosos "getters/setters". Compare os seguintes códigos:

class Pessoa
  def nome
    @nome
  end

  def nome=(valor)
    @nome = valor
  end

  def nascimento
    @nascimento
  end

  def nascimento=(valor)
    @nascimento = valor
  end

  def cpf
    @cpf
  end

  def cpf=(valor)
    @cpf = valor
  end
end

class Pessoa
  attr_accessor :nome, :nascimento, :cpf
end

Isso deixa claro o conceito de facilidade do Ruby, deixando que você gaste mais tempo para a lógica da sua aplicação do que em formalidades da linguagem.

[editar] Controle de acesso

Em Ruby, você pode deixar três tipos de acesso aos métodos: métodos públicos, privados e protegidos. Os métodos públicos podem ser acessados por qualquer classe e por qualquer objeto (instância). Os métodos privados podem ser acessados somente por objetos de mesmo tipo (mesma classe).

Métodos protegidos são métodos que podem ser acessados por qualquer objeto dentro da mesma estrutura hierárquica da classe. Por exemplo, uma classe

Pessoa < SerHumano

pode acessar métodos protegidos de SerHumano. Mas, ao contrário de outras linguagens, você especifica o controle de acesso por "bloco", como nos exemplos abaixo:

class Pessoa
  attr :nome, :nascimento, :cpf

  def metodoPublico
  end

  protected

  def metodoProtegido
  end

  def outroMetodoProtegido
  end

  private

  def metodoPrivado
  end

  def outroMetodoPrivado
  end

  public

  def deNovoMetodoPublico
  end

end

Você pode ainda declarar todos seus métodos sem definir a visibilidade do método em bloco, mas usando outro atalho bem interessante:

class Pessoa

  attr :nome, :nascimento, :cpf

  def metodoPublico
  end

  def metodoProtegido
  end

  def outroMetodoProtegido
  end

  def metodoPrivado
  end

  def outroMetodoPrivado
  end

  def deNovoMetodoPublico
  end

  public :metodoPublico, :deNovoMetodoPublico
  protected :metodoProtegido, :outroMetodoProtegido

  private :metodoPrivado, :outroMetodoPrivado

end


[editar] Modules, os helpers e classes agrupadas

Além das classes normais, temos também os "Modules", que são parecidas com classes, mas servem para agrupar os métodos que geralmente colocamos nas classes "Helper" em outras linguagens. Dessa forma, podemos fazer um módulo Debug que tem diversos métodos úteis para a depuração de nossos programas. Por exemplo, podemos adicionar um método que nos retorna informações sobre um objeto (instância):

module Debug
  LEVEL = "producao" 
  def info
    "#{self.type.name} (\##{self.id}): #{self.to_s}" 
  end
end

Este código foi baseado no exemplo de Modules do livro "Pickaxe" (Programming Ruby: The Pragmatic Programmer's Guide). Em Java, podemos fazer algo semelhante, mas utilizando frameworks IoC, mas que em geral são de alta complexidade: ou alteram o fonte logo antes da compilação, ou alteram o byte-code de classes já compiladas. Em ambos os casos, o código é "injetado" em cada classe, diferente desta tática do Ruby, que "herda" o comportamento, deixando o código em apenas um lugar.


[editar] Mixin's, resposta simples ao problema da herança múltipla

Em Orientação a Objetos, a herança múltipla é geralmente considerada um grande problema, pois pode acabar trazendo mais danos do que vantagens. Ruby, assim como a maioria das linguagens OO, não suporta herança múltipla diretamente. Ao invés disto, você pode adicionar comportamentos a uma classe, utilizando os Mixin’s. Eles funcionam como os includes: você só declara qual a classe que deseja herdar o comportamento. Deste jeito:

class MeuObjeto < ObjetoPai
  include Debug
  include Comparable
end

Nesta classe, estamos herdando diretamente de ObjetoPai, mas "incluindo" o comportamento das classes "Debug" e "Comparable", deixando isso totalmente transparente à classe usuária, mantendo o encapsulamento.


[editar] Code Blocks

"Code blocks", ou blocos de código, são trechos de código que são passados como parâmetros para métodos. "Code blocks" são extremamente usados em Ruby, sendo um dos responsáveis pela manutenção da simplicidade nos códigos. Blocos são limitados por chaves ou por "do end". Em geral, usa-se chaves quando o bloco possui apenas uma linha, e "do end" quando temos mais de uma. Por exemplo:

IO.readlines("hosts.txt").each do | linha |
  puts linha.chomp
end

# Esta linha faz o mesmo:
IO.readlines("hosts.txt").each { | linha | puts linha.chomp}

Neste caso, estamos usando o método "each" da classe "Array", que obtemos através do método "readlines" da classe "IO". O método "readlines" é responsável por abrir o arquivo, ler as linhas, executar o código que foi recebido no bloco, passando "linha" como parâmetro e fecha o arquivo. Para o usuário, todas as operações "preparatórias" (abrir, iterar e fechar arquivo) ficam "escondidas". Preocupação a menos. Para entender como funciona internamente, vamos ver um exemplo de como aceitar um code block:

class Paises

  @paises = ["Argentina", "Brasil", "Paraguai", "Uruguai"]

  def Paises.each
    for i in 0...@paises.length
      yield @paises[i]
    end
  end
end

Paises.each do | pais |
  puts pais
end

Neste exemplo, podemos ver que economizamos algumas linhas de código, deixando o "código de infraestrutura" dentro da classe Paises, fornecendo o método "each" ao usuário. Assim, o usuário não precisa saber como obter os dados, o que fazer para iniciar a iteração e o que fazer no final da iteração.


[editar] Tratamento de exceções

Como toda boa linguagem moderna, Ruby também deixa que o programador tome conta do fluxo da aplicação, mesmo em caso de exceções. As palavras-chave para isto são "begin", "rescue" e "ensure".

"Begin" inicia um trecho que pode cair em alguma exceção. "Rescue" determina o comportamento em caso de uma exceção específica ou não. "Ensure" é o código que será executado independente de ter havido exceção ou não.

Ao contrário de outras linguagens, Ruby não exige que um trecho "que pode dar erro" esteja obrigatoriamente dentro de um trecho "begin". O programador é livre para determinar se quer ter o controle sobre as exceções ou não. Isso é bastante útil, já que em Java, por exemplo, a maioria dos "catch" são apenas para passar o erro para um nível superior do sistema:

try {
# algo que vai causar exceção
} catch (Exception e) {
throw e;
}

Além destas palavras-chave, temos também o "retry", que re-executa o trecho a partir do "begin". Isso é extremamente útil, já que nos dá a possibilidade de arrumar o erro, ou tentar outros parâmetros. Como exemplo, pegamos este trecho de código da biblioteca "net/smtp", escrito por Minero Aoki e citado no livro Pickaxe (Programming Ruby: The Pragmatic Programmer's Guide).

@esmtp = true
begin
  # First try an extended login. If it fails because the
  # server doesn't support it, fall back to a normal login
  if @esmtp then
    @command.ehlo(helodom)
  else
    @command.helo(helodom)
  end
rescue ProtocolError
  if @esmtp then
    @esmtp = false
    retry
  else
    raise
  end
end


[editar] Quem está por trás do Ruby?

Ainda hoje, Matz é o responsável por todas as decisões não-consensuais do Ruby. Ou seja, qualquer divergência quanto à implementação de uma nova funcionalidade é resolvida pelo "ditador benevolente". Apesar desta "dependência", a comunidade é forte a ponto de sobreviver "caso o Matz seja atropelado por um ônibus espacial". Existem pessoas que estão tão inteiradas com o código quanto o próprio Matz. Diferentemente de outras tecnologias opensource, não existe uma empresa por trás de suas operações, bancando os custos. O projeto sobrevive de doações feitas pelos usuários satisfeitos e por empresas que conseguiram aumentar sua produtividade utilizando Ruby.

[editar] Ruby para administradores de sistemas

Depois de mostrar um pouco de como Ruby funciona por dentro, vamos adentrar em um tópico um pouco mais prático. Hoje em dia, a maioria dos administradores de sistemas Unix utilizam Perl ou Shell Script como ferramenta para resolver os problemas diários. Isso implica no aprendizado de uma linguagem que nem sempre é amigável, com regras nem sempre claras. Por vezes, os administradores acabam demorando muito tempo no desenvolvimento destes scripts. Por este motivo, cada vez mais administradores de sistemas estão usando Ruby para resolver seus problemas. Abaixo, um exemplo real que nos foi apresentado há algum tempo. A idéia era fazer um pequeno script que verifica se o serviço da porta 80 (web) de alguns servidores estavam ativos.

require 'net/http'

File.open("hosts.txt", "r").each_line do | host |

  conexao = Net::HTTP.new(host.chomp, 80)
  resposta, conteudo = conexao.get("/", nil)

  if resposta.code.to_i > 400
    # aqui vai a rotina pra enviar email...
  end
end

Como podemos ver, em 9 linhas fizemos um script que pode ser colocado como "cronjob" em qualquer Unix.

[editar] Exemplos de código

[editar] Array (vetor)

a = [1, 'hi', 3.14, 1, 2, [4, 5]]

a[2]                      # 3.14
a.reverse                 # [[4, 5], 2, 1, 3.14, "hi", 1]
a.flatten.uniq            # [1, "hi", 3.14, 2, 4, 5]

[editar] Hash (dicionário)

hash = {'water' => 'wet', 'fire' => 'hot'}
puts hash['fire']       

hash.each_pair do |key, value| 
  puts "#{key} is #{value}"
end

  # Prints:             water is wet
  #                     fire is hot

hash.delete_if {|key, value| key == 'water'}   # Deletes 'water' => 'wet'

[editar] Classes

Uma das grandes vantagens das classes em Ruby é o fato de elas serem abertas para alteração. Isso não quer dizer extender a classe e sim altera-la em tempo de execução. Por exemplo, suponha que precise de um novo metodo na classe String de Ruby para capturar sempre a primeira letra. Em outras linguagens, o comum é criar metodos utilitarios para realizar a operação. Em Ruby, você simplesmente altera a classe para que ela agora possua tal metodo. Exemplo:

class String
  def first
    "" << self[0]
  end
end

puts "Marcos Pereira".first

Isso mostra o quanto Ruby pode se adaptar as necessidades do programador.

[editar] Exemplos de Classes

class Person
  def initialize(name, age)
    @name, @age = name, age
  end

  def <=>(person)
    @age <=> person.age
  end

  def to_s
    "#{@name} (#{@age})"
  end

  attr_reader :name, :age
end

group = [ Person.new("John", 20), 
          Person.new("Markus", 63), 
          Person.new("Ash", 16) 
        ]

puts group.sort.reverse
class Pessoa < SerHumano # heranca

  include Mamifero # emulando heranca multipla

  # cria tanto metodos de leitura como escrita... Em java, seria setNome e getNome
  attr :nome 

  # isso cria o metodo de leitura de estado. Em java, seria getIdade
  attr_reader :idade 

  # isso cria o metodo de mudanca de estado. Em java, isso seria o setNascimento
  attr_writer :nascimento 

  # "self." antes do nome significa que é um metodo de classe
  def self.comer(comida) 
  end

  # sem "self.", significa que é um método de "instância"
  def timbreDeVoz()
  end

  # sim, qualquer caracter eh possivel no nome dos metodos ;-)
  def correr!() 
  end

  # inclusive, fazer sobrecarga (overload) de operadores
  def =(outrovalor) 
  end

end

[editar] Referências


THIS WEB:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2008 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -

Static Wikipedia 2007:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2006:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu