Ruby (linguagem de programação) - Ruby (programming language)


Da Wikipédia, a enciclopédia livre
Rubi
ruby logo.svg
Paradigma Multi-paradigma : orientada a objeto , imperativo , funcional , reflexivo
Projetado por Yukihiro Matsumoto
Desenvolvedor Yukihiro Matsumoto, et al.
Apareceu pela primeira vez 1995 ; 23 anos atrás ( 1995 )
Versão estável 2.5.3 (18 outubro de 2018 ; 50 dias )  ( 2018/10/18 ) [±]
disciplina Typing Duck , dinâmico , forte
Escopo Lexical, às vezes dinâmica
linguagem de implementação C
OS Multi-plataforma
Licença Rubi , GPLv2 ou BSD 2 cláusula de licença
extensões de arquivo .rb
Local na rede Internet www .ruby-lang .org
grandes implementações
Ruby MRI , YARV , Rubinius , MagLev , JRuby , MacRuby , RubyMotion , Mruby
Influenciado por
Ada , C ++ , CLU , Dylan , Eiffel , Lisp , Lua , Perl , Python , Smalltalk
Influenciado
Clojure , CoffeeScript , Cristal , D , Elixir , Groovy , Ioke , Julia , Mirah , Nu , Reia , Anel , Rust , Swift

Rubi é uma dinâmica , interpretado , reflexiva , orientada a objeto , linguagem de programação de propósito geral . Ele foi projetado e desenvolvido em meados dos anos 1990 por Yukihiro "Matz" Matsumoto no Japão .

De acordo com o criador, Ruby foi influenciada pelo Perl , Smalltalk , Eiffel , Ada , e Lisp . Ele suporta múltiplos paradigmas de programação , incluindo funcional , orientada a objeto , e imperativo . Ele também tem um tipo dinâmico sistema automático e gerenciamento de memória .

História

conceito inicial

Matsumoto disse que Ruby foi concebido em 1993. Em um post 1999 para o ruby-talk mailing list, ele descreve algumas de suas idéias iniciais sobre a língua:

Eu estava falando com o meu colega sobre a possibilidade de uma linguagem de script orientada a objetos. Eu sabia Perl (Perl4, não Perl5), mas eu não gostei muito, porque tinha o cheiro de uma linguagem de brinquedo (ainda tem). A linguagem orientada a objetos parecia muito promissor. Eu sabia Python então. Mas eu não gosto disso, porque eu não acho que foi uma verdadeira linguagem orientada a objeto - características OO parecia ser add-on para o idioma. Como um maníaco linguagem e fã OO por 15 anos, eu realmente queria um autêntico, fácil de usar linguagem de script orientada a objetos. Procurei, mas não conseguiu encontrar um. Então eu decidi fazê-lo.

Matsumoto descreve a concepção de rubi como sendo um simples Lisp idioma no seu núcleo, com um sistema objecto como o de Smalltalk, blocos inspirados por funções de ordem superior , e utilidade prática como o de Perl.

O nome "Ruby"

O nome "Ruby" se originou durante uma sessão de bate-papo online entre Matsumoto e Keiju Ishitsuka em 24 de fevereiro de 1993, antes de qualquer código tivesse sido escrito para a linguagem. Inicialmente foram propostos dois nomes: " Coral " e " Rubi ". Matsumoto escolheu o último em uma tarde e-mail para Ishitsuka. Matsumoto depois observou um fator na escolha do nome "Ruby" - era o birthstone de um de seus colegas.

primeira publicação

A primeira versão pública do Ruby 0,95 foi anunciada no dia doméstico japonês newsgroups em 21 de dezembro de 1995. Posteriormente, mais três versões do Ruby foram liberados em dois dias. O lançamento coincidiu com o lançamento do idioma japonês -list ruby lista de discussão, que foi a primeira lista de endereços para o novo idioma.

Já presentes neste estágio de desenvolvimento eram muitas das características familiares em versões posteriores do Ruby, incluindo orientada a objetos de design, as classes com herança, mixins , iteradores , fechamentos , tratamento de exceções e coleta de lixo .

primeiros lançamentos

Após o lançamento do Ruby 0,95 em 1995, várias versões estáveis ​​do Ruby foram lançados nos anos seguintes:

  • Ruby 1.0: 25 de dezembro, 1996
  • Ruby 1.2: dezembro 1998
  • Ruby 1.4: agosto 1999
  • Ruby 1.6: setembro 2000

Em 1997, o primeiro artigo sobre Ruby foi publicado na Web. No mesmo ano, Matsumoto foi contratado pela netlab.jp para trabalhar em Ruby como um desenvolvedor em tempo integral.

Em 1998, o Application Archive Rubi foi lançado pela Matsumoto, juntamente com uma página em língua Inglês simples para Ruby.

Em 1999, a primeira lista de idiomas Inglês mailing ruby-talk começou, que sinalizou um interesse crescente na língua fora do Japão. Neste mesmo ano, Matsumoto e Keiju Ishitsuka escreveu o primeiro livro sobre Ruby, O orientado a objetos Scripting linguagem Ruby (オブジェクト指向スクリプト言語Rubi), que foi publicado no Japão em outubro de 1999. Ele seria seguido no início de 2000 em cerca de 20 livros sobre o ruby publicada em japonês.

Em 2000, Ruby era mais popular do que Python no Japão. Em setembro de 2000, o primeiro livro idioma Inglês Programming Ruby foi impresso, que foi lançado mais tarde gratuitamente ao público, ampliando ainda mais a adoção do Ruby entre falantes de inglês. No início de 2002, o idioma Inglês ruby-talk mailing list estava recebendo mais mensagens do que a de língua japonesa ruby-list , demonstrando crescente popularidade de Ruby no mundo de língua não-japonês.

ruby 1.8

Ruby 1.8 foi lançado inicialmente agosto de 2003, manteve-se estável por um longo tempo, e foi aposentado de Junho de 2013. Apesar de obsoleto, ainda há código com base nele. Ruby 1.8 é apenas parcialmente compatível com Ruby 1.9.

Ruby 1.8 tem sido objecto de vários padrões da indústria. As especificações de idioma para Ruby foram desenvolvidos pelo Centro de Padrões Abertos Promoção da Agência de Promoção de tecnologia da informação (a governo japonês agência) para apresentação ao Comitê de Padrões Industriais japoneses (JISC) e depois para a Organização Internacional de Normalização (ISO). Foi aceite como um Japanese Industrial Standard (JIS X 3017) em 2011 e um padrão internacional ( ISO / IEC 30170 ) em 2012.

Por volta de 2005, o interesse na linguagem Ruby subiu em conjunto com Ruby on Rails , um framework web escrito em Ruby. Rails é frequentemente creditado com o aumento da consciência da Ruby.

ruby 1.9

Ruby 1.9 foi lançado no dia de Natal em 2007. eficaz com Ruby 1.9.3, lançado 31 outubro de 2011, Ruby comutada de ser dual-licenciado sob a Licença Ruby e do GPL para ser dual-licenciado sob a Licença Ruby e a dois licença BSD cláusula. Adoção de 1,9 foi retardado por mudanças de 1.8 que exigiam muitos populares terceiros gemas de ser reescrito.

Ruby 1.9 introduz muitas mudanças significativas em relação a série 1.8. Exemplos:

  • bloco locais variáveis (variáveis que são locais para o bloco em que elas são declaradas)
  • um adicional lambda sintaxe:f = ->(a,b) { puts a + b }
  • um adicional de Hash sintaxe literal usando dois pontos para as teclas de símbolo:{symbol_key: "value"} == {:symbol_key => "value"}
  • per-string codificações de caracteres são suportados
  • novo socket API ( IPv6 apoio)
  • require_relative garantia de importação

Ruby 1.9 tem sido obsoleto desde 23 de fevereiro de 2015, e não receberá mais bugs e segurança. Os usuários são aconselhados a atualizar para uma versão mais recente.

rubi 2,0

Ruby 2.0 adicionado vários novos recursos, incluindo:

  • argumentos método de palavra-chave,
  • um novo método, Module#prepend, que se prolonga para uma classe,
  • um novo literal para a criação de uma série de símbolos,
  • nova API para a avaliação preguiçosa de enumerables, e
  • uma nova convenção de usar #to_h para converter objetos de hashes.

Rubi 2,0 destina-se a ser totalmente compatível com Ruby 1.9.3. A partir do lançamento oficial 2.0.0 em 24 de fevereiro, 2013, havia apenas cinco (menor) incompatibilidades conhecidas.

Tem sido obsoleto desde 22 fevereiro de 2016, e não receberá mais bugs e segurança. Os usuários são aconselhados a atualizar para uma versão mais recente.

ruby 2.1

Ruby 2.1.0 foi lançado no dia de Natal em 2013. A versão inclui speed-ups, correções de bugs e atualizações da biblioteca.

Começando com 2.1.0, a política de versão do Ruby é mais como versionamento semântico . Embora semelhantes, a política de controle de versão de Ruby não é compatível com a versão semântica:

Rubi versionamento semântico
MAJOR : Maior quando a mudança incompatível que não pode ser liberado em menores. Reservados para eventos especiais. MAJOR : Aumento quando você faz mudanças na API incompatíveis.
MINOR : aumentado a cada Natal, pode ser API incompatíveis. MINOR : aumentou quando você adiciona funcionalidade em um compatível com versões anteriores maneira.
TEENY : segurança ou correção de bug que mantém compatibilidade de API. Pode ser aumentada mais de 10 (como 2.1.11), e será lançado a cada 2-3 meses. PATCH : aumentou quando você faz correções de bugs para trás compatíveis.
PATCH : número de commits desde a última versão secundária (será reposto em 0 quando liberando menor). -

versionamento semântico também fornece etiquetas adicionais para pré-lançamento e construir metadados estão disponíveis como extensões para o formato MAJOR.MINOR.PATCH, não disponíveis em Ruby.

Ruby 2.1 tem sido obsoleto desde 1 de Abril de 2017, e não receberá mais bugs e segurança. Os usuários são aconselhados a atualizar para uma versão mais recente.

ruby 2.2

Ruby 2.2.0 foi lançado no dia de Natal em 2014. A versão inclui speed-ups, correções de bugs e atualizações de biblioteca e remove algumas APIs desaprovadas. Mais notavelmente, Ruby 2.2.0 introduz alterações ao gerenciamento de memória - um coletor de lixo incremental, apoio para a coleta de lixo de símbolos e a opção para compilar diretamente contra jemalloc. Ele também contém o suporte experimental para uso vfork (2) com o sistema () e micélios (), e adicionou suporte para o Unicode especificação 7.0.

Características que foram feitas obsoleto ou removidos incluem callcc, a biblioteca DL, Digest :: HMAC, lib / rational.rb, lib / complex.rb, GServer, Logger :: aplicação, bem como as várias funções da API C.

desempenho PowerPC64
Desde a versão 2.2.1, o desempenho de Ruby MRI em PowerPC64 foi melhorada.

rubi 2,3

Ruby 2.3.0 foi lançado no dia de Natal em 2015. Algumas mudanças notáveis ​​incluem:

  • A capacidade de marcar todas as strings literais como congelado por padrão com um consequentemente grande aumento de desempenho em operações de cadeia.
  • comparação hash para permitir a verificação direta de pares de chave / valor em vez de apenas chaves.
  • Um novo operador de navegação segura &. que pode aliviar nil manipulação (por exemplo, em vez de , podemos usar ).if obj && obj.foo && obj.foo.barif obj&.foo&.bar
  • O did_you_mean gem está agora incluído por padrão e necessário na inicialização para automaticamente sugerir nome similar corresponde em um NameError ou NoMethodError .
  • Hash # dig e Array # escavação para extrair facilmente valores profundamente aninhados (por exemplo dado , o valor Foo Baz agora podem ser recuperados por ).profile = { social: { wikipedia: { name: 'Foo Baz' } } }profile.dig(:social, :wikipedia, :name)
  • .grep_v(regexp) que irá corresponder a todos os exemplos negativos de uma dada expressão regular, além de outros novos recursos.

O 2.3 ramo também inclui muitas melhorias de desempenho, atualizações e correções de bugs incluindo alterações Proc # chamada, soquete e IO uso de palavras-chave de exceção, Linha manuseio # nome, líquida de inadimplência passiva :: conexões FTP, e Rake sendo removidos do stdlib.

ruby 2.4

Ruby 2.4.0 foi lançado no dia de Natal em 2016. Algumas mudanças notáveis ​​incluem:

  • Encadernação # IRB: Inicie uma sessão REPL semelhante ao binding.pry
  • Unify Fixnum e Bignum em Integer classe
  • Cordas suporta mapeamentos caso Unicode, e não apenas ASCII
  • Um novo método, Regexp # jogo ?, que é uma versão mais rápida boolean de Regexp # jogo
  • detecção de impasse thread agora mostra tópicos com o seu registo de chamadas e dependência

A 2,4 ramo também inclui melhorias de desempenho para hash tabela, matriz # max, matriz # min, e o acesso variável exemplo.

A popularidade de Ruby tem vindo a diminuir desde 2014, um deslizamento que pode ser permanente em face da crescente concorrência.

rubi 2,5

Ruby 2.5.0 foi lançado no dia de Natal em 2017. Algumas mudanças notáveis ​​incluem:

  • resgate e assegurar declarações usar automaticamente uma envolvente do-end bloco (menor necessidade de extras começam-end blocos)
  • Método-encadeamento com yield_self
  • cobertura de divisão de apoio e método de medição de cobertura
  • Transformações Hash mais fáceis com Hash # fatia e Cardinal # transform_keys

No topo do que chegar um monte de melhorias de desempenho como passar bloco mais rápido (3 vezes mais rápido), Mutexes mais rápidos, modelos mais rápido ERB e melhorias em alguns métodos de concatenação.

Tabela de versões

Versão Última versão teeny data de lançamento inicial Fim da fase de apoio Fim da fase de manutenção de segurança
versão antiga, não mais suportada: 1.0 N / D 1996/12/25 N / D N / D
versão antiga, não mais suportada: 1.8 1.8.7-P375 2003/08/04 2012-06 2014/07/01
versão antiga, não mais suportada: 1.9 1.9.3-P551 2007-12-25 2014/02/23 2015/02/23
versão antiga, não mais suportada: 2,0 2.0.0-p648 2013/02/24 2015/02/24 2016/02/24
versão antiga, não mais suportada: 2.1 2.1.10 2013/12/25 2016/03/30 2017/03/31
versão antiga, não mais suportada: 2.2 2.2.10 2014/12/25 2017/03/28 2018/03/31
versão mais antiga, mas ainda suportados: 2,3 2.3.8 2015/12/25 2018/06/20 2019/03/31
versão mais antiga, mas ainda suportados: 2.4 2.4.5 2016/12/25 TBA TBA
versão estável atual: 2,5 2.5.3 2017/12/25 TBA TBA
versão futura: 2.6 2018/12/25 TBA TBA
versão futura: 3,0 2020 TBA TBA
Lenda:
Versão antiga
versão mais antiga, ainda suportada
Última versão
versão mais recente pré-visualização
versão futura

Filosofia

Yukihiro Matsumoto , o criador do Ruby

Matsumoto disse que Ruby é projetado para a produtividade e diversão programador, seguindo os princípios da boa interface design. Em um Talk Google Tecnologia em 2008 Matsumoto afirmou ainda, "Espero ver o Ruby ajudar cada programador no mundo para ser produtivo, e desfrutar de uma programação, e para ser feliz. Esse é o objetivo principal da linguagem Ruby." Ele salienta que projeto de sistemas precisa enfatizar humana, em vez de computador, precisa:

Muitas vezes as pessoas, especialmente os engenheiros de computador, focar as máquinas. Eles pensam: "Ao fazer isso, a máquina irá correr rápido. Ao fazer isso, a máquina será executado de forma mais eficaz. Ao fazer isso, a máquina será algo algo algo." Eles estão se concentrando em máquinas. Mas, na verdade temos de nos concentrar em seres humanos, sobre a forma como os seres humanos se preocupam fazendo programação e operação da aplicação das máquinas. Nós somos os mestres. Eles são os escravos.

Rubi é dito para seguir o princípio da menor surpresa (Pola), o que significa que a linguagem deve comportar-se de modo a minimizar a confusão para usuários experientes. Matsumoto disse que seu principal objetivo do projeto era fazer uma linguagem que ele mesmo gostava de usar, minimizando o trabalho programador e possíveis confusões. Ele disse que não tinha aplicado o princípio da menor surpresa ao desenho de Ruby, mas, no entanto a frase passou a ser intimamente associada com a linguagem de programação Ruby. A frase em si tem sido uma fonte de surpresa, como os usuários novatos podem levá-lo para dizer que os comportamentos de Ruby tentar igualar perto comportamentos familiares de outras línguas. Em 2005 a discussão de maio na comp.lang.ruby newsgroup, Matsumoto tentou distanciar-rubi de Pola, explicando que porque qualquer escolha de design vai ser surpreendente para alguém, ele usa um padrão pessoal na avaliação de surpresa. Se esse padrão pessoal permanece consistente, haveria algumas surpresas para aqueles familiarizados com o padrão.

Matsumoto definido desta maneira em uma entrevista:

Todo mundo tem um fundo individual. Alguém pode vir de Python, alguém pode vir de Perl, e eles podem ser surpreendidos por diferentes aspectos da linguagem. Em seguida, eles vêm até mim e dizem: 'Fiquei surpreso com esta característica da linguagem, então o Ruby viola o princípio da menor surpresa.' Esperar. Esperar. O princípio da menor surpresa não é apenas para si. O princípio da menor surpresa significa princípio do menor a minha surpresa. E isso significa que o princípio da menor surpresa depois de aprender Ruby muito bem. Por exemplo, eu era um programador C ++ antes de começar a projetar Ruby. I programado em C ++ exclusivamente para dois ou três anos. E depois de dois anos de programação C ++, ele ainda me surpreende.

Características

Semântica

Ruby é orientada a objeto : cada valor é um objeto, incluindo classes e instâncias de tipos que muitas outras línguas designam como primitivos (como números inteiros , booleanos, e " nulo "). Variáveis sempre manter referências a objetos. Cada função é um método e métodos são sempre chamados em um objeto. Métodos definidos no escopo nível superior tornar-se métodos da classe Object. Uma vez que esta classe é um ancestral de todas as outras classes, tais métodos podem ser chamados em qualquer objeto. Eles também são visíveis em todos os âmbitos, servindo efetivamente como procedimentos "globais". Rubi suporta herança com expedição dinâmica , mixins e métodos únicos (pertencentes a, e definida por, um único exemplo , em vez de ser definida na classe). Embora o Ruby não suporta herança múltipla , classes podem importar módulos como mixins.

Rubi tem sido descrito como uma linguagem de programação multi-paradigma : permite programação procedural (definindo funções / variáveis fora das aulas os torna parte da raiz, 'self' Object), com orientação a objetos (tudo é um objeto) ou de programação funcional (-lo tem funções anônimas , fechamentos e continuações ; demonstrações todos possuem valores e funções retornam a última avaliação). Tem suporte para a introspecção , reflexão e metaprogramming , bem como suporte para sistemas baseados intérprete tópicos . Ruby tem tipagem dinâmica , e suporta polimorfismo paramétrico .

De acordo com o rubi FAQ, a sintaxe é semelhante ao Perl e a semântica são semelhantes aos Smalltalk , mas difere muito do Python .

Sintaxe

A sintaxe de Ruby é muito semelhante ao de Perl e Python . Definições de classe e método são assinaladas por palavras-chave, enquanto que blocos de código podem ser ambos definidos por palavras-chave ou chaves. Em contraste com Perl, variáveis não são obrigatoriamente prefixado com um sigilo . Quando utilizado, o sigilo muda a semântica do âmbito da variável. Para fins práticos, não há distinção entre expressões e declarações . Quebras de linha são significativos e tomado como o fim de uma instrução; um ponto e vírgula pode ser usado equivalentemente. Ao contrário do Python, recuo não é significativa.

Uma das diferenças de Python e Perl é que Ruby mantém todas as suas variáveis de instância completamente privadas para a classe e só expõe-los através de métodos de acesso ( attr_writer, attr_reader, etc.). Ao contrário da "getter" e "Setter" métodos de outras linguagens como C ++ ou Java , métodos de acesso em Ruby pode ser criada com uma única linha de código via metaprogramação ; no entanto, métodos de acesso também pode ser criada na forma tradicional de C ++ e Java. Como invocação destes métodos não requer o uso de parênteses, é trivial para mudar uma variável de instância em uma função cheia, sem modificar uma única linha de código de chamada ou ter que fazer qualquer refatoração alcançar funcionalidade semelhante para C # e VB.NET propriedade membros.

Descritores de propriedade do Python são semelhantes, mas vêm com uma troca no processo de desenvolvimento. Se um começa em Python usando uma variável de instância exposta publicamente, e mais tarde muda a implementação de usar uma variável de instância privada exposta através de um descritor de propriedade, código interno para a classe podem precisar de ser ajustados para usar a variável privada em vez da propriedade pública . Projeto de Ruby obriga todas as variáveis de instância seja privado, mas também fornece uma maneira simples de declarar sete getmétodos. Isto está de acordo com a ideia de que em Ruby, um acede nunca diretamente os membros internos de uma classe de fora da classe; em vez disso, passa-se uma mensagem para a classe e recebe uma resposta.

Veja os exemplos abaixo para obter amostras de código demonstrando sintaxe Ruby.

Interação

A distribuição oficial Rubi também inclui irb, de um intérprete de linha de comando interativa que pode ser usado para código de teste rapidamente. O fragmento de código que se segue representa uma sessão de amostra usando irb:

$ irb
irb(main):001:0> puts 'Hello, World'
Hello, World
 => nil
irb(main):002:0> 1+2
 => 3

Exemplos

Os exemplos a seguir podem ser executados em um shell de Ruby, como Ruby interativo Shell , ou salvos em um arquivo e executado a partir da linha de comando digitando . ruby <filename>

Clássico Olá, mundo exemplo:

puts 'Hello World!'

Alguns código Ruby básica:

# Everything, including a literal, is an object, so this works:
-199.abs                                                 # => 199
'ice is nice'.length                                     # => 11
'ruby is cool.'.index('u')                               # => 1
"Nice Day Isn't It?".downcase.split('').uniq.sort.join   
# => " '?acdeinsty"

Entrada:

print 'Please type name >'
name = gets.chomp
puts "Hello #{name}."

conversões:

puts 'Give me a number'
number = gets.chomp
puts number.to_i
output_number = number.to_i + 1
puts output_number.to_s + ' is a bigger number.'

Cordas

Há uma variedade de maneiras de definir cordas em Ruby.

As seguintes atribuições são equivalentes:

a = "\nThis is a double-quoted string\n"
a = %Q{\nThis is a double-quoted string\n}
a = %{\nThis is a double-quoted string\n}
a = %/\nThis is a double-quoted string\n/
a = <<-BLOCK

This is a double-quoted string
BLOCK

Cordas apoiar interpolação variável :

var = 3.14159
"pi is #{var}"
=> "pi is 3.14159"

As seguintes atribuições são equivalentes e produzir cordas matérias :

a = 'This is a single-quoted string'
a = %q{This is a single-quoted string}

Colecções

Construção e utilização de uma matriz :

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

a[2]             # => 3.14
a.[](2)          # => 3.14
a.reverse        # => [[4, 5], 2, 1, 3.14, 'hi', 1]
a.flatten.uniq   # => [1, 'hi', 3.14, 2, 4, 5]

Construção e utilização de uma matriz associativa (em Ruby, chamado um hash de ):

hash = Hash.new # equivalent to hash = {}
hash = { :water => 'wet', :fire => 'hot' } # makes the previous line redundant as we are now
                                           # assigning hash to a new, separate hash object
puts hash[:fire] # prints "hot"

hash.each_pair do |key, value|   # or: hash.each do |key, value|
  puts "#{key} is #{value}"
end
# returns {:water=>"wet", :fire=>"hot"} and prints:
# water is wet
# fire is hot

hash.delete :water                            # deletes the pair :water => 'wet' and returns "wet"
hash.delete_if {|key,value| value == 'hot'}   # deletes the pair :fire => 'hot' and returns {}

estruturas de controle

Se declaração:

# Generate a random number and print whether it's even or odd.
if rand(100).even?
  puts "It's even"
else
  puts "It's odd"
end

Blocos e iterators

As duas sintaxes para a criação de um bloco de código:

{ puts 'Hello, World!' } # note the braces
# or:
do
  puts 'Hello, World!'
end

Um bloco de código pode ser passado para um método como um argumento bloco opcional. Muitos métodos internos têm tais argumentos:

File.open('file.txt', 'w') do |file| # 'w' denotes "write mode"
  file.puts 'Wrote some text.'
end                                  # file is automatically closed here

File.readlines('file.txt').each do |line|
  puts line
end
# => Wrote some text.

Parâmetro de passagem de um bloco para ser um fechamento :

# In an object instance variable (denoted with '@'), remember a block.
def remember(&a_block)
  @block = a_block
end

# Invoke the preceding method, giving it a block that takes a name.
remember {|name| puts "Hello, #{name}!"}

# Call the closure (note that this happens not to close over any free variables):
@block.call('Jon')   # => "Hello, Jon!"

Criando uma função anônima :

proc {|arg| puts arg}
Proc.new {|arg| puts arg}
lambda {|arg| puts arg}
->(arg) {puts arg}         # introduced in Ruby 1.9

Voltando fechos a partir de um método de:

def create_set_and_get(initial_value=0) # note the default value of 0
  closure_value = initial_value
  [ Proc.new {|x| closure_value = x}, Proc.new { closure_value } ]
end

setter, getter = create_set_and_get  # returns two values
setter.call(21)
getter.call      # => 21

# Parameter variables can also be used as a binding for the closure,
# so the preceding can be rewritten as:

def create_set_and_get(closure_value=0)
  [ proc {|x| closure_value = x } , proc { closure_value } ]
end

Produzindo o fluxo de controle do programa para um bloco que foi fornecido no momento chamando:

def use_hello
  yield "hello"
end

# Invoke the preceding method, passing it a block.
use_hello {|string| puts string}  # => 'hello'

Iteração sobre enumerações e arrays usando blocos:

array = [1, 'hi', 3.14]
array.each {|item| puts item }
# prints:
# 1
# 'hi'
# 3.14

array.each_index {|index| puts "#{index}: #{array[index]}" }
# prints:
# 0: 1
# 1: 'hi'
# 2: 3.14

# The following uses a (a..b) Range
(3..6).each {|num| puts num }
# prints:
# 3
# 4
# 5
# 6

# The following uses a (a...b) Range
(3...6).each {|num| puts num }
# prints:
# 3
# 4
# 5

Um método tal como injectpode aceitar tanto um parâmetro e um bloco. Os injectitera método sobre cada um dos membros de uma lista, que executam alguma função em que, mantendo um agregado. Isso é análogo à foldlfunção em linguagens de programação funcional . Por exemplo:

[1,3,5].inject(10) {|sum, element| sum + element}   # => 19

Na primeira passagem, o bloco 10 recebe (o argumento para injectar) como sum, e um (o primeiro elemento da matriz) como element. Isso retorna 11, que torna-se então sumna próxima passagem. Adiciona-se a 3 para obter 14, que é então adicionada a 5 na terceira passagem, para retornar finalmente 19.

Usando uma enumeração e um bloco de quadratura os números de 1 a 10 (usando uma gama ):

(1..10).collect {|x| x*x}  # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Ou invocar um método em cada item ( mapé um sinônimo para collect):

(1..5).map(&:to_f)  # => [1.0, 2.0, 3.0, 4.0, 5.0]

Classes

O código a seguir define uma classe chamada Person. Além initialize, o construtor de costume para criar novos objetos, ele tem dois métodos: um para substituir o <=>operador de comparação (assim Array#sortpode classificar por idade) e outro para substituir o to_smétodo (assim Kernel#putspode formatar a sua saída). Aqui, attr_readeré um exemplo de metaprogramação em Ruby: attr_accessordefine métodos getter e setter de variáveis de instância, mas attr_readerapenas métodos getter. A última declaração avaliada em um método é o seu valor de retorno, permitindo que a omissão de uma explícita returndeclaração.

class Person
  attr_reader :name, :age
  def initialize(name, age)
    @name, @age = name, age
  end
  def <=>(person) # the comparison operator for sorting
    @age <=> person.age
  end
  def to_s
    "#{@name} (#{@age})"
  end
end

group = [
  Person.new("Bob", 33),
  Person.new("Chris", 16),
  Person.new("Ash", 23)
]

puts group.sort.reverse

O código anterior imprime três nomes em ordem inversa idade:

Bob (33)
Ash (23)
Chris (16)

Personé uma constante e é uma referência a um Classobjecto.

aulas abertas

Em Ruby, as classes nunca são fechadas: métodos podem sempre ser adicionados a uma classe existente. Isso se aplica a todas as classes, incluindo o padrão, built-in classes. Tudo que é necessário fazer é abrir uma definição de classe para uma classe existente, e os novos conteúdos especificados serão adicionados aos conteúdos existentes. Um exemplo simples de adicionar um novo método para a biblioteca padrão Timede classe:

# re-open Ruby's Time class
class Time
  def yesterday
    self - 86400
  end
end

today = Time.now               # => 2013-09-03 16:09:37 +0300
yesterday = today.yesterday    # => 2013-09-02 16:09:37 +0300

Adicionando métodos a classes previamente definidas é muitas vezes chamado de macaco-patching . Se realizada de forma imprudente, a prática pode levar a ambas as colisões de comportamento com resultados inesperados subseqüentes e problemas de escalabilidade código.

Desde Rubi 2,0 tem sido possível utilizar refinamentos para reduzir as consequências potencialmente negativas de macaco-patching, limitando o âmbito do remendo para áreas particulares da base de código.

# re-open Ruby's Time class
module RelativeTimeExtensions
  refine Time do
    def half_a_day_ago
      self - 43200
    end
  end
end

module MyModule
  class MyClass
    # Allow the refinement to be used
    using RelativeTimeExtensions

    def window
      Time.now.half_a_day_ago
    end
  end
end

exceções

Uma exceção é gerada com uma raisechamada:

raise

Uma mensagem opcional pode ser adicionado à exceção:

raise "This is a message"

Exceções também podem ser especificados pelo programador:

raise ArgumentError, "Illegal arguments!"

Alternativamente, um exemplo excepção pode ser passado para o raisemétodo:

raise ArgumentError.new("Illegal arguments!")

Esta última construção é útil quando levantando uma instância de uma classe de exceção personalizada com um construtor que leva mais de um argumento:

class ParseError < Exception
  def initialize(input, line, pos)
    super "Could not parse '#{input}' at line #{line}, position #{pos}"
  end
end

raise ParseError.new("Foo", 3, 9)

Exceções são tratadas pela rescuecláusula. Tal cláusula pode capturar exceções que herdam StandardError. Outras palavras-chave de controle de fluxo que podem ser usadas ao manusear exceções são elsee ensure:

begin
  # do something
rescue
  # handle exception
else
  # do this if no exception was raised
ensure
  # do this whether or not an exception was raised
end

É um erro comum para tentar capturar todas as exceções com uma cláusula de resgate simples. Para capturar todas as exceções deve-se escrever:

begin
  # do something
rescue Exception
  # Exception handling code here.
  # Don't write only "rescue"; that only catches StandardError, a subclass of Exception.
end

Ou capturar exceções particulares:

begin
  # do something
rescue RuntimeError
  # handle only RuntimeError and its subclasses
end

Também é possível especificar que o objeto de exceção ser disponibilizados para a cláusula de manipulador:

begin
  # do something
rescue RuntimeError => e
  # handling, possibly involving e, such as "puts e.to_s"
end

Alternativamente, a exceção mais recente é armazenado no mundial mágica $!.

Várias exceções também podem ser capturados:

begin
  # do something
rescue RuntimeError, Timeout::Error => e
  # handling, possibly involving e
end

metaprogramação

Código Ruby pode modificar programaticamente, em tempo de execução , aspectos de sua própria estrutura, que seria fixado em linguagens mais rígidas, como definições de classes e métodos. Este tipo de metaprogramming pode ser usado para escrever o código mais conciso e eficaz estender a linguagem.

Por exemplo, o seguinte código Ruby gera novos métodos para o built-in Stringde classe, com base em uma lista de cores. Os métodos de envolver o conteúdo da string com uma tag HTML denominado com a respectiva cor.

COLORS = { black:   "000",
           red:     "f00",
           green:   "0f0",
           yellow:  "ff0",
           blue:    "00f",
           magenta: "f0f",
           cyan:    "0ff",
           white:   "fff" }

class String
  COLORS.each do |color,code|
    define_method "in_#{color}" do
      "<span style=\"color: ##{code}\">#{self}</span>"
    end
  end
end

Os métodos gerado pode então ser utilizado da seguinte forma:

"Hello, World!".in_blue
 => "<span style=\"color: #00f\">Hello, World!</span>"

Para implementar o equivalente em muitas outras línguas, o programador teria que escrever cada método ( in_black, in_red, in_green, etc.) separadamente.

Alguns outros usos possíveis para Ruby metaprogramming incluem:

  • interceptar e modificar as chamadas de método
  • implementação de novos modelos de herança
  • gerar dinamicamente as classes de parâmetros
  • serialização de objetos automática
  • ajuda interativa e depuração

Mais exemplos

Mais amostra de código Ruby é disponível como algoritmos no seguinte artigo:

implementações

intérprete Ruby Matz

The Ruby originais intérprete é muitas vezes referido como o rubi intérprete de Matz ou ressonância magnética. Esta implementação é escrito em C e usa seu próprio Rubi específicos de máquina virtual .

A padronizado e retirou-rubi 1,8 implementação foi escrita em C , como uma passagem única linguagem interpretada .

Começando com Ruby 1.9, e continuando com Ruby 2.xe acima, o intérprete oficial Rubi tem sido YARV ( "Yet Another Rubi VM"), e esta aplicação substituiu a máquina virtual mais lento utilizado em versões anteriores do MRI.

implementações alternativas

A partir de 2018, há um número de implementações alternativas de rubi, incluindo JRuby , Rubinius , e mruby . Cada tem uma abordagem diferente, com JRuby e Rubinius fornecendo compilação just-in-time e mruby também fornecendo compilação antes-do-tempo .

Ruby tem três principais implementações alternativas:

  • JRuby , um Java aplicação que roda na máquina virtual Java . JRuby atualmente tem como alvo o Ruby 2.3.
  • TruffleRuby , uma implementação Java usando a estrutura de implementação da linguagem Truffle com GraalVM
  • Rubinius , um C ++ máquina virtual código de bytes que usa LLVM para compilar a código de máquina em tempo de execução. O compilador bytecode e classes mais centrais são escritas em Ruby puro. Rubinius atualmente objetiva o Ruby 2.1,

Outras implementações de Ruby incluem:

  • MagLev , um Smalltalk aplicação que roda em GemTalk Sistemas ' GemStone / S VM
  • mruby , uma aplicação concebida para ser incorporada em código C, de modo semelhante a Lua . Atualmente está sendo desenvolvido por Yukihiro Matsumoto e outros
  • RGSS, ou Ruby Game System Scripting, uma proprietária de implementação que é usada pelo Criador RPG série de software para design de jogo e modificação do motor RPG Maker
  • Um transpiler (parcial) a partir de Ruby para Julia , julializer está disponível. Ele pode ser usado para um grande aumento de velocidade sobre por exemplo implementações JRuby (só pode ser útil para um código numérico) rubi ou.
  • Topaz , a implementação de Ruby escrito em Python
  • Opal , um intérprete baseado na Web que compila Ruby para JavaScript

Outras implementações de Ruby agora extintas foram:

A maturidade de implementações de Ruby tende a ser medido pela sua capacidade de executar o Ruby on Rails (Rails) quadro, porque é complexo para implementar e usa muitos recursos específicos do Ruby. O ponto quando uma implementação específica atinge este objetivo é chamado de "o Rails singularidade". A implementação de referência (RM) , JRuby e Rubinius são todos capazes de rodar Rails não modificados em um ambiente de produção.

suporte à plataforma

Matsumoto originalmente fez o desenvolvimento Ruby on a 4.3BSD baseados Sony NEWS-OS 3.x, mas depois migrou seu trabalho para SunOS 4.x, e finalmente para Linux .

Em 1999, Ruby era conhecido por trabalhar em diversos sistemas operacionais , incluindo NEWS-OS, SunOS, AIX , SVR4 , Solaris , NEC UP-UX , NeXTSTEP , BSD, Linux, Mac OS , DOS , o Windows , e BeOS .

Versões e implementações modernas do rubi estão disponíveis em vários sistemas operacionais, como Linux, BSD, Solaris, AIX, MacOS , o Windows, Windows Phone , Windows CE , Symbian OS , BeOS, e IBM i .

Repositórios e bibliotecas

RubyGems é o gerenciador de pacotes do Ruby. Um pacote de Ruby é chamado de "jóia" e pode ser facilmente instalado através da linha de comando. A maioria das gemas são bibliotecas, embora alguns existem que são aplicações, tais como IDEs . Há mais de 9.000 pedras preciosas rubi hospedados em RubyGems.org .

Muitas bibliotecas Ruby novos e existentes estão hospedados no GitHub , um serviço que oferece controle de versão repositório de hospedagem para Git .

O Application Archive Ruby, que sediou aplicações, documentação e bibliotecas para programação Ruby, foi mantida até 2013, quando sua função foi transferida para RubyGems.

Veja também

Referências

Outras leituras

links externos