Arrays Ruby

Um Array (arranjo) é apenas uma lista de itens em ordem (como mangas, maçãs e laranjas). Cada posição na lista atua como uma variável: você pode ver para qual objeto uma determinada posição aponta, e você pode fazer ela apontar para um objeto diferente. Você pode fazer um array usando colchetes. Em Ruby, o primeiro valor em um array tem o índice 0. Os métodos size e length retornam o número de elementos no array. O último elemento de um array está no índice size-1. Valores negativos de índice são contados a partir do final do array, de modo que o último elemento de um array pode ser acessado com um índice -1. Se você tentar ler um elemento além do final do array (com um índice >= size) ou antes do início do array (com índice < -size), o Ruby simplesmente retornará nil (nulo) e não lançará uma exceção. Os arrays em Ruby são mutáveis – arrays são redimensionados dinamicamente; você pode acrescentar elementos a eles e eles crescem o necessário. Vamos olhar para o seguinte exemplo p018arrays.rb. Por favor, siga pelo programa com atenção.

 1 # p018arrays.rb
 2 # Arrays
 3 
 4 # array vazio
 5 var1 = []
 6 # Índice do array inicia em 0
 7 puts var1[0]
 8 
 9 var2 = [5]
10 # um array armazenando apenas um número
11 puts var2[0]
12 
13 # um array armazenando duas strings
14 var3 = ['Olá', 'Tchau']
15 puts var3[0]
16 puts var3[1]
17 
18 sabor = 'manga'
19 # um array cujos elementos apontam para três
20 # objetos - um float, uma string e um array
21 var4 = [80.5, sabor, [true, false]]
22 puts var4[2]
23 
24 # uma vírgula no final é ignorada
25 name = ['Satish', 'Talim', 'Ruby', 'Java',]
26 puts name[0]
27 puts name[1]
28 puts name[2]
29 puts name[3]
30 # o próximo tem como saída nil
31 # nil é o jeito do Ruby dizer 'nada'
32 puts name[4]
33 # podemos adicionar mais elementos também
34 name[4] = 'Pune'
35 puts name[4]
36 # podemos adicionar qualquer coisa!
37 name[5] = 4.33
38 puts name[5]
39 # podemos adicionar um array a um array
40 name[6] = [1, 2, 3]
41 puts name[6]
42 
43 # alguns métodos da classe array
44 newarr = [45, 23, 1, 90]
45 puts newarr.sort
46 puts newarr.length
47 puts newarr.first
48 puts newarr.last
49 
50 # o método each (iterador - extrai cada elemento em lang
51 # do end é um bloco de código
52 # falaremos sobre blocos mais tarde
53 # a variável lang se refere a cada item no array a medida que ele é iterado no loop
54 linguas = ['Pune', 'Mumbai', 'Bangalore']
55 
56 linguas.each do |lang|
57   puts 'Eu amo ' + lang + '!'
58   puts 'voce nao?'
59 end
60 
61 # apaga uma entrada no meio e desloca o restante da entradas
62 linguas.delete('Mumbai')
63 
64 linguas.each do |lang|
65   puts 'Eu amo ' + lang + '!'
66   puts 'voce nao?'
67 end

O método each (para qualquer objeto) permite-nos fazer algo (o que quisermos) para cada (each) objeto para o qual o array aponta. No exemplo, somos capazes de iterar sobre o array sem usar nenhum número. Aqui estão algumas coisas para se lembrar:

Aqui está um exemplo interessante de um método que retorna um array. Exemplo p019mtdarry.rb.

 1 # p019mtdarry.rb
 2 # se você dá ao return multiplos parâmetros.
 3 # o método os retornará em um array
 4 # o método times da classe Integer itera num vezes,
 5 # passando para num os valores de 0 a num-1
 6 
 7 def mtdarry
 8   10.times do |num|
 9     quadrado = num * num
10     return num, quadrado if n > 5
11   end
12 end
13 
14 # usando atribuição paralela para coletar o valor de retorno
15 num, quadrado = mtdarry
16 puts num
17 puts quadrado

A saída é:

1 >ruby p019mtdarry.rb
2 6
3 36
4 >Exit code: 0

O método times da classe Integer (inteiro) itera o bloco n vezes, passando os valores de zero a num-1. Como podemos ver, se você dá ao return múltiplos parâmetros, o método retorna estes em um array. Você pode usar a atribuição em paralelo para coletar esses valores de retorno.

Atribuição paralela

Para explicar isso, usaremos os termos lvalue (valor á esquerda) e rvalue (valor à direita).
Um lvalue é algo que pode aparecer por si mesmo no lado esquerdo de uma atribuição (uma variável, constante ou método que seta algum atributo). Um rvalue é algo que pode aparecer por si só no lado direito. Ruby permite que você tenha uma lista de rvalues separados por vírgula. Uma vez que o Ruby vê mais que um rvalue em uma atribuição, as regras de atribuição paralela entram em cena. Em primeiro lugar, todos os rvalues são avaliados, da esquerda para a direita e então coletados em um array (ao menos que eles já sejam um array). Este array será o valor retornado pela atribuição como um todo. Em seguida, o lado a esquerda é inspecionado. Se ele contém um único elemento, o array é associado a esse elemento.

1 a = 1, 2, 3, 4 # => a == [1, 2, 3, 4]
2 b = [1, 2, 3, 4] # => b == [1, 2, 3, 4]

Se o lado esquerdo contém uma vírgula, o Ruby casa os valores do lado direito com os sucessivos elementos do lado esquerdo. Os elementos que restam são descartados.

1 a, b = 1, 2, 3, 4 # => a == 1, b == 2
2 c, = 1, 2, 3, 4 # => c == 1

Variáveis de ambiente

Uma variável de ambiente é um link entre nosso programa e o mundo externo. Uma variável de ambiente é essencialmente um rótulo que se refere a um pedaço de texto; e pode ser usada para armazenar informações de configurações como caminhos, nomes de usuário e assim por diante. Você pode acessar variáveis de ambiente do sistema operacional usando a variável predefinida ENV.

1 ENV.each {|k,v| puts "#{k}: #{v}"}

Ruby seta ENV para as variáveis do ambiente. Após isso, a iteração procede com each. Desta vez o bloco recebe dois parâmetros:
k (chave) e v (valor). Blocos são um mecanismo completamente geral e podem receber qualquer número de argumentos.

Os valores de algumas variáveis de ambiente são lidos pelo Ruby quando ele inicializa. Essas variáveis modificam o comportamento
do interpretador, como mostrado na tabela abaixo.

Nome da variável Descrição
DLN_LIBRARY_PATH Busca no caminho (path) por módulos carregados dinamicamente
HOME Aponta para o diretório home do usuário. Usado para expandir o ~ em nomes de diretórios e arquivos
LOGDIR Ponteiro alternativo para o diretório home do usuário se $HOME não estiver setado. Usado apenas por Dir.chdir
OPENSSL_CONF Indica a localização do arquivo de configuração do OPenSSL
RUBYLIB Caminho de busca adicional para programas Ruby ($SAFE deve ser 0)
RUBYLIB_PREFIX (windows somente) ALtera o caminho de RUBYLIB adicionando esse prefixo a cada componente
RUBYOPT opções adicionais de linha de comando ao Ruby; examinado após as opções reais de linha de comando
serem parseadas ($SAFE deve ser 0)
RUBYPATH com a opção -S, busca o camnho para programas Ruby (o padrão é o PATH)
RUBYSHELL Shell a se usar quando criando um novo processo no Windows; se não setado, checará também SHELL
ou COMPSPEC
RUBY_TCL_DLL sobrescreve o nome padrão para a bibliota compartilhada ou DLL do TCL
RUBY_TK_DLL sobrescreve o nome padrão para a bibliota compartilhada ou DLL do Tk tanto essa variável como a do TCL precisando ser setadas para se usar uma das duas bibliotecas

Um programa Ruby pode escrever no objeto ENV. Na maioria dos sistemas isso muda os valores das variáveis de ambiente correspondentes. Entretanto, essa mudança é local para o processo que a faz e para qualquer processo filho criado. Um subprocesso altera uma variável de ambiente e essa mudança é herdada por um processo que é iniciado pelo primeiro. Entretanto, a mudança não é visível para o pai original (isso apenas serve para provar que os pais realmente nunca sabem o que seus filhos estão fazendo).

1 ENV["course"] = "FORPC101"
2 puts "#{ENV['course']}"

Argumentos de linha de comando

Se você está iniciando um programa da linha de comando, você pode adicionar parâmetros no final do comando e estes serão processados pelo programa.

Você pode fazer o mesmo com sua aplicação Ruby. O Ruby automaticamente coloca qualquer parâmetro que são adicionados à linha de comando quando você executa seu programa Ruby em um array especial chamado ARGV. Se seu programa é:

1 f = ARGV[0]
2 puts f

Você pode executar esse programa da linha de comando assim:

1 ruby tmp.rb 23

E o programa deve mostrar 23 como saída.

Biblioteca GetoptLong

A Classe GetoptLong suporta o parsing de opções de linha de comando. As opções podem ter um sinal de menos (-) seguido por um único caractere ou dois sinais de menos (—) seguidos por um nome (uma opção longa).

As opções podem ser dadas em qualquer ordem. Uma única opção interna pode ter múltiplas representações externas. Por exemplo, a opção para controlar a saída verbosa pode ser tanto -v, —verbose ou -details. Algumas opções podem também receber um valor associado. Cada opção interna é passada a GetoptLong como um array, contendo strings representando as formas externas e uma flag. A flag especifica como GetoptLong é associada ao argumento com a opção (NO_ARGUMENT, REQUIRED_ARGUMENT, or OPTIONAL_ARGUMENT).

Suponha que eu queira chamar um programa Ruby assim:

1 ruby tsftpc.rb -hftp.ibiblio.org -n21 -uanonymous -ps@s.com

Aqui está o código de como fazê-lo:

 1 require 'getoptlong'
 2 
 3 # Chame usando "ruby tsftpc.rb -hftp.ibiblio.org -n21 -uanonymous -ps@s.com"
 4 # Os parâmetros podem estar em qualquer ordem
 5 unless ARGV.length == 4
 6   puts "Uso: ruby tsftpc.rb -hftp_site_url -nport_no -uuser_name -ppassword"
 7   exit
 8 end
 9 
10 host_name = port_no = user_name = password = ''
11 # specifica a opção que aceitamos e
12 # inicializa o parser de opções
13 opts = GetoptLong.new(
14 [ "--hostname", "-h", GetoptLong::REQUIRED_ARGUMENT ],
15 [ "--port", "-n", GetoptLong::REQUIRED_ARGUMENT ],
16 [ "--username", "-u", GetoptLong::REQUIRED_ARGUMENT ],
17 [ "--pass", "-p", GetoptLong::REQUIRED_ARGUMENT ]
18 )
19 # processa as opções parseadas
20 opts.each do |opt, arg|
21   case opt
22     when '--hostname'
23       host_name = arg
24     when '--port'
25       port_no = arg
26     when '--username'
27       user_name = arg
28     when '--pass'
29       password = arg
30   end
31 end

require te dá acesso as muitas extensões e bibliotecas de programação que vem com a linguagem Ruby – além de um número maior ainda de extensões e bibliotecas escritas independentemente por outros programadores e tornadas disponíveis para se usar com Ruby. Nós estudaremos o require em mais detalhas mais tarde. Além disso, mais tarde, deveremos estudar como acessar constantes usando ::

Como converto objetos em um Array? Se você quer empacotar objetos em um Array, você pode usar um método especial Array do módulo Kernel (que começa com letra maiúscula e se parece com uma classe). Esse método especial converte seus argumentos em um array. Por exemplo:

1 str = 'ola'
2 print Array(str).class # Array

Outro exemplo:

1 str = 'ola\nmundo'
2 print Array(str) # ["ola\nmundo"]

Quais são os ancestrais de Array? Rode o segunte programa para descobrir:

1 a = [1,2,3,4]
2 print a.class.ancestors

Você verá:

1 [Array, Enumerable, Object, Kernel, BasicObject]

Você pode ver os detalhes da classe Array na documentação oficial do Ruby.

Logo do Guru-SP

Este material tem como base o tutorial do RubyLearning.com de Satish Talim e foi traduzido por membros do GURU-SP com a permissão do autor.

Ajude o RubyLearning participando em algum dos cursos pagos ou fazendo uma doação para o projeto

Voltar para o índice