Sei sulla pagina 1di 155

Anúncios

Página anterior Próxima página

Ruby é uma linguagem de programação pura orientada a objetos. Foi criado em 1993 por
Yukihiro Matsumoto do Japão.

Você pode encontrar o nome Yukihiro Matsumoto na lista de discussão Ruby em


www.ruby-lang.org . Matsumoto também é conhecido como Matz na comunidade Ruby.

Ruby é "o melhor amigo de um programador".

O Ruby possui recursos semelhantes aos do Smalltalk, Perl e Python. Perl, Python e
Smalltalk são linguagens de script. O Smalltalk é uma verdadeira linguagem orientada a
objetos. O Ruby, como o Smalltalk, é uma linguagem perfeita orientada a objetos. Usar a
sintaxe do Ruby é muito mais fácil do que usar a sintaxe do Smalltalk.

Ruby é um código aberto e está disponível gratuitamente na Web,Recursos do Ruby


mas está sujeito a uma licença.

Ruby é uma linguagem de programação interpretada de propósito geral.

Ruby é uma verdadeira linguagem de programação orientada a objetos.

Ruby é uma linguagem de script do lado do servidor semelhante a Python e PERL.

Ruby pode ser usado para escrever scripts CGI (Common Gateway Interface).

Ruby pode ser incorporado em HTML (Hypertext Markup Language).

O Ruby possui uma sintaxe limpa e fácil que permite que um novo desenvolvedor
aprenda de maneira rápida e fácil.

Ruby tem uma sintaxe semelhante à de muitas linguagens de programação, como C


++ e Perl.

Ruby é muito escalável e grandes programas escritos em Ruby são facilmente


mantidos.

O Ruby pode ser usado para desenvolver aplicativos de Internet e intranet.


O Ruby pode ser instalado em ambientes Windows e POSIX.

Ruby suporta muitas ferramentas GUI, como Tcl / Tk, GTK e OpenGL.

O Ruby pode ser facilmente conectado ao DB2, MySQL, Oracle e Sybase.

O Ruby possui um rico conjunto de funções internas, que podem ser usadas
diretamente em scripts Ruby.

Para executar os exemplos discutidos neste tutorial, vocêFerramentas que você precisará
precisará de um computador mais recente como o Intel Core i3
ou i5 com um mínimo de 2 GB de RAM (recomenda-se 4 GB de RAM). Você também
precisará do seguinte software -

Sistema operacional Linux ou Windows 95/98/2000 / NT ou Windows 7.

Servidor Web Apache 1.3.19-5.

Navegador da Web do Internet Explorer 5.0 ou superior.

Ruby 1.8.5

Este tutorial fornecerá as habilidades necessárias para criar GUI, rede e aplicativos da Web
usando o Ruby. Ele também falará sobre estender e incorporar aplicativos Ruby.

O próximo capítulo orienta você para onde você pode obter Ruby e suaO que é o próximo?
documentação. Finalmente, ele instrui sobre como instalar o Ruby e
preparar um ambiente para desenvolver aplicativos Ruby.

Se você ainda estiver disposto a configurar seu ambiente para aConfiguração do ambiente local
linguagem de programação Ruby, então vamos continuar. Este
tutorial ensinará todos os tópicos importantes relacionados à configuração do ambiente.
Recomendamos que você analise os tópicos a seguir primeiro e, em seguida, prossiga.

Instalação Ruby no Linux / Unix - Se você está planejando ter seu ambiente de
desenvolvimento no Linux / Unix Machine, então siga este capítulo.

Instalação Ruby no Windows - Se você planeja ter seu ambiente de


desenvolvimento no Windows Machine, siga este capítulo.

Ruby Command Line Options - Este capítulo lista todas as opções de linha de
comando, que você pode usar junto com o interpretador Ruby.

Ruby Environment Variables - Este capítulo tem uma lista de todas as variáveis
de ambiente importantes a serem configuradas para fazer o interpretador de Ruby
funcionar.

Para escrever seus programas Ruby, você precisará de um editor - Editores de rubis populares
Se você estiver trabalhando na máquina Windows, poderá usar qualquer editor de
texto simples como o Bloco de notas ou Editar mais.

VIM (Vi IMproved) é um editor de texto muito simples. Isso está disponível em
quase todas as máquinas Unix e agora também no Windows. Caso contrário, você
pode usar seu editor vi favorito para escrever programas Ruby.

RubyWin é um Ambiente de Desenvolvimento Integrado (IDE) do Ruby para


Windows.

O Ambiente de Desenvolvimento Ruby (RDE) também é um IDE muito bom para


usuários do Windows.

O Ruby Interativo (IRb) fornece um shell para experimentação. Dentro Ruby Interativo (IRb)
do shell IRb, você pode visualizar imediatamente os resultados da
expressão, linha por linha.

Esta ferramenta vem junto com a instalação do Ruby, então você não tem nada a fazer para
ter o IRb funcionando.

Basta digitar irb no seu prompt de comando e uma Sessão Interativa Ruby iniciará
conforme abaixo:

$irb
irb 0.6.1(99/09/16)
irb(main):001:0> def hello
irb(main):002:1> out = "Hello World"
irb(main):003:1> puts out
irb(main):004:1> end
nil
irb(main):005:0> hello
Hello World
nil
irb(main):006:0>

Não se preocupe com o que fizemos aqui. Você aprenderá todas essas etapas nos capítulos
subseqüentes.

Nós assumimos que agora você tem um Ambiente Ruby funcional e vocêO que é o próximo?
está pronto para escrever o primeiro Programa Ruby. O próximo capítulo
ensinará como escrever programas em Ruby.

Vamos escrever um programa simples em ruby. Todos os arquivos ruby terão extensão .rb .
Então, coloque o seguinte código-fonte em um arquivo test.rb.

#!/usr/bin/ruby -w

puts "Hello, Ruby!";

Aqui, assumimos que você tem o interpretador Ruby disponível no diretório / usr / bin.
Agora, tente executar este programa da seguinte maneira -

$ ruby test.rb

Isso produzirá o seguinte resultado -

Hello, Ruby!

Você viu um programa Ruby simples, agora vamos ver alguns conceitos básicos
relacionados à sintaxe do Ruby.

Caracteres em branco, como espaços e guias, sãoEspaço em branco no programa Ruby


geralmente ignorados no código Ruby, exceto quando
aparecem em strings. Às vezes, porém, eles são usados para interpretar declarações
ambíguas. Interpretações desse tipo produzem avisos quando a opção -w está ativada.

a + b is interpreted as a+b ( Here a is a local variable)


a +b is interpreted as a(+b) ( Here a is a method call)

Ruby interpreta ponto-e-vírgula e caracteres de nova linhaEndings de linha no programa Ruby


como o final de uma instrução. No entanto, se Ruby
encontrar operadores, como +, - ou backslash no final de uma linha, eles indicam a
continuação de uma instrução.

Identificadores são nomes de variáveis, constantes e métodos.Identificadores Ruby


Identificadores Ruby diferenciam maiúsculas de minúsculas. Isso significa
que Ram e RAM são dois identificadores diferentes em Ruby.

Os nomes de identificadores Ruby podem consistir em caracteres alfanuméricos e o


caractere de sublinhado (_).

A lista a seguir mostra as palavras reservadas no Ruby. Essas palavrasPalavras reservadas


reservadas não podem ser usadas como nomes constantes ou variáveis.
Eles podem, no entanto, ser usados como nomes de métodos.

INÍCIO Faz Próximo então

FIM outro nada verdade

alias elsif não undef

e fim ou a não ser que

início garantir refazer até

pausa falso resgatar quando

caso para tente novamente enquanto


classe E se Retorna enquanto

def em auto __ARQUIVO__

definiram? módulo super __LINHA__

"Aqui Documento" refere-se a construir cadeias de várias linhas.Aqui documento em Ruby


Seguindo um << você pode especificar uma string ou um
identificador para terminar o literal da string, e todas as linhas seguindo a linha atual até o
terminador são o valor da string.

Se o terminador for citado, o tipo de aspas determina o tipo do literal da cadeia orientada a
linhas. Observe que não deve haver espaço entre << e o terminador.

Aqui estão alguns exemplos diferentes

#!/usr/bin/ruby -w

print <<EOF
This is the first way of creating
here document ie. multiple line string.
EOF

print <<"EOF"; # same as above


This is the second way of creating
here document ie. multiple line string.
EOF

print <<`EOC` # execute commands


echo hi there
echo lo there
EOC

print <<"foo", <<"bar" # you can stack them


I said foo.
foo
I said bar.
bar

Isso produzirá o seguinte resultado -

This is the first way of creating


her document ie. multiple line string.
This is the second way of creating
her document ie. multiple line string.
hi there
lo there
I said foo.
I said bar.

Ruby BEGIN Statement

BEGIN {
code
}

Declara o código a ser chamado antes de o programa ser executado.

#!/usr/bin/ruby

puts "This is main Ruby Program"

BEGIN {
puts "Initializing Ruby Program"
}

Isso produzirá o seguinte resultado -

Initializing Ruby Program


This is main Ruby Program

Declaração Ruby END

END {
code
}

Declara o código a ser chamado no final do programa.

#!/usr/bin/ruby

puts "This is main Ruby Program"

END {
puts "Terminating Ruby Program"
}
BEGIN {
puts "Initializing Ruby Program"
}

Isso produzirá o seguinte resultado -

Initializing Ruby Program


This is main Ruby Program
Terminating Ruby Program

Um comentário oculta uma linha, parte de uma linha ou várias linhas doComentários Ruby
interpretador Ruby. Você pode usar o caractere hash (#) no início de uma
linha -

# I am a comment. Just ignore me.

Ou, um comentário pode estar na mesma linha depois de uma declaração ou expressão -
name = "Madisetti" # This is again comment

Você pode comentar várias linhas da seguinte maneira -

# This is a comment.
# This is a comment, too.
# This is a comment, too.
# I said that already.

Aqui está outra forma. Este comentário do bloco oculta várias linhas do interpretador com =
begin / = end -

= begin
This is a comment.
This is a comment, too.
This is a comment, too.
I said that already.
= end

Ruby é uma linguagem de programação orientada a objetos perfeita. Os recursos da


linguagem de programação orientada a objeto incluem -

Encapsulamento de dados

Abstração de dados

Polimorfismo

Herança

Esses recursos foram discutidos no capítulo Ruby Orientado a Objetos .

Um programa orientado a objeto envolve classes e objetos. Uma classe é o plano a partir do
qual objetos individuais são criados. Em termos orientados a objetos, dizemos que sua
bicicleta é uma instância da classe de objetos conhecidos como bicicletas.

Tomemos o exemplo de qualquer veículo. É composto por rodas, cavalos de potência e


capacidade do tanque de combustível ou gás. Essas características formam os membros de
dados da classe Vehicle. Você pode diferenciar um veículo do outro com a ajuda dessas
características.

Um veículo também pode ter certas funções, como parar, dirigir e acelerar. Até mesmo
essas funções formam os membros de dados da classe Vehicle. Você pode, portanto, definir
uma classe como uma combinação de características e funções.

Uma classe Veículo pode ser definida como -

Class Vehicle {

Number no_of_wheels
Number horsepower
Characters type_of_tank
Number Capacity
Function speeding {
}

Function driving {
}

Function halting {
}
}

Atribuindo valores diferentes a esses membros de dados, você pode formar várias instâncias
da classe Vehicle. Por exemplo, um avião tem três rodas, potência de 1.000, combustível
como o tipo de tanque e uma capacidade de 100 litros. Da mesma forma, um carro tem
quatro rodas, potência de 200, gás como o tipo de tanque e uma capacidade de 25 litros.

Para implementar a programação orientada a objetos usando oDefinindo uma classe em Ruby
Ruby, você precisa primeiro aprender como criar objetos e
classes no Ruby.

Uma classe em Ruby sempre começa com a classe de palavra-chave seguida pelo nome da
classe. O nome deve estar sempre em maiúsculas iniciais. A classe Cliente pode ser exibida
como -

class Customer
end

Você encerra uma classe usando o final da palavra-chave. Todos os membros de dados da
classe estão entre a definição de classe e a palavra-chave final .

Ruby fornece quatro tipos de variáveis - Variáveis em uma classe Ruby

Variáveis locais - Variáveis locais são as variáveis definidas em um método.


Variáveis locais não estão disponíveis fora do método. Você verá mais detalhes sobre
o método no capítulo subseqüente. Variáveis locais começam com uma letra
minúscula ou _.

Variáveis de instância - Variáveis de instância estão disponíveis em métodos


para qualquer instância ou objeto específico. Isso significa que as variáveis de
instância mudam de objeto para objeto. Variáveis de instância são precedidas pelo
sinal de arroba (@) seguido pelo nome da variável.

Variáveis de Classe - Variáveis de classe estão disponíveis em diferentes objetos.


Uma variável de classe pertence à classe e é uma característica de uma classe. Eles
são precedidos pelo sinal @@ e são seguidos pelo nome da variável.

Variáveis globais - as variáveis de classe não estão disponíveis nas classes. Se


você deseja ter uma única variável, que está disponível nas classes, você precisa
definir uma variável global. As variáveis globais são sempre precedidas pelo cifrão
($).

Usando a variável de classe @@ no_of_customers, você pode determinar o número de


objetos que estão sendo criados. Isso permite derivar o número de clientes.

class Customer
@@no_of_customers = 0
end

Objetos são instâncias da classe. Agora vocêCriando Objetos em Ruby usando o novo método
aprenderá a criar objetos de uma classe em Ruby.
Você pode criar objetos em Ruby usando o método new da classe.

O método new é um tipo exclusivo de método, que é predefinido na biblioteca Ruby. O novo
método pertence aos métodos de classe .

Aqui está o exemplo para criar dois objetos cust1 e cust2 da classe Customer -

cust1 = Customer. new


cust2 = Customer. new

Aqui, cust1 e cust2 são os nomes de dois objetos. Você escreve o nome do objeto seguido
pelo sinal de igual (=) após o qual o nome da classe se seguirá. Em seguida, o operador de
ponto e a palavra-chave new serão seguidos.

Você pode passar parâmetros para o método new eMétodo Customizado para Criar Objetos Ruby
esses parâmetros podem ser usados para inicializar
variáveis de classe.

Quando você planeja declarar o novo método com parâmetros, você precisa declarar o
método inicializar no momento da criação da classe.

O método initialize é um tipo especial de método, que será executado quando o novo
método da classe for chamado com parâmetros.

Aqui está o exemplo para criar o método initialize

class Customer
@@no_of_customers = 0
def initialize(id, name, addr)
@cust_id = id
@cust_name = name
@cust_addr = addr
end
end

Neste exemplo, você declara o método initialize com id, name e addr como variáveis
locais. Aqui, def e end são usados para definir uma inicialização do método Ruby. Você
aprenderá mais sobre métodos nos próximos capítulos.
No método initialize , você passa os valores dessas variáveis locais para as variáveis de
instância @cust_id, @cust_name e @cust_addr. Aqui, as variáveis locais mantêm os valores
que são passados junto com o novo método.

Agora, você pode criar objetos da seguinte maneira -

cust1 = Customer.new("1", "John", "Wisdom Apartments, Ludhiya")


cust2 = Customer.new("2", "Poul", "New Empire road, Khandala")

Em Ruby, as funções são chamadas de métodos. Cada Funções de membro na classe Ruby
método em uma classe começa com a palavra-chave def
seguida do nome do método.

O nome do método sempre preferiu em letras minúsculas . Você finaliza um método em


Ruby usando a palavra-chave end .

Aqui está o exemplo para definir um método Ruby -

class Sample
def function
statement 1
statement 2
end
end

Aqui, a instrução 1 e a instrução 2 fazem parte do corpo da função do método dentro da


classe Sample. Essas instruções podem ser qualquer declaração Ruby válida. Por exemplo,
podemos colocar um método coloca para imprimir Hello Ruby da seguinte forma -

class Sample
def hello
puts "Hello Ruby!"
end
end

Agora, no exemplo a seguir, crie um objeto da classe Sample e chame o método hello e veja
o resultado -

#!/usr/bin/ruby

class Sample
def hello
puts "Hello Ruby!"
end
end

# Now using above class to create objects


object = Sample. new
object.hello

Isso produzirá o seguinte resultado -

Hello Ruby!
Aqui está um estudo de caso se você quiser praticar mais com classes Estudo de caso simples
e objetos.

Estudo de caso da classe Ruby

Variáveis são os locais da memória, que contêm todos os dados a serem usados por
qualquer programa.

Existem cinco tipos de variáveis suportadas pelo Ruby. Você já passou por uma pequena
descrição dessas variáveis no capítulo anterior também. Esses cinco tipos de variáveis são
explicados neste capítulo.

Variáveis globais começam com $. Variáveis globais não inicializadasVariáveis Globais Ruby
têm o valor nulo e produzem avisos com a opção -w.

A atribuição a variáveis globais altera o status global. Não é recomendado usar variáveis
globais. Eles tornam os programas enigmáticos.

Aqui está um exemplo mostrando o uso da variável global.

#!/usr/bin/ruby

$global_variable = 10
class Class1
def print_global
puts "Global variable in Class1 is #$global_variable"
end
end
class Class2
def print_global
puts "Global variable in Class2 is #$global_variable"
end
end

class1obj = Class1.new
class1obj.print_global
class2obj = Class2.new
class2obj.print_global

Aqui $ global_variable é uma variável global. Isso produzirá o seguinte resultado -

OBSERVAÇÃO - Em Ruby, você PODE acessar o valor de qualquer variável ou constante


colocando um caractere de hash (#) logo antes dessa variável ou constante.

Global variable in Class1 is 10


Global variable in Class2 is 10

Variáveis de instância começam com @. Variáveis de instânciaVariáveis de instância do Ruby


não inicializadas têm o valor nil e produzem avisos com a opção
-w.

Aqui está um exemplo mostrando o uso de variáveis de instância.


#!/usr/bin/ruby

class Customer
def initialize(id, name, addr)
@cust_id = id
@cust_name = name
@cust_addr = addr
end
def display_details()
puts "Customer id #@cust_id"
puts "Customer name #@cust_name"
puts "Customer address #@cust_addr"
end
end

# Create Objects
cust1 = Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2 = Customer.new("2", "Poul", "New Empire road, Khandala")

# Call Methods
cust1.display_details()
cust2.display_details()

Aqui, @cust_id, @cust_name e @cust_addr são variáveis de instância. Isso produzirá o


seguinte resultado -

Customer id 1
Customer name John
Customer address Wisdom Apartments, Ludhiya
Customer id 2
Customer name Poul
Customer address New Empire road, Khandala

As variáveis de classe começam com @@ e devem ser inicializadasVariáveis de Classe Ruby


antes de poderem ser usadas nas definições dos métodos.

Fazer referência a uma variável de classe não inicializada produz um erro. As variáveis de
classe são compartilhadas entre os descendentes da classe ou módulo em que as variáveis
de classe são definidas.

Substituir variáveis de classe produz avisos com a opção -w.

Aqui está um exemplo mostrando o uso da variável de classe -

#!/usr/bin/ruby

class Customer
@@no_of_customers = 0
def initialize(id, name, addr)
@cust_id = id
@cust_name = name
@cust_addr = addr
end
def display_details()
puts "Customer id #@cust_id"
puts "Customer name #@cust_name"
puts "Customer address #@cust_addr"
end
def total_no_of_customers()
@@no_of_customers += 1
puts "Total number of customers: #@@no_of_customers"
end
end

# Create Objects
cust1 = Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2 = Customer.new("2", "Poul", "New Empire road, Khandala")

# Call Methods
cust1.total_no_of_customers()
cust2.total_no_of_customers()

Aqui @@ no_of_customers é uma variável de classe. Isso produzirá o seguinte resultado -

Total number of customers: 1


Total number of customers: 2

Variáveis locais começam com uma letra minúscula ou _. O escopo deVariáveis locais do Ruby
uma variável local varia de classe, módulo, def ou do para o final
correspondente ou da chave de abertura de um bloco para sua chave de fechamento {}.

Quando uma variável local não inicializada é referenciada, ela é interpretada como uma
chamada para um método que não possui argumentos.

A atribuição a variáveis locais não inicializadas também serve como declaração variável. As
variáveis começam a existir até o final do escopo atual ser atingido. O tempo de vida de
variáveis locais é determinado quando Ruby analisa o programa.

No exemplo acima, as variáveis locais são id, name e addr.

As constantes começam com uma letra maiúscula. Constantes definidasConstantes Ruby


dentro de uma classe ou módulo podem ser acessadas de dentro dessa
classe ou módulo, e aquelas definidas fora de uma classe ou módulo podem ser acessadas
globalmente.

Constantes não podem ser definidas dentro de métodos. Fazer referência a uma constante
não inicializada produz um erro. Fazer uma atribuição a uma constante já inicializada produz
um aviso.

#!/usr/bin/ruby

class Example
VAR1 = 100
VAR2 = 200
def show
puts "Value of first Constant is #{VAR1}"
puts "Value of second Constant is #{VAR2}"
end
end
# Create Objects
object = Example.new()
object.show

Aqui VAR1 e VAR2 são constantes. Isso produzirá o seguinte resultado -

Value of first Constant is 100


Value of second Constant is 200

Eles são variáveis especiais que têm a aparência de variáveis locais,Pseudo-Variáveis Ruby
mas se comportam como constantes. Você não pode atribuir nenhum
valor a essas variáveis.

self - O objeto receptor do método atual.

true - Valor representando verdadeiro.

false - Valor representando falso.

nil - Valor representando indefinido.

__FILE__ - O nome do arquivo de origem atual.

__LINE__ - O número da linha atual no arquivo de origem.

As regras que Ruby usa para literais são simples e intuitivas. Esta seçãoRuby Basic Literais
explica todos os literais básicos de Ruby.

Ruby suporta números inteiros. Um número inteiro pode variar de -2 30 a 2Números inteiros
30-1 ou -2 62 a 2 62-1 . Inteiros dentro deste intervalo são objetos da classe
Fixnum e inteiros fora desse intervalo são armazenados em objetos da classe Bignum .

Você escreve inteiros usando um sinal principal opcional, um indicador de base opcional (0
para octal, 0x para hexadecimal ou 0b para binário), seguido por uma cadeia de dígitos na
base apropriada. Caracteres de sublinhado são ignorados na seqüência de dígitos.

Você também pode obter o valor inteiro, correspondente a um caractere ASCII ou escapar
da sequência, precedendo-o com um ponto de interrogação.

123 # Fixnum decimal


1_234 # Fixnum decimal with underline
-500 # Negative Fixnum
0377 # octal
0xff # hexadecimal
0b1011 # binary
?a # character code for 'a'
?\n # code for a newline (0x0a)
12345678901234567890 # Bignum

OBSERVAÇÃO - Classe e Objetos são explicados em um capítulo separado deste tutorial.

Ruby suporta números flutuantes. Eles também são números, mas com decimais. Os
números de ponto flutuante são objetos da classe Float e podem ser Números Flutuantes
qualquer um dos seguintes -

123.4 # floating point value


1.0e6 # scientific notation
4E20 # dot not required
4e+20 # sign before exponential

Strings Ruby são simplesmente seqüências de bytes de 8 bits e são objetosLiterais de cordas
da classe String. As strings com aspas duplas permitem a notação de
substituição e contrabarra, mas as strings com aspas simples não permitem a substituição e
permitem a notação de contrabarra apenas para \\ e \ '

#!/usr/bin/ruby -w

puts 'escape using "\\"';


puts 'That\'s right';

Isso produzirá o seguinte resultado -

escape using "\"


That's right

Você pode substituir o valor de qualquer expressão Ruby em uma string usando a sequência
# {expr} . Aqui, expr poderia ser qualquer expressão rubi.

#!/usr/bin/ruby -w

puts "Multiplication Value : #{24*60*60}";

Isso produzirá o seguinte resultado -

Multiplication Value : 86400

A seguir está a lista de notações de barra invertida suportadas peloNotações de barra invertida
Ruby -

Notação Personagem representado

\n Newline (0x0a)

\r Retorno de carro (0x0d)

\f Formfeed (0x0c)

\b Backspace (0x08)

\uma Bell (0x07)


\e Escape (0x1b)

\s Espaço (0x20)

\ nnn Notação Octal (n sendo 0-7)

\ xnn Notação hexadecimal (n sendo 0-9, af ou AF)

\ cx, \ Cx Controle-x

\ Mx Meta-x (c | 0x80)

\ M- \ Cx Meta-Control-x

\x Personagem x

Para mais detalhes sobre Ruby Strings, passe por Ruby Strings .

Literais de Ruby Array são criados colocando-se uma série de referências deRuby Arrays
objetos separados por vírgula entre os colchetes. Uma vírgula final é ignorada.

#!/usr/bin/ruby

ary = [ "fred", 10, 3.14, "This is a string", "last element", ]


ary.each do |i|
puts i
end

Isso produzirá o seguinte resultado -

fred
10
3.14
This is a string
last element

Para mais detalhes sobre Ruby Arrays, vá até Ruby Arrays .

Um literal Ruby Hash é criado colocando uma lista de pares chave / valor entreHashes Ruby
chaves, com uma vírgula ou a sequência => entre a chave e o valor. Uma
vírgula final é ignorada.

#!/usr/bin/ruby

hsh = colors = { "red" => 0xf00, "green" => 0x0f0, "blue" => 0x00f }
hsh.each do |key, value|
print key, " is ", value, "\n"
end
Isso produzirá o seguinte resultado -

red is 3840
green is 240
blue is 15

Para mais detalhes sobre Ruby Hashes, passe por Ruby Hashes .

Um intervalo representa um intervalo que é um conjunto de valores com inícioRuby Ranges


e fim. Os intervalos podem ser construídos usando s..e e s ... e literais ou com
Range.new.

Ranges construídos usando .. correr desde o início até o fim, inclusive. Aqueles criados
usando ... excluem o valor final. Quando usado como um iterador, os intervalos retornam
cada valor na sequência.

Um intervalo (1..5) significa que ele inclui 1, 2, 3, 4, 5 valores e um intervalo (1 ... 5)


significa que ele inclui 1, 2, 3, 4 valores.

#!/usr/bin/ruby

(10..15).each do |n|
print n, ' '
end

Isso produzirá o seguinte resultado -

10 11 12 13 14 15

Para mais detalhes sobre Ruby Ranges, vá até Ruby Ranges .

Ruby suporta um rico conjunto de operadores, como você esperaria de uma linguagem
moderna. A maioria dos operadores são, na verdade, chamadas de método. Por exemplo, a
+ b é interpretada como a + (b), onde o método + no objeto referido pela variável a é
chamado com b como seu argumento.

Para cada operador (+ - * /% ** & | ^ << >> && ||), existe uma forma correspondente de
operador de atribuição abreviada (+ = - = etc.).

Suponha que a variável a detenha 10 e a variável b detenha 20,Operadores Aritméticos Rubi


então -

Operador Descrição Exemplo

+ Adição - Adiciona valores nos dois lados do operador. a + b dará 30

Subtração - Subtrai o operando da direita do operando da


- a - b dará -10
esquerda.
Multiplicação - Multiplica valores em ambos os lados do
* a * b dará 200
operador.

Divisão - Divide o operando esquerdo pelo operando


/ b / a vai dar 2
direito.

Módulo - Divide o operando esquerdo pelo operando direito


% b% a dará 0
e retorna o restante.

Expoente - Executa o cálculo exponencial (potência) nos a ** b dará 10 à


**
operadores. potência 20

Suponha que a variável a detenha 10 e a variável b detenhaOperadores de Comparação Ruby


20, então -

Operador Descrição Exemplo

Verifica se o valor de dois operandos é igual ou


== (a == b) não é verdade.
não, se sim, a condição se torna verdadeira.

Verifica se o valor de dois operandos é igual ou


!= não, se os valores não forem iguais, a condição (a! = b) é verdade.
se tornará verdadeira.

Verifica se o valor do operando esquerdo é maior


> que o valor do operando direito, se sim, a (a> b) não é verdade.
condição se torna verdadeira.

Verifica se o valor do operando esquerdo é


< menor que o valor do operando direito, se sim, a (a <b) é verdade.
condição se torna verdadeira.

Verifica se o valor do operando à esquerda é


>= maior ou igual ao valor do operando à direita, se (a> = b) não é verdade.
sim, a condição se torna verdadeira.

Verifica se o valor do operando à esquerda é


<= menor ou igual ao valor do operando à direita, (a <= b) é verdade.
se sim, a condição se torna verdadeira.

Operador de comparação combinada. Retorna 0


se primeiro operando for igual a segundo, 1 se
<=> (a <=> b) retorna -1.
primeiro operando for maior que o segundo e -1
se primeiro operando for menor que o segundo.

Usado para testar a igualdade dentro de uma (1 ... 10) === 5 retorna
===
cláusula when de uma instrução case . verdadeiro.

Verdadeiro se o receptor e o argumento tiverem 1 == 1.0 retorna verdadeiro,


.eql
o mesmo tipo e valores iguais. mas 1.eql (1.0) é falso.
Se aObj é duplicado de bObj,
então aObj == bObj é
Verdadeiro se o receptor e o argumento tiverem
igual? verdadeiro, a.equal? bObj é
o mesmo id de objeto.
falso, mas a.equal? aObj é
verdadeira.

Suponha que a variável a detenha 10 e a variável b detenhaOperadores de atribuição de ruby


20, então -

Operador Descrição Exemplo

Operador de atribuição simples, atribui valores de c = a + b irá atribuir o


=
operandos do lado direito ao operando do lado esquerdo. valor de a + b em c

Adicione o operador AND, adiciona o operando direito ao c + = a é equivalente


+= operando esquerdo e atribua o resultado ao operando ac=c+a
esquerdo.

Subtrair e operador de atribuição subtrai o operando c - = a é equivalente a


-= direito do operando esquerdo e atribui o resultado ao c=c-a
operando esquerdo.

Multiply AND assignment operator, multiplica o operando à c * = a é equivalente a


*= direita pelo operando à esquerda e atribui o resultado ao c=c*a
operando à esquerda.

Divide AND assignment operator, divide o operando c / = a é equivalente a


/= esquerdo com o operando da direita e atribui o resultado c=c/a
ao operando da esquerda.

Módulo E operador de atribuição, obtém o módulo usando c% = a é equivalente


%=
dois operandos e atribui o resultado ao operando esquerdo. a c = c% a

Operador de expoente E de atribuição, realiza cálculos c ** = a é equivalente


** = exponenciais (potência) nos operadores e atribui valor ao a c = c ** a
operando esquerdo.

Ruby também suporta a atribuição paralela de variáveis. Isso Atribuição Paralela ao Ruby
permite que várias variáveis sejam inicializadas com uma única
linha de código Ruby. Por exemplo -

a = 10
b = 20
c = 30

Isso pode ser mais rapidamente declarado usando a atribuição paralela -

a, b, c = 10, 20, 30

A atribuição paralela também é útil para trocar os valores mantidos em duas variáveis -
a, b = b, c

O operador bit a bit trabalha em bits e executa a operação bit a bit. Operadores Bitwise Ruby

Assuma se a = 60; eb = 13; agora em formato binário eles serão os seguintes -

a = 0011 1100
b = 0000 1101
------------------
a&b = 0000 1100
a|b = 0011 1101
a^b = 0011 0001
~a = 1100 0011

Os seguintes operadores Bitwise são suportados pela linguagem Ruby.

Operador Descrição Exemplo

Binary AND Operator copia um pouco para o


E (a & b) dará 12, que é 0000 1100
resultado, se existir em ambos os operandos.

Binário OU Operador copia um bit se existir em (a | b) vai dar 61, que é 0011
|
um dos operandos. 1101

Operador XOR binário copia o bit se estiver (a ^ b) dará 49, que é 0011 0001
^ definido em um operando, mas não em
ambos.

(~ a) dará -61, que é 1100 0011


Binary Ones Complement Operator é unário e no formulário de complemento de
~
tem o efeito de 'flipping' bits. 2 devido a um número binário
assinado.

Operador Shift Esquerdo. O valor dos


operandos esquerdos é movido para a um << 2 dará 240, que é 1111
<< <<
esquerda pelo número de bits especificado 0000
pelo operando direito.

Operador de deslocamento à direita binário. O


valor dos operandos esquerdos é movido para
>> a >> 2 dará 15, que é 0000 1111
a direita pelo número de bits especificado pelo
operando direito.

Os seguintes operadores lógicos são suportados pela linguagem Ruby Operadores Lógicos Ruby

Suponha que a variável a detenha 10 e a variável b detenha 20,


então -

Operador Descrição Exemplo


Chamado Lógico E operador. Se ambos os operandos forem (aeb) é
e
verdadeiros, a condição se tornará verdadeira. verdade.

Chamado Lógico OU Operador. Se algum dos dois operandos for (a ou b) é


ou
diferente de zero, a condição se tornará verdadeira. verdade.

Chamado Lógico E operador. Se ambos os operandos forem (a && b) é


&&
diferentes de zero, a condição se tornará verdadeira. verdade.

Chamado Lógico OU Operador. Se algum dos dois operandos for (a || b) é


||
diferente de zero, a condição se tornará verdadeira. verdadeiro.

Operador NÃO Lógico Chamado. Use para inverter o estado lógico ! (a && b) é
! do seu operando. Se uma condição for verdadeira, o operador falso.
Lógico NOT tornará falso.

Operador NÃO Lógico Chamado. Use para inverter o estado lógico não (a && b) é
não do seu operando. Se uma condição for verdadeira, o operador falso.
Lógico NOT tornará falso.

Há mais um operador chamado Ternary Operator. Em primeiro lugar,Operador Ternário Rubi


avalia uma expressão para um valor verdadeiro ou falso e, em seguida,
executa uma das duas instruções dadas, dependendo do resultado da avaliação. O operador
condicional tem essa sintaxe -

Operador Descrição Exemplo

Expressão Se a condição é verdadeira? Então, valor X: Caso contrário,


?:
Condicional valor Y

Os intervalos de sequência em Ruby são usados para criar umOperadores Ruby Range
intervalo de valores sucessivos - consistindo em um valor inicial, um
valor final e um intervalo de valores entre eles.

Em Ruby, essas seqüências são criadas usando os operadores de faixa "..." e "...". O
formulário de dois pontos cria um intervalo inclusivo, enquanto o formulário de três pontos
cria um intervalo que exclui o valor alto especificado.

Operador Descrição Exemplo

Cria um intervalo desde o ponto inicial até o 1..10 Cria um intervalo de 1 a


..
ponto final, inclusive. 10 inclusive.

Cria um intervalo desde o ponto inicial até o 1 ... 10 Cria um intervalo de 1 a


...
ponto final exclusivo. 9.

definiram? é um operador especial que assume a forma de umaOperadores Ruby definido?


chamada de método para determinar se a expressão passada está
definida ou não. Ele retorna uma string de descrição da expressão ou nil se a expressão não
estiver definida.

Existem vários usos de definidos? Operador

defined? variable # True if variable is initialized

Por exemplo

foo = 42
defined? foo # => "local-variable"
defined? $_ # => "global-variable"
defined? bar # => nil (undefined)

defined? method_call # True if a method is defined

Por exemplo

defined? puts # => "method"


defined? puts(bar) # => nil (bar is not defined here)
defined? unpack # => nil (not defined here)

# True if a method exists that can be called with super user


defined? super

Por exemplo

defined? super # => "super" (if it can be called)


defined? super # => nil (if it cannot be)

defined? yield # True if a code block has been passed

Por exemplo

defined? yield # => "yield" (if there is a block passed)


defined? yield # => nil (if there is no block)

Você chama um método de módulo precedendo seue dois-pontos "::" operadores Ruby Dot "."
nome com o nome do módulo e um ponto, e faz
referência a uma constante usando o nome do módulo e dois dois-pontos.

O :: é um operador unário que permite: constantes, métodos de instância e métodos de


classe definidos dentro de uma classe ou módulo, para serem acessados de qualquer lugar
fora da classe ou módulo.

Lembre-se de que Ruby, classes e métodos podem ser considerados constantes também.

Você precisa apenas prefixar o :: Const_name com uma expressão que retorne a classe ou
objeto de módulo apropriado.

Se nenhuma expressão de prefixo é usada, a classe de objeto principal é usada por padrão.

Aqui estão dois exemplos -

MR_COUNT = 0 # constant defined on main Object class


module Foo
MR_COUNT = 0
::MR_COUNT = 1 # set global count to 1
MR_COUNT = 2 # set local count to 2
end
puts MR_COUNT # this is the global constant
puts Foo::MR_COUNT # this is the local "Foo" constant

Segundo exemplo

CONST = ' out there'


class Inside_one
CONST = proc {' in there'}
def where_is_my_CONST
::CONST + ' inside one'
end
end
class Inside_two
CONST = ' inside two'
def where_is_my_CONST
CONST
end
end
puts Inside_one.new.where_is_my_CONST
puts Inside_two.new.where_is_my_CONST
puts Object::CONST + Inside_two::CONST
puts Inside_two::CONST + CONST
puts Inside_one::CONST
puts Inside_one::CONST.call + Inside_two::CONST

A tabela a seguir lista todos os operadores da maiorPrecedência de Operadores Ruby


precedência para a mais baixa.

Método Operador Descrição

sim :: Operador de resolução constante

sim [] [] = Referência de elemento, conjunto de elementos

sim ** Exponenciação (aumentar ao poder)

Não, complemento, unário mais e menos (os nomes


sim !~+-
dos métodos para os dois últimos são + @ e - @)
sim * /% Multiplique, divida e modulo

sim +- Adição e subtração

sim >> << Deslocamento bitwise direito e esquerdo

sim E Bitwise 'AND'

sim ^| Exclusivo de bits 'OR' e 'OR' regular

sim <= <>> = Operadores de comparação

Operadores de correspondência de igualdade e


sim <=> == ===! = = ~! ~ padrão (! = E! ~ Não podem ser definidos como
métodos)

&& Logical 'AND'

|| Logical 'OR'

.. ... Faixa (inclusiva e exclusiva)

?: Ternário se-então-mais

=% = {= = - = + = | = & =
>> = << = * = && = || = ** Tarefa
=

definiram? Verifique se o símbolo especificado foi definido

não Negação lógica

ou e Composição lógica

NOTA - Os operadores com um Sim na coluna do método são, na verdade, métodos e,


como tal, podem ser substituídos.

Comentários são linhas de anotação dentro do código Ruby que são ignoradas no tempo de
execução. Um comentário de linha única começa com # caractere e eles se estendem de #
até o final da linha da seguinte forma -

#!/usr/bin/ruby -w
# This is a single line comment.

puts "Hello, Ruby!"

Quando executado, o programa acima produz o seguinte resultado -

Hello, Ruby!
Você pode comentar várias linhas usando a sintaxe = begin e = Ruby Multiline Comentários
end da seguinte maneira -

#!/usr/bin/ruby -w

puts "Hello, Ruby!"

=begin
This is a multiline comment and con spwan as many lines as you
like. But =begin and =end should come in the first line only.
=end

Quando executado, o programa acima produz o seguinte resultado -

Hello, Ruby!

Certifique-se de que os comentários à direita estejam suficientemente longe do código e que


sejam facilmente distinguidos. Se houver mais de um comentário à direita em um bloco,
alinhe-os. Por exemplo -

@counter # keeps track times page has been hit


@siteCounter # keeps track of times all pages have been hit

O Ruby oferece estruturas condicionais que são bastante comuns em linguagens modernas.
Aqui, vamos explicar todas as instruções e modificadores condicionais disponíveis no Ruby.

Ruby if ... else Statement

if conditional [then]
code...
[elsif conditional [then]
code...]...
[else
code...]
end

se expressões são usadas para execução condicional. Os valores falso e nulo são falsos e
tudo o mais é verdadeiro. Observe que Ruby usa elsif, não mais se nem elif.

Executa o código se a condicional for verdadeira. Se a condicional não for verdadeira, o


código especificado na cláusula else será executado.

A condicional de uma expressão if é separada do código pela palavra reservada, em seguida


, uma nova linha ou um ponto e vírgula.

#!/usr/bin/ruby

x = 1
if x > 2
puts "x is greater than 2"
elsif x <= 2 and x!=0
puts "x is 1"
else
puts "I can't guess the number"
end

x is 1

Ruby se modificador

code if condition

Executa o código se a condicional for verdadeira.

#!/usr/bin/ruby

$debug = 1
print "debug\n" if $debug

Isso produzirá o seguinte resultado -

debug

Ruby, a menos que seja uma declaração

unless conditional [then]


code
[else
code ]
end

Executa o código se condicional for falso. Se a condicional for verdadeira, o código


especificado na cláusula else será executado.

#!/usr/bin/ruby

x = 1
unless x>=2
puts "x is less than 2"
else
puts "x is greater than 2"
end

Isso produzirá o seguinte resultado -

x is less than 2

Ruby, a menos que modificador


code unless conditional

Executa o código se condicional for falso.

#!/usr/bin/ruby

$var = 1
print "1 -- Value is set\n" if $var
print "2 -- Value is set\n" unless $var

$var = false
print "3 -- Value is set\n" unless $var

Isso produzirá o seguinte resultado -

1 -- Value is set
3 -- Value is set

Declaração de caso do Ruby

case expression
[when expression [, expression ...] [then]
code ]...
[else
code ]
end

Compara a expressão especificada por maiúsculas e minúsculas especificada por quando


usar o operador === e executa o código da cláusula when correspondente.

A expressão especificada pela cláusula when é avaliada como o operando da esquerda. Se


nenhuma cláusula when for correspondente, o caso executará o código da cláusula else .

Quando a expressão de uma instrução é separada do código pela palavra reservada, uma
nova linha ou um ponto-e-vírgula. Assim -

case expr0
when expr1, expr2
stmt1
when expr3, expr4
stmt2
else
stmt3
end

é basicamente semelhante ao seguinte -

_tmp = expr0
if expr1 === _tmp || expr2 === _tmp
stmt1
elsif expr3 === _tmp || expr4 === _tmp
stmt2
else
stmt3
end

#!/usr/bin/ruby

$age = 5
case $age
when 0 .. 2
puts "baby"
when 3 .. 6
puts "little child"
when 7 .. 12
puts "child"
when 13 .. 18
puts "youth"
else
puts "adult"
end

Isso produzirá o seguinte resultado -

little child

Os loops em Ruby são usados para executar o mesmo bloco de código em um determinado
número de vezes. Este capítulo detalha todas as instruções de loop suportadas pelo Ruby.

Ruby enquanto Statement

while conditional [do]


code
end

Executa o código enquanto a condicional é verdadeira. A condicional de um loop while é


separada do código pela palavra reservada do, uma nova linha, uma barra invertida \ ou um
ponto-e-vírgula;

#!/usr/bin/ruby

$i = 0
$num = 5

while $i < $num do


puts("Inside the loop i = #$i" )
$i +=1
end

Isso produzirá o seguinte resultado -


Inside the loop i = 0
Inside the loop i = 1
Inside the loop i = 2
Inside the loop i = 3
Inside the loop i = 4

Ruby enquanto modificador

code while condition

OR

begin
code
end while conditional

Executa o código enquanto a condicional é verdadeira.

Se um modificador while segue uma instrução begin sem cláusulas rescue ou ensure, o
código é executado uma vez antes da condição ser avaliada.

#!/usr/bin/ruby

$i = 0
$num = 5
begin
puts("Inside the loop i = #$i" )
$i +=1
end while $i < $num

Isso produzirá o seguinte resultado -

Inside the loop i = 0


Inside the loop i = 1
Inside the loop i = 2
Inside the loop i = 3
Inside the loop i = 4

Ruby até a declaração

until conditional [do]


code
end

Executa o código enquanto condicional é falso. A condicional de uma instrução until é


separada do código pela palavra reservada do , uma nova linha ou um ponto e vírgula.

#!/usr/bin/ruby
$i = 0
$num = 5

until $i > $num do


puts("Inside the loop i = #$i" )
$i +=1;
end

Isso produzirá o seguinte resultado -

Inside the loop i = 0


Inside the loop i = 1
Inside the loop i = 2
Inside the loop i = 3
Inside the loop i = 4
Inside the loop i = 5

Ruby até modificador

code until conditional

OR

begin
code
end until conditional

Executa o código enquanto condicional é falso.

Se um modificador until seguir uma instrução begin sem cláusulas rescue ou ensure, o
código será executado uma vez antes da condição ser avaliada.

#!/usr/bin/ruby

$i = 0
$num = 5
begin
puts("Inside the loop i = #$i" )
$i +=1;
end until $i > $num

Isso produzirá o seguinte resultado -

Inside the loop i = 0


Inside the loop i = 1
Inside the loop i = 2
Inside the loop i = 3
Inside the loop i = 4
Inside the loop i = 5
Ruby for Statement

for variable [, variable ...] in expression [do]


code
end

Executa o código uma vez para cada elemento na expressão .

#!/usr/bin/ruby

for i in 0..5
puts "Value of local variable is #{i}"
end

Aqui, definimos o intervalo 0..5. A declaração para i em 0..5 permitirá que eu tome valores
no intervalo de 0 a 5 (incluindo 5). Isso produzirá o seguinte resultado -

Value of local variable is 0


Value of local variable is 1
Value of local variable is 2
Value of local variable is 3
Value of local variable is 4
Value of local variable is 5

Um loop for ... é quase exatamente equivalente ao seguinte -

(expression).each do |variable[, variable...]| code end

exceto que um loop for não cria um novo escopo para variáveis locais. A expressão do loop
for é separada do código pela palavra reservada do, uma nova linha ou um ponto e vírgula.

#!/usr/bin/ruby

(0..5).each do |i|
puts "Value of local variable is #{i}"
end

Isso produzirá o seguinte resultado -

Value of local variable is 0


Value of local variable is 1
Value of local variable is 2
Value of local variable is 3
Value of local variable is 4
Value of local variable is 5

Declaração de quebra de Ruby


break

Termina o loop mais interno. Encerra um método com um bloco associado, se chamado
dentro do bloco (com o método retornando nil).

#!/usr/bin/ruby

for i in 0..5
if i > 2 then
break
end
puts "Value of local variable is #{i}"
end

Isso produzirá o seguinte resultado -

Value of local variable is 0


Value of local variable is 1
Value of local variable is 2

Ruby next Statement

next

Salta para a próxima iteração do loop mais interno. Encerra a execução de um bloco se
chamado dentro de um bloco (com rendimento ou retorno de chamada nulo).

#!/usr/bin/ruby

for i in 0..5
if i < 2 then
next
end
puts "Value of local variable is #{i}"
end

Isso produzirá o seguinte resultado -

Value of local variable is 2


Value of local variable is 3
Value of local variable is 4
Value of local variable is 5

Declaração Ruby Redo

redo

Reinicia essa iteração do loop mais interno, sem verificar a condição de loop. Reinicia o
rendimento ou chama se chamado dentro de um bloco.
#!/usr/bin/ruby

for i in 0..5
if i < 2 then
puts "Value of local variable is #{i}"
redo
end
end

Isso produzirá o seguinte resultado e entrará em um loop infinito -

Value of local variable is 0


Value of local variable is 0
............................

Declaração de repetição do Ruby

retry

Se a nova tentativa aparecer na cláusula rescue da expressão begin, reinicie a partir do


início do corpo inicial.

begin
do_something # exception raised
rescue
# handles error
retry # restart from beginning
end

Se a nova tentativa aparecer no iterador, o bloco ou o corpo da expressão for reinicia a


chamada da chamada do iterador. Argumentos para o iterador são reavaliados.

for i in 1..5
retry if some_condition # restart from i == 1
end

#!/usr/bin/ruby
for i in 0..5
retry if i > 2
puts "Value of local variable is #{i}"
end

Isso produzirá o seguinte resultado e entrará em um loop infinito -

Value of local variable is 1


Value of local variable is 2
Value of local variable is 1
Value of local variable is 2
Value of local variable is 1
Value of local variable is 2
............................

Os métodos Ruby são muito semelhantes às funções em qualquer outra linguagem de


programação. Os métodos Ruby são usados para agrupar uma ou mais instruções repetidas
em uma única unidade.

Os nomes dos métodos devem começar com uma letra minúscula. Se você começar um
nome de método com uma letra maiúscula, Ruby pode pensar que é uma constante e,
portanto, pode analisar a chamada incorretamente.

Os métodos devem ser definidos antes de chamá-los, caso contrário, o Ruby levantará uma
exceção para a invocação do método indefinido.

Sintaxe

def method_name [( [arg [= default]]...[, * arg [, &expr ]])]


expr..
end

Então, você pode definir um método simples como segue -

def method_name
expr..
end

Você pode representar um método que aceita parâmetros como este -

def method_name (var1, var2)


expr..
end

Você pode definir valores padrão para os parâmetros, que serão usados se o método for
chamado sem passar pelos parâmetros necessários -

def method_name (var1 = value1, var2 = value2)


expr..
end

Sempre que você chama o método simples, escreve apenas o nome do método da seguinte
forma:

method_name

No entanto, quando você chama um método com parâmetros, escreve o nome do método
junto com os parâmetros, como -

method_name 25, 30

A desvantagem mais importante de usar métodos com parâmetros é que você precisa
lembrar o número de parâmetros sempre que chamar tais métodos. Por exemplo, se um
método aceita três parâmetros e você passa apenas dois, o Ruby exibe um erro.

#!/usr/bin/ruby

def test(a1 = "Ruby", a2 = "Perl")


puts "The programming language is #{a1}"
puts "The programming language is #{a2}"
end
test "C", "C++"
test

Isso produzirá o seguinte resultado -

The programming language is C


The programming language is C++
The programming language is Ruby
The programming language is Perl

Todo método em Ruby retorna um valor por padrão. Este valorRetornar valores de métodos
retornado será o valor da última declaração. Por exemplo -

def test
i = 100
j = 10
k = 0
end

Este método, quando chamado, retornará a última variável declarada k .

A declaração de retorno em ruby é usada para retornar um ouDeclaração de retorno do Ruby


mais valores de um método Ruby.

return [expr[`,' expr...]]

Se mais de duas expressões forem fornecidas, a matriz contendo esses valores será o valor
de retorno. Se nenhuma expressão for dada, nil será o valor de retorno.

return

OR

return 12

OR

return 1,2,3

Dê uma olhada neste exemplo -


#!/usr/bin/ruby

def test
i = 100
j = 200
k = 300
return i, j, k
end
var = test
puts var

Isso produzirá o seguinte resultado -

100
200
300

Suponha que você declare um método que usa dois parâmetros,Número Variável de Parâmetros
sempre que você chamar esse método, precisará passar dois
parâmetros junto com ele.

No entanto, Ruby permite declarar métodos que funcionam com um número variável de
parâmetros. Vamos examinar uma amostra disso -

#!/usr/bin/ruby

def sample (*test)


puts "The number of parameters is #{test.length}"
for i in 0...test.length
puts "The parameters are #{test[i]}"
end
end
sample "Zara", "6", "F"
sample "Mac", "36", "M", "MCA"

Nesse código, você declarou uma amostra de método que aceita um teste de parâmetro. No
entanto, esse parâmetro é um parâmetro variável. Isso significa que esse parâmetro pode
receber qualquer número de variáveis. Então, o código acima irá produzir o seguinte
resultado -

The number of parameters is 3


The parameters are Zara
The parameters are 6
The parameters are F
The number of parameters is 4
The parameters are Mac
The parameters are 36
The parameters are M
The parameters are MCA

Quando um método é definido fora da definição de classe, o método éMétodos de aula


marcado como privado por padrão. Por outro lado, os métodos definidos na
definição de classe são marcados como públicos por padrão. A visibilidade padrão e a marca
privada dos métodos podem ser alteradas por público ou privado do Módulo.

Sempre que você quiser acessar um método de uma classe, primeiro você precisa instanciar
a classe. Então, usando o objeto, você pode acessar qualquer membro da classe.

Ruby dá a você uma maneira de acessar um método sem instanciar uma classe. Vamos ver
como um método de classe é declarado e acessado -

class Accounts
def reading_charge
end
def Accounts.return_date
end
end

Veja como o método return_date é declarado. É declarado com o nome da classe seguido
por um período, que é seguido pelo nome do método. Você pode acessar este método de
classe diretamente da seguinte maneira -

Accounts.return_date

Para acessar este método, você não precisa criar objetos da classe Accounts.

Isto dá alias a métodos ou variáveis globais. Os aliases não podemDeclaração de alias do Ruby
ser definidos no corpo do método. O alias do método mantém a
definição atual do método, mesmo quando os métodos são substituídos.

Fazer aliases para as variáveis globais numeradas ($ 1, $ 2, ...) é proibido. Substituir as


variáveis globais internas pode causar sérios problemas.

alias method-name method-name


alias global-variable-name global-variable-name

alias foo bar


alias $MATCH $&

Aqui definimos alias foo para bar, e $ MATCH é um apelido para $ &

Isso cancela a definição do método. Um undef não pode aparecer noRuby undef Statement
corpo do método.

Ao usar undef e alias , a interface da classe pode ser modificada independentemente da


superclasse, mas observe que ela pode ser quebrada por meio do método interno call to
self.
undef method-name

Para indefinir um método chamado bar faça o seguinte -

undef bar

Você viu como o Ruby define os métodos em que você pode colocar o número de instruções
e, em seguida, chama esse método. Da mesma forma, Ruby tem um conceito de Block.

Um bloco consiste em pedaços de código.

Você atribui um nome a um bloco.

O código no bloco é sempre colocado entre chaves ({}).

Um bloco é sempre chamado de uma função com o mesmo nome do bloco. Isso
significa que, se você tiver um bloco com o nome test , use o teste de função para
chamar este bloco.

Você chama um bloco usando a instrução yield .

Sintaxe

block_name {
statement1
statement2
..........
}

Aqui, você aprenderá a invocar um bloco usando uma declaração de rendimento simples.
Você também aprenderá a usar uma instrução yield com parâmetros para invocar um bloco.
Você verificará o código de amostra com os dois tipos de declarações de rendimento .

Vamos ver um exemplo da declaração de rendimento - A declaração de rendimento

#!/usr/bin/ruby

def test
puts "You are in the method"
yield
puts "You are again back to the method"
yield
end
test {puts "You are in the block"}

Isso produzirá o seguinte resultado -

You are in the method


You are in the block
You are again back to the method
You are in the block

Você também pode passar parâmetros com a declaração de rendimento. Aqui está um
exemplo -

#!/usr/bin/ruby

def test
yield 5
puts "You are in the method test"
yield 100
end
test {|i| puts "You are in the block #{i}"}

Isso produzirá o seguinte resultado -

You are in the block 5


You are in the method test
You are in the block 100

Aqui, a declaração de rendimento é escrita seguida por parâmetros.Você pode até passar
mais de um parâmetro. No bloco, você coloca uma variável entre duas linhas verticais (||)
para aceitar os parâmetros. Portanto, no código anterior, a instrução yield 5 passa o valor 5
como um parâmetro para o bloco de teste.

Agora, olhe a seguinte declaração -

test {|i| puts "You are in the block #{i}"}

Aqui, o valor 5 é recebido na variável i . Agora, observe a seguinte declaração de puts -

puts "You are in the block #{i}"

A saída desta declaração de puts é -

You are in the block 5

Se você quiser passar mais de um parâmetro, a declaração de rendimento se torna -

yield a, b

e o bloco é -

test {|a, b| statement}

Os parâmetros serão separados por vírgulas.

Você viu como um bloco e um método podem ser associados uns aos outros. Você
normalmente chama um bloco usando a instrução yield de um método que possui o mesmo
nome do bloco. Portanto, você escreve -

#!/usr/bin/ruby

def test
yield
end
test{ puts "Hello world"}

Este exemplo é a maneira mais simples de implementar um bloco. Você chama o bloco de
teste usando a instrução yield .

Mas se o último argumento de um método é precedido por &, então você pode passar um
bloco para este método e este bloco será atribuído ao último parâmetro. No caso de ambos
* e & estarem presentes na lista de argumentos, & devem vir depois.

#!/usr/bin/ruby

def test(&block)
block.call
end
test { puts "Hello World!"}

Isso produzirá o seguinte resultado -

Hello World!

Todo arquivo fonte do Ruby pode declarar blocos de código a serem executados enquanto o
arquivo está sendo carregado (os blocos BEGIN) e após o término da execução do programa
(os blocos END).

#!/usr/bin/ruby

BEGIN {
# BEGIN block code
puts "BEGIN code block"
}

END {
# END block code
puts "END code block"
}
# MAIN block code
puts "MAIN code block"

Um programa pode incluir vários blocos BEGIN e END. Os blocos BEGIN são executados na
ordem em que são encontrados. Os blocos END são executados na ordem inversa. Quando
executado, o programa acima produz o seguinte resultado -

BEGIN code block


MAIN code block
END code block

Módulos são uma maneira de agrupar métodos, classes e constantes. Os módulos oferecem
dois grandes benefícios.

Os módulos fornecem um namespace e evitam confrontos de nomes.

Módulos implementam o mixin facility.

Os módulos definem um namespace, uma caixa de proteção na qual seus métodos e


constantes podem ser reproduzidos sem ter que se preocupar em ser pisado por outros
métodos e constantes.

Sintaxe

module Identifier
statement1
statement2
...........
end

As constantes de módulo são nomeadas como constantes de classe, com uma letra
maiúscula inicial. As definições do método também são semelhantes: Os métodos do
módulo são definidos exatamente como os métodos de classe.

Como nos métodos de classe, você chama um método de módulo precedendo seu nome
com o nome do módulo e um ponto, e faz referência a uma constante usando o nome do
módulo e dois dois-pontos.

#!/usr/bin/ruby

# Module defined in trig.rb file

module Trig
PI = 3.141592654
def Trig.sin(x)
# ..
end
def Trig.cos(x)
# ..
end
end

Podemos definir mais um módulo com o mesmo nome de função, mas funcionalidade
diferente

#!/usr/bin/ruby

# Module defined in moral.rb file


module Moral
VERY_BAD = 0
BAD = 1
def Moral.sin(badness)
# ...
end
end

Como os métodos de classe, sempre que você define um método em um módulo, você
especifica o nome do módulo seguido por um ponto e, em seguida, o nome do método.

A instrução require é semelhante à instrução include de C e C ++ e a declaração de


importação de Java. Se um terceiro programa quiser usar qualquer módulo definido, ele
pode simplesmente carregar os arquivos do módulo usando a instrução require do Ruby -

require filename

Aqui, não é necessário fornecer extensão .rb junto com um nome de arquivo.

$LOAD_PATH << '.'

require 'trig.rb'
require 'moral'

y = Trig.sin(Trig::PI/4)
wrongdoing = Moral.sin(Moral::VERY_BAD)

Aqui estamos usando $ LOAD_PATH << '.' Para tornar Ruby ciente de que os arquivos
incluídos devem ser procurados no diretório atual. Se você não quiser usar $ LOAD_PATH,
então você pode usar require_relative para incluir arquivos de um diretório relativo.

IMPORTANTE - Aqui, os dois arquivos contêm o mesmo nome de função. Portanto, isso
resultará em ambigüidade de código, ao incluir no programa de chamada, mas os módulos
evitam a ambigüidade do código e podemos chamar a função apropriada usando o nome do
módulo.

Você pode incorporar um módulo em uma classe. Para incorporar um módulo em uma
classe, você usa a instrução include na classe -

include modulename

Se um módulo é definido em um arquivo separado, é necessário incluir esse arquivo usando


require statement antes de inserir o módulo em uma classe.
Considere o seguinte módulo escrito no arquivo support.rb .

module Week
FIRST_DAY = "Sunday"
def Week.weeks_in_month
puts "You have four weeks in a month"
end
def Week.weeks_in_year
puts "You have 52 weeks in a year"
end
end

Agora, você pode incluir este módulo em uma classe da seguinte maneira -

#!/usr/bin/ruby
$LOAD_PATH << '.'
require "support"

class Decade
include Week
no_of_yrs = 10
def no_of_months
puts Week::FIRST_DAY
number = 10*12
puts number
end
end
d1 = Decade.new
puts Week::FIRST_DAY
Week.weeks_in_month
Week.weeks_in_year
d1.no_of_months

Isso produzirá o seguinte resultado -

Sunday
You have four weeks in a month
You have 52 weeks in a year
Sunday
120

Antes de passar por esta seção, assumimos que você tem o conhecimento de Conceitos
orientados a objetos.

Quando uma classe pode herdar recursos de mais de uma classe pai, a classe deve mostrar
herança múltipla.

Ruby não suporta múltiplas heranças diretamente, mas o Ruby Modules tem outro uso
maravilhoso. De uma só vez, eles praticamente eliminam a necessidade de herança
múltipla, fornecendo uma facilidade chamada mixin .
Os Mixins oferecem uma maneira maravilhosamente controlada de adicionar funcionalidade
às classes. No entanto, o verdadeiro poder deles é exibido quando o código no mixin
começa a interagir com o código na classe que o utiliza.

Vamos examinar o seguinte exemplo de código para entender o mixin -

module A
def a1
end
def a2
end
end
module B
def b1
end
def b2
end
end

class Sample
include A
include B
def s1
end
end

samp = Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1

O módulo A consiste nos métodos a1 e a2. O módulo B consiste nos métodos b1 e b2. A
classe Sample inclui os módulos A e B. A classe Sample pode acessar todos os quatro
métodos, a saber, a1, a2, b1 e b2. Portanto, você pode ver que a classe Sample herda de
ambos os módulos. Assim, você pode dizer que a classe Sample mostra herança múltipla ou
um mixin .

Um objeto String em Ruby mantém e manipula uma seqüência arbitrária de um ou mais


bytes, geralmente representando caracteres que representam a linguagem humana.

Os literais de string mais simples são colocados entre aspas simples (o caractere de
apóstrofo). O texto dentro das marcas de aspas é o valor da string -

'This is a simple Ruby string literal'

Se você precisar colocar um apóstrofo dentro de um literal de cadeia de aspas simples,


preceda-o com uma barra invertida, para que o interpretador Ruby não pense que ele
encerra a cadeia de caracteres -

'Won\'t you read O\'Reilly\'s book?'


A barra invertida também funciona para escapar de outra barra invertida, para que a
segunda barra invertida não seja interpretada como um caractere de escape.

A seguir estão os recursos relacionados a cadeias de caracteres do Ruby.

A substituição de expressão é um meio de incorporar o valor de qualquer expressão Ruby


em uma string usando # {e} -

#!/usr/bin/ruby

x, y, z = 12, 36, 72
puts "The value of x is #{ x }."
puts "The sum of x and y is #{ x + y }."
puts "The average was #{ (x + y + z)/3 }."

Isso produzirá o seguinte resultado -

The value of x is 12.


The sum of x and y is 48.
The average was 40.

Com strings delimitadas em geral, você pode criar strings dentro de um par de caracteres
delimitadores arbitrários, por exemplo,!, (, {, <, Etc., precedidos por um caractere
percentual (%). Q, qex têm significados especiais Cadeias delimitadas por geral podem ser -

%{Ruby is fun.} equivalent to "Ruby is fun."


%Q{ Ruby is fun. } equivalent to " Ruby is fun. "
%q[Ruby is fun.] equivalent to a single-quoted string
%x!ls! equivalent to back tick command output `ls`

A tabela a seguir é uma lista de caracteres de escape ou não imprimíveis que podem
ser representados com a notação de barra invertida.

O conjunto de caracteres padrão para Ruby é ASCII, cujos caracteres podem ser
representados por bytes únicos. Se você usar o UTF-8 ou outro conjunto de caracteres
moderno, os caracteres poderão ser representados em um a quatro bytes.

Você pode alterar o seu conjunto de caracteres usando $ KCODE no início do seu programa,
como este -
$KCODE = 'u'

A seguir estão os valores possíveis para $ KCODE.

Precisamos ter uma instância do objeto String para chamar um método String. A seguir está
a maneira de criar uma instância do objeto String -

new [String.new(str = "")]

Isso retornará um novo objeto de string contendo uma cópia de str . Agora, usando o objeto
str , todos nós podemos usar qualquer método de instância disponível. Por exemplo -

#!/usr/bin/ruby

myStr = String.new("THIS IS TEST")


foo = myStr.downcase

puts "#{foo}"

Isso produzirá o seguinte resultado -

this is test

A seguir estão os métodos public String (Supondo que str seja um objeto String) -

A tabela a seguir lista as diretivas de descompactação do método String # unpack.

Tente o exemplo a seguir para descompactar vários dados.

"abc \0\0abc \0\0".unpack('A6Z6') #=> ["abc", "abc "]


"abc \0\0".unpack('a3a3') #=> ["abc", " \000\000"]
"abc \0abc \0".unpack('Z*Z*') #=> ["abc ", "abc "]
"aa".unpack('b8B8') #=> ["10000110", "01100001"]
"aaa".unpack('h2H2c') #=> ["16", "61", 97]
"\xfe\xff\xfe\xff".unpack('sS') #=> [-2, 65534]
"now = 20is".unpack('M*') #=> ["now is"]
"whole".unpack('xax2aX2aX1aX2a') #=> ["h", "e", "l", "l", "o"]

Matrizes Ruby são ordenadas, coleções indexadas por inteiro de qualquer objeto. Cada
elemento em uma matriz é associado e referenciado por um índice.

A indexação de matriz começa em 0, como em C ou Java. Um índice negativo é assumido


em relação ao final da matriz - ou seja, um índice de -1 indica o último elemento da matriz,
-2 é o próximo ao último elemento na matriz e assim por diante.

Os arrays Ruby podem conter objetos como String, Integer, Fixnum, Hash, Symbol e até
mesmo outros objetos Array. Os arrays Ruby não são tão rígidos quanto os arrays em outros
idiomas. Os arrays Ruby crescem automaticamente ao adicionar elementos a eles.

Há muitas maneiras de criar ou inicializar uma matriz. Uma maneira é com o novo método
de classe -

names = Array.new

Você pode definir o tamanho de uma matriz no momento da criação da matriz

names = Array.new(20)

Os nomes das matrizes agora têm um tamanho ou comprimento de 20 elementos. Você


pode retornar o tamanho de um array com os métodos de tamanho ou tamanho -

#! / usr / bin / ruby

names = Array . novo ( 20 )


coloca nomes . size # Isso retorna 20
nomes de puts . comprimento # Isso também retorna 20

Isso produzirá o seguinte resultado -

20
20

Você pode atribuir um valor a cada elemento da matriz da seguinte maneira -

#!/usr/bin/ruby

names = Array.new(4, "mac")


puts "#{names}"

Isso produzirá o seguinte resultado -

["mac", "mac", "mac", "mac"]

Você também pode usar um bloco com novo, preenchendo cada elemento com o que o bloco
avalia para -

#!/usr/bin/ruby

nums = Array.new(10) { |e| e = e * 2 }


puts "#{nums}"

Isso produzirá o seguinte resultado -


[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

Existe outro método de Array, []. Funciona assim -

nums = Array.[](1, 2, 3, 4,5)

Mais uma forma de criação de matriz é a seguinte -

nums = Array[1, 2, 3, 4,5]

O módulo Kernel disponível no núcleo Ruby possui um método Array, que aceita apenas um
único argumento. Aqui, o método usa um intervalo como argumento para criar uma matriz
de dígitos -

#!/usr/bin/ruby

digits = Array(0..9)
puts "#{digits}"

Isso produzirá o seguinte resultado -

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Precisamos ter uma instância do objeto Array para chamar um método Array. Como vimos,
seguir é o caminho para criar uma instância do objeto Array -

Array.[](...) [or] Array[...] [or] [...]

Isso retornará uma nova matriz preenchida com os objetos fornecidos. Agora, usando o
objeto criado, podemos chamar qualquer método de instância disponível. Por exemplo -

#!/usr/bin/ruby

digits = Array(0..9)
num = digits.at(6)
puts "#{num}"

Isso produzirá o seguinte resultado -

A seguir estão os métodos de matriz pública (supondo que matriz seja um objeto de
matriz) -

A tabela a seguir lista as diretivas de pacote para uso com o Array # pack.
Tente o exemplo a seguir para compactar vários dados.

a = [ "a", "b", "c" ]


n = [ 65, 66, 67 ]
puts a.pack("A3A3A3") #=> "a b c "
puts a.pack("a3a3a3") #=> "a\000\000b\000\000c\000\000"
puts n.pack("ccc") #=> "ABC"

Isso produzirá o seguinte resultado -

a b c
abc
ABC

Um hash é uma coleção de pares de valores-chave como este: "empregado" => "salário". É
semelhante a um Array, exceto que a indexação é feita através de chaves arbitrárias de
qualquer tipo de objeto, não um índice inteiro.

A ordem em que você percorre um hash por chave ou valor pode parecer arbitrária e
geralmente não estará na ordem de inserção. Se você tentar acessar um hash com uma
chave que não existe, o método retornará nulo .

Assim como nos arrays, há várias maneiras de criar hashes. Você pode criar um hash vazio
com o novo método de classe -

months = Hash.new

Você também pode usar o novo para criar um hash com um valor padrão, que é de outra
forma apenas nulo -

months = Hash.new( "month" )

or

months = Hash.new "month"

Quando você acessa qualquer chave em um hash que possui um valor padrão, se a chave
ou o valor não existir, o acesso ao hash retornará o valor padrão -

#!/usr/bin/ruby

months = Hash.new( "month" )

puts "#{months[0]}"
puts "#{months[72]}"
Isso produzirá o seguinte resultado -

month
month

#!/usr/bin/ruby

H = Hash["a" => 100, "b" => 200]

puts "#{H['a']}"
puts "#{H['b']}"

Isso produzirá o seguinte resultado -

100
200

Você pode usar qualquer objeto Ruby como chave ou valor, até mesmo um array, então o
exemplo a seguir é válido -

[1,"jan"] => "January"

Precisamos ter uma instância do objeto Hash para chamar um método Hash. Como vimos,
seguir é o caminho para criar uma instância do objeto Hash -

Hash[[key =>|, value]* ] or

Hash.new [or] Hash.new(obj) [or]


Hash.new { |hash, key| block }

Isso retornará um novo hash preenchido com os objetos fornecidos. Agora, usando o objeto
criado, podemos chamar qualquer método de instância disponível. Por exemplo -

#!/usr/bin/ruby

$, = ", "
months = Hash.new( "month" )
months = {"1" => "January", "2" => "February"}

keys = months.keys
puts "#{keys}"

Isso produzirá o seguinte resultado -

["1", "2"]

A seguir estão os métodos de hash públicos (supondo que hash é um objeto de matriz) -

Sr. Métodos e Descrição


Não.
hash == other_hash

Testa se dois hashes são iguais, com base em se eles têm o mesmo número de
1
pares de valores-chave e se os pares de valores-chave correspondem ao par
correspondente em cada hash.

chave de hash]

2 Usando uma chave, faz referência a um valor do hash. Se a chave não for
encontrada, retorna um valor padrão.

hash. [chave] = valor


3
Associa o valor dado por valor com a chave dada pela chave .

hash.clear
4
Remove todos os pares de valores-chave do hash.

hash.default (key = nil)

5 Retorna o valor padrão para hash , nil se não for definido por padrão =. ([] retorna
um valor padrão se a chave não existir no hash .)

hash.default = obj
6
Define um valor padrão para hash .

hash.default_proc
7
Retorna um bloco se o hash foi criado por um bloco.

hash.delete (chave) [ou]

array.delete (key) {| chave | quadra }


8
Exclui um par de valores-chave de hash por chave . Se o bloco é usado, retorna o
resultado de um bloco se o par não for encontrado. Compare delete_if .

hash.delete_if {| chave, valor | quadra }

9 Exclui um par de valores-chave do hash para cada par que o bloco avalia como
verdadeiro .

hash.each {| chave, valor | quadra }


10
Itera sobre hash , chamando o bloco uma vez para cada chave, passando o valor-
chave como uma matriz de dois elementos.

hash.each_key {| chave | quadra }

11 Itera sobre hash , chamando o bloco uma vez para cada chave, passando a chave
como um parâmetro.

hash.each_key {| key_value_array | quadra }

12 Itera sobre hash , chamando o bloco uma vez para cada chave , passando a chave
e valor como parâmetros.

hash.each_key {| value | quadra }

13 Itera sobre hash , chamando o bloco uma vez para cada chave , passando o valor
como parâmetro.

hash.empty?

14 Testa se o hash está vazio (não contém pares de valores-chave), retornando true
ou false .

hash.fetch (chave [, padrão]) [ou]

hash.fetch (key) {| chave | quadra }

15
Retorna um valor de hash para a chave dada . Se a chave não puder ser
encontrada e não houver outros argumentos, ela gerará uma exceção IndexError ;
se o padrão é dado, ele é retornado; se o bloco opcional for especificado, seu
resultado será retornado.

hash.has_key? (key) [ou] hash.include? (chave) [ou]

16 hash.key? (chave) [ou] hash.member? (chave)

Testa se uma determinada chave está presente no hash, retornando true ou false .

hash.has_value? (valor)
17
Testa se o hash contém o valor fornecido .

hash.index (valor)

18 Retorna a chave para o valor fornecido em hash, nil se nenhum valor


correspondente for encontrado.
hash.indexes (chaves)

Retorna um novo array que consiste em valores para a (s) chave (s) dada (s). Irá
19
inserir o valor padrão para chaves que não são encontradas. Este método está
obsoleto. Use select.

hash.indices (chaves)

Retorna um novo array que consiste em valores para a (s) chave (s) dada (s). Irá
20
inserir o valor padrão para chaves que não são encontradas. Este método está
obsoleto. Use select.

hash.inspect
21
Retorna uma versão bonita de string de impressão de hash.

hash.invert

22 Cria um novo hash , invertendo chaves e valores do hash ; ou seja, no novo hash,
as chaves do hash se tornam valores e valores tornam-se chaves.

hash.keys
23
Cria um novo array com chaves do hash .

hash.length
24
Retorna o tamanho ou o comprimento do hash como um inteiro.

hash.merge (other_hash) [ou]

hash.merge (other_hash) {| chave, oldval, newval | quadra }


25 Retorna um novo hash contendo o conteúdo de hash e other_hash ,
sobrescrevendo pares em hash com chaves duplicadas com aqueles de other_hash
.

hash.merge! (other_hash) [ou]

26 hash.merge! (other_hash) {| chave, oldval, newval | quadra }

O mesmo que mesclar, mas as alterações são feitas no lugar.

hash.rehash

27 Reconstrói o hash com base nos valores atuais de cada chave . Se os valores foram
alterados desde que foram inseridos, esse método reindexará o hash .
hash.reject {| chave, valor | quadra }
28
Cria um novo hash para cada par que o bloco avalia como verdadeiro

hash.reject! {| chave, valor | quadra }


29
O mesmo que rejeitar , mas as mudanças são feitas no lugar.

hash.replace (other_hash)
30
Substitui o conteúdo do hash pelo conteúdo de other_hash .

hash.select {| chave, valor | quadra }

31 Retorna um novo array que consiste em pares de valor-chave do hash para o qual
o bloco retorna true .

hash.shift

32 Remove um par de valores-chave do hash , retornando-o como uma matriz de dois


elementos.

hash.size
33
Retorna o tamanho ou o comprimento do hash como um inteiro.

hash.sort

34 Converte o hash em um array bidimensional contendo matrizes de pares de


valores-chave e classifica-os como um array.

hash.store (chave, valor)


35
Armazena um par de valores-chave em hash .

hash.to_a

36 Cria um array bidimensional a partir do hash. Cada par chave / valor é convertido
em um array, e todos esses arrays são armazenados em um array contendo.

hash.to_hash
37
Retorna o hash (self).

hash.to_s
38
Converte o hash em uma matriz e, em seguida, converte essa matriz em uma
string.

hash.update (other_hash) [ou]

hash.update (other_hash) {| chave, oldval, newval | quadra}


39 Retorna um novo hash contendo o conteúdo de hash e other_hash ,
sobrescrevendo pares em hash com chaves duplicadas com aqueles de other_hash
.

hash.value? (valor)
40
Testa se o hash contém o valor fornecido .

valores de hash
41
Retorna uma nova matriz contendo todos os valores de hash .

hash.values_at (obj, ...)

42 Retorna uma nova matriz contendo os valores do hash associados à determinada


chave ou chaves.

A classe Time representa datas e horas em Ruby. É uma camada fina sobre a
funcionalidade de data e hora do sistema fornecida pelo sistema operacional. Esta classe
pode não conseguir em seu sistema representar datas antes de 1970 ou depois de 2038.

Este capítulo familiariza você com todos os conceitos de data e hora mais desejados.

A seguir, o exemplo simples para obter data e hora atuais - Obtendo a data e hora atuais

#!/usr/bin/ruby -w

time1 = Time.new
puts "Current Time : " + time1.inspect

# Time.now is a synonym:
time2 = Time.now
puts "Current Time : " + time2.inspect

Isso produzirá o seguinte resultado -

Current Time : Mon Jun 02 12:02:39 -0700 2008


Current Time : Mon Jun 02 12:02:39 -0700 2008
Podemos usar o objeto Time para obter vários componentes de data e hora. A seguir está o
exemplo mostrando o mesmo -

#!/usr/bin/ruby -w

time = Time.new

# Components of a Time
puts "Current Time : " + time.inspect
puts time.year # => Year of the date
puts time.month # => Month of the date (1 to 12)
puts time.day # => Day of the date (1 to 31 )
puts time.wday # => 0: Day of week: 0 is Sunday
puts time.yday # => 365: Day of year
puts time.hour # => 23: 24-hour clock
puts time.min # => 59
puts time.sec # => 59
puts time.usec # => 999999: microseconds
puts time.zone # => "UTC": timezone name

Isso produzirá o seguinte resultado -

Current Time : Mon Jun 02 12:03:08 -0700 2008


2008
6
2
1
154
12
3
8
247476
UTC

Essas duas funções podem ser usadas para formatar a data em um formato padrão da
seguinte maneira -

# July 8, 2008
Time.local(2008, 7, 8)
# July 8, 2008, 09:10am, local time
Time.local(2008, 7, 8, 9, 10)
# July 8, 2008, 09:10 UTC
Time.utc(2008, 7, 8, 9, 10)
# July 8, 2008, 09:10:11 GMT (same as UTC)
Time.gm(2008, 7, 8, 9, 10, 11)

A seguir, o exemplo para obter todos os componentes em uma matriz no seguinte formato -

[sec,min,hour,day,month,year,wday,yday,isdst,zone]

Tente o seguinte -
#!/usr/bin/ruby -w

time = Time.new
values = time.to_a
p values

Isso gerará o seguinte resultado -

[26, 10, 12, 2, 6, 2008, 1, 154, false, "MST"]

Essa matriz pode ser passada para as funções Time.utc ou Time.local para obter diferentes
formatos de datas da seguinte maneira:

#!/usr/bin/ruby -w

time = Time.new
values = time.to_a
puts Time.utc(*values)

Isso gerará o seguinte resultado -

Mon Jun 02 12:15:36 UTC 2008

A seguir, a maneira de obter o tempo representado internamente como segundos desde a


época (dependente da plataforma) -

# Returns number of seconds since epoch


time = Time.now.to_i

# Convert number of seconds into Time object.


Time.at(time)

# Returns second since epoch which includes microseconds


time = Time.now.to_f

Você pode usar um objeto Time para obter todas as informações relacionadas a fusos
horários e horário de verão da seguinte maneira:

time = Time.new

# Here is the interpretation


time.zone # => "UTC": return the timezone
time.utc_offset # => 0: UTC is 0 seconds offset from UTC
time.zone # => "PST" (or whatever your timezone is)
time.isdst # => false: If UTC does not have DST.
time.utc? # => true: if t is in UTC time zone
time.localtime # Convert to local timezone.
time.gmtime # Convert back to UTC.
time.getlocal # Return a new Time object in local zone
time.getutc # Return a new Time object in UTC
Existem várias maneiras de formatar a data e a hora. Aqui está um exemplo mostrando
alguns -

#!/usr/bin/ruby -w

time = Time.new
puts time.to_s
puts time.ctime
puts time.localtime
puts time.strftime("%Y-%m-%d %H:%M:%S")

Isso produzirá o seguinte resultado -

Mon Jun 02 12:35:19 -0700 2008


Mon Jun 2 12:35:19 2008
Mon Jun 02 12:35:19 -0700 2008
2008-06-02 12:35:19

Essas diretivas na tabela a seguir são usadas com o método Time.strftime .

Sr. Diretiva e Descrição


Não.

%uma
1
O nome abreviado do dia da semana (Sun).

%UMA
2
O nome completo do dia da semana (domingo).

%b
3
O nome abreviado do mês (Jan).

%B
4
O nome completo do mês (janeiro).

%c
5
A representação de data e hora local preferida.

%d
6
Dia do mês (01 a 31).
%H
7
Hora do dia, relógio de 24 horas (00 a 23).

%EU
8
Hora do dia, relógio de 12 horas (01 a 12).

%j
9
Dia do ano (001 a 366).

%m
10
Mês do ano (01 a 12).

%M
11
Minuto da hora (00 a 59).

%p
12
Indicador Meridiano (AM ou PM).

%S
13
Segundo do minuto (00 a 60).

%VOCÊ

14 Número da semana do ano atual, começando com o primeiro domingo como o


primeiro dia da primeira semana (00 a 53).

%W

15 Número da semana do ano atual, começando com a primeira segunda-feira como


o primeiro dia da primeira semana (00 a 53).

%W
16
Dia da semana (domingo é 0, 0 a 6).

%x
17
Representação preferida apenas para a data, sem tempo.
%X
18
Representação preferida apenas pelo tempo, sem data.

%y
19
Ano sem um século (00 a 99).

%Y
20
Ano com o século.

%Z
21
Nome do fuso horário.

%%
22
Caractere Literal%.

Você pode executar aritmética simples com o tempo da seguinte forma -

now = Time.now # Current time


puts now

past = now - 10 # 10 seconds ago. Time - number => Time


puts past

future = now + 10 # 10 seconds from now Time + number => Time


puts future

diff = future - past # => 10 Time - Time => number of seconds


puts diff

Isso produzirá o seguinte resultado -

Thu Aug 01 20:57:05 -0700 2013


Thu Aug 01 20:56:55 -0700 2013
Thu Aug 01 20:57:15 -0700 2013
20.0

Os intervalos ocorrem em todos os lugares: de janeiro a dezembro, de 0 a 9, linhas de 50 a


67 e assim por diante. Ruby suporta intervalos e nos permite usar intervalos de várias
maneiras -
Intervalos como seqüências

Intervalos como condições

Intervalos como intervalos

O primeiro e talvez o uso mais natural de intervalos é expressar uma sequência. Seqüências
têm um ponto inicial, um ponto final e uma maneira de produzir valores sucessivos na
seqüência.

Ruby cria essas seqüências usando os operadores de faixa '' .. '' e '' ... '' . O formulário de
dois pontos cria um intervalo inclusivo, enquanto o formulário de três pontos cria um
intervalo que exclui o valor alto especificado.

(1..5) #==> 1, 2, 3, 4, 5
(1...5) #==> 1, 2, 3, 4
('a'..'d') #==> 'a', 'b', 'c', 'd'

A sequência 1..100 é mantida como um objeto Range contendo referências a dois objetos
Fixnum . Se precisar, você pode converter um intervalo em uma lista usando o método to_a
. Experimente o seguinte exemplo -

#!/usr/bin/ruby

$, =", " # Array value separator


range1 = (1..10).to_a
range2 = ('bar'..'bat').to_a

puts "#{range1}"
puts "#{range2}"

Isso produzirá o seguinte resultado -

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
["bar", "bas", "bat"]

Os intervalos implementam métodos que permitem iterar sobre eles e testar seu conteúdo
de várias maneiras -

#!/usr/bin/ruby

# Assume a range
digits = 0..9

puts digits.include?(5)
ret = digits.min
puts "Min value is #{ret}"

ret = digits.max
puts "Max value is #{ret}"

ret = digits.reject {|i| i < 5 }


puts "Rejected values are #{ret}"

digits.each do |digit|
puts "In Loop #{digit}"
end

Isso produzirá o seguinte resultado -

true
Min value is 0
Max value is 9
Rejected values are 5, 6, 7, 8, 9
In Loop 0
In Loop 1
In Loop 2
In Loop 3
In Loop 4
In Loop 5
In Loop 6
In Loop 7
In Loop 8
In Loop 9

Os intervalos também podem ser usados como expressões condicionais. Por exemplo, o
fragmento de código a seguir imprime conjuntos de linhas da entrada padrão, em que a
primeira linha de cada conjunto contém a palavra início e a última linha em que a palavra
termina -

while gets
print if /start/../end/
end

Os intervalos podem ser usados em declarações de caso -

#!/usr/bin/ruby

score = 70

result = case score


when 0..40 then "Fail"
when 41..60 then "Pass"
when 61..70 then "Pass with Merit"
when 71..100 then "Pass with Distinction"
else "Invalid Score"
end

puts result

Isso produzirá o seguinte resultado -


Pass with Merit

Um uso final do intervalo versátil é como um teste de intervalo: ver se algum valor está
dentro do intervalo representado pelo intervalo. Isso é feito usando ===, o operador de
igualdade de casos.

#!/usr/bin/ruby

if ((1..10) === 5)
puts "5 lies in (1..10)"
end

if (('a'..'j') === 'c')


puts "c lies in ('a'..'j')"
end

if (('a'..'j') === 'z')


puts "z lies in ('a'..'j')"
end

Isso produzirá o seguinte resultado -

5 lies in (1..10)
c lies in ('a'..'j')

Iteradores não são nada além de métodos suportados por coleções . Objetos que
armazenam um grupo de membros de dados são chamados de coleções. Em Ruby, matrizes
e hashes podem ser chamados de coleções.

Iteradores retornam todos os elementos de uma coleção, um após o outro. Vamos discutir
dois iteradores aqui, cada um e coletar . Vamos ver isso em detalhes.

O iterador each retorna todos os elementos de uma matriz ou um hash.

collection.each do |variable|
code
end

Executa o código para cada elemento na coleção . Aqui, a coleção pode ser uma matriz ou
um hash rubi.

#!/usr/bin/ruby
ary = [1,2,3,4,5]
ary.each do |i|
puts i
end

Isso produzirá o seguinte resultado -

1
2
3
4
5

Você sempre associa cada iterador a um bloco. Ele retorna cada valor da matriz, um por
um, ao bloco. O valor é armazenado na variável i e, em seguida, exibido na tela.

O iterador de coleta retorna todos os elementos de uma coleção.

collection = collection.collect

O método de coleta nem sempre precisa estar associado a um bloco. O método collect
retorna toda a coleção, independentemente de ser uma matriz ou um hash.

#!/usr/bin/ruby

a = [1,2,3,4,5]
b = Array.new
b = a.collect
puts b

Isso produzirá o seguinte resultado -

1
2
3
4
5

NOTA - O método de coleta não é o caminho certo para fazer cópias entre arrays. Existe
outro método chamado clone , que deve ser usado para copiar um array em outro array.

Você normalmente usa o método collect quando deseja fazer algo com cada um dos valores
para obter o novo array. Por exemplo, esse código produz um array b contendo 10 vezes
cada valor em a .

#!/usr/bin/ruby
a = [1,2,3,4,5]
b = a.collect{|x| 10*x}
puts b

Isso produzirá o seguinte resultado -

10
20
30
40
50

Ruby fornece um conjunto completo de métodos relacionados a E / S implementados no


módulo Kernel. Todos os métodos de E / S são derivados da classe IO.

A classe IO fornece todos os métodos básicos, como read, write, gets, puts, readline, getc e
printf .

Este capítulo cobrirá todas as funções básicas de E / S disponíveis no Ruby. Para mais
funções, por favor consulte Ruby Class IO .

Nos capítulos anteriores, você atribuiu valores a variáveis e depois imprimiu a saída usando
a instrução puts .

A instrução puts instrui o programa a exibir o valor armazenado na variável. Isto irá
adicionar uma nova linha no final de cada linha que escreve.

#!/usr/bin/ruby

val1 = "This is variable one"


val2 = "This is variable two"
puts val1
puts val2

Isso produzirá o seguinte resultado -

This is variable one


This is variable two

A instrução gets pode ser usada para obter qualquer entrada do usuário da tela padrão
chamada STDIN.
O código a seguir mostra como usar a instrução gets. Esse código solicitará que o usuário
insira um valor, que será armazenado em um val variável e, finalmente, será impresso no
STDOUT.

#!/usr/bin/ruby

puts "Enter a value :"


val = gets
puts val

Isso produzirá o seguinte resultado -

Enter a value :
This is entered value
This is entered value

Ao contrário da instrução puts , que gera a string inteira na tela, a instrução putc pode ser
usada para gerar um caractere por vez.

A saída do código a seguir é apenas o caractere H -

#!/usr/bin/ruby

str = "Hello Ruby!"


putc str

Isso produzirá o seguinte resultado -

A instrução print é semelhante à instrução puts . A única diferença é que a instrução puts
vai para a próxima linha depois de imprimir o conteúdo, enquanto que com a instrução print
o cursor está posicionado na mesma linha.

#!/usr/bin/ruby

print "Hello World"


print "Good Morning"

Isso produzirá o seguinte resultado -

Hello WorldGood Morning


Até agora, você estava lendo e escrevendo para a entrada e saída padrão. Agora, vamos ver
como jogar com arquivos de dados reais.

Você pode criar um objeto File usando o método File.new para leitura, gravação ou ambos,
de acordo com a string de modo. Finalmente, você pode usar o método File.close para
fechar esse arquivo.

aFile = File.new("filename", "mode")


# ... process the file
aFile.close

Você pode usar o método File.open para criar um novo objeto de arquivo e atribuir esse
objeto de arquivo a um arquivo. No entanto, há uma diferença entre File.Open e File.New
métodos. A diferença é que o método File.open pode ser associado a um bloco, enquanto
você não pode fazer o mesmo usando o método File.new .

File.open("filename", "mode") do |aFile|


# ... process the file
end

Aqui está uma lista dos diferentes modos de abrir um arquivo -

Os mesmos métodos que utilizamos para E / S 'simples' estão disponíveis para todos os
objetos de arquivo. Portanto, o gets lê uma linha da entrada padrão e aFile.gets lê uma
linha do objeto de arquivo aFile.

No entanto, os objetos de E / S fornecem um conjunto adicional de métodos de acesso para


facilitar nossas vidas.

Você pode usar o método sysread para ler o conteúdo de um arquivo. Você pode abrir o
arquivo em qualquer um dos modos ao usar o método sysread. Por exemplo -

A seguir, o arquivo de texto de entrada -

This is a simple text file for testing purpose.

Agora vamos tentar ler este arquivo -

#!/usr/bin/ruby
aFile = File.new("input.txt", "r")
if aFile
content = aFile.sysread(20)
puts content
else
puts "Unable to open file!"
end

Esta declaração irá mostrar os primeiros 20 caracteres do arquivo. O ponteiro do arquivo


agora será colocado no 21º caractere no arquivo.

Você pode usar o método syswrite para gravar o conteúdo em um arquivo. Você precisa
abrir o arquivo no modo de gravação ao usar o método syswrite. Por exemplo -

#!/usr/bin/ruby

aFile = File.new("input.txt", "r+")


if aFile
aFile.syswrite("ABCDEF")
else
puts "Unable to open file!"
end

Esta declaração irá escrever "ABCDEF" no arquivo.

Este método pertence à classe File . O método each_byte está sempre associado a um
bloco. Considere o seguinte exemplo de código -

#!/usr/bin/ruby

aFile = File.new("input.txt", "r+")


if aFile
aFile.syswrite("ABCDEF")
aFile.each_byte {|ch| putc ch; putc ?. }
else
puts "Unable to open file!"
end

Os caracteres são passados um a um para a variável ch e, em seguida, exibidos na tela da


seguinte maneira -

s. .a. .s.i.m.p.l.e. .t.e.x.t. .f.i.l.e. .f.o.r. .t.e.s.t.i.n.g. .p.u.r.p.o.s.e...


.
.

A classe File é uma subclasse da classe IO. A classe IO também possui alguns métodos, que
podem ser usados para manipular arquivos.
Um dos métodos de classe IO é IO.readlines . Este método retorna o conteúdo do arquivo
linha por linha. O código a seguir exibe o uso do método IO.readlines -

#!/usr/bin/ruby

arr = IO.readlines("input.txt")
puts arr[0]
puts arr[1]

Neste código, a variável arr é um array. Cada linha do arquivo input.txt será um elemento
na matriz arr. Portanto, arr [0] conterá a primeira linha, enquanto arr [1] conterá a segunda
linha do arquivo.

Este método também retorna saída linha por linha. A diferença entre o método foreach e o
método readlines é que o método foreach está associado a um bloco. No entanto, ao
contrário das linhas de leitura do método , o método foreach não retorna uma matriz. Por
exemplo -

#!/usr/bin/ruby

IO.foreach("input.txt"){|block| puts block}

Este código passará o conteúdo do teste de arquivo linha a linha para o bloco de variáveis e,
em seguida, a saída será exibida na tela.

Você pode renomear e excluir arquivos programaticamente com Ruby com os métodos
rename e delete .

A seguir, o exemplo para renomear um arquivo existente test1.txt -

#!/usr/bin/ruby

# Rename a file from test1.txt to test2.txt


File.rename( "test1.txt", "test2.txt" )

A seguir está o exemplo para excluir um arquivo existente test2.txt -

#!/usr/bin/ruby

# Delete file test2.txt


File.delete("test2.txt")

Use o método chmod com uma máscara para alterar o modo ou permissões / lista de acesso
de um arquivo -
A seguir está o exemplo para alterar o modo de um arquivo test.txt existente para um valor
de máscara -

#!/usr/bin/ruby

file = File.new( "test.txt", "w" )


file.chmod( 0755 )

A seguir está a tabela, que pode ajudá-lo a escolher uma máscara diferente para o
método chmod -

O comando a seguir testa se um arquivo existe antes de abri-lo -

#!/usr/bin/ruby

File.open("file.rb") if File::exists?( "file.rb" )

O seguinte comando pergunta se o arquivo é realmente um arquivo -

#!/usr/bin/ruby

# This returns either true or false


File.file?( "text.txt" )

O seguinte comando descobre se o nome do arquivo fornecido é um diretório -

#!/usr/bin/ruby

# a directory
File::directory?( "/usr/local/bin" ) # => true

# a file
File::directory?( "file.rb" ) # => false

O seguinte comando descobre se o arquivo é legível, gravável ou executável -

#!/usr/bin/ruby

File.readable?( "test.txt" ) # => true


File.writable?( "test.txt" ) # => true
File.executable?( "test.txt" ) # => false

O seguinte comando descobre se o arquivo tem tamanho zero ou não -

#!/usr/bin/ruby

File.zero?( "test.txt" ) # => true

O seguinte comando retorna o tamanho do arquivo -

#!/usr/bin/ruby
File.size?( "text.txt" ) # => 1002

O seguinte comando pode ser usado para descobrir um tipo de arquivo -

#!/usr/bin/ruby

File::ftype( "test.txt" ) # => file

O método ftype identifica o tipo do arquivo retornando um dos seguintes - arquivo,


diretório, caractereEspecial, blocoEspecial, fifo, link, soquete ou desconhecido.

O seguinte comando pode ser usado para descobrir quando um arquivo foi criado,
modificado ou acessado pela última vez -

#!/usr/bin/ruby

File::ctime( "test.txt" ) # => Fri May 09 10:06:37 -0700 2008


File::mtime( "text.txt" ) # => Fri May 09 10:44:44 -0700 2008
File::atime( "text.txt" ) # => Fri May 09 10:45:01 -0700 2008

Todos os arquivos estão contidos em vários diretórios, e o Ruby não tem nenhum problema
em lidar com isso também. Enquanto a classe File manipula arquivos, os diretórios são
manipulados com a classe Dir .

Para alterar o diretório dentro de um programa Ruby, use Dir.chdir da seguinte maneira.
Este exemplo altera o diretório atual para / usr / bin .

Dir.chdir("/usr/bin")

Você pode descobrir qual é o diretório atual com Dir.pwd -

puts Dir.pwd # This will return something like /usr/bin

Você pode obter uma lista dos arquivos e diretórios dentro de um diretório específico usando
Dir.entries -

puts Dir.entries("/usr/bin").join(' ')

Dir.entries retorna uma matriz com todas as entradas no diretório especificado. Dir.foreach
fornece o mesmo recurso -

Dir.foreach("/usr/bin") do |entry|
puts entry
end

Uma forma ainda mais concisa de obter listagens de diretórios é usando o método array da
classe Dir -
Dir["/usr/bin/*"]

O Dir.mkdir pode ser usado para criar diretórios -

Dir.mkdir("mynewdir")

Você também pode definir permissões em um novo diretório (não um que já exista) com
mkdir -

NOTA - A máscara 755 define permissões owner, group, world [qualquer um] para rwxr-
xr-x onde r = read, w = write e x = execute.

Dir.mkdir( "mynewdir", 755 )

O Dir.delete pode ser usado para excluir um diretório. O Dir.unlink e o Dir.rmdir executam
exatamente a mesma função e são fornecidos por conveniência.

Dir.delete("testdir")

Arquivos temporários são aqueles que podem ser criados brevemente durante a execução
de um programa, mas não são um armazenamento permanente de informações.

Dir.tmpdir fornece o caminho para o diretório temporário no sistema atual, embora o


método não esteja disponível por padrão. Para tornar o Dir.tmpdir disponível, é necessário
usar require 'tmpdir'.

Você pode usar Dir.tmpdir com File.join para criar um arquivo temporário independente de
plataforma -

require 'tmpdir'
tempfilename = File.join(Dir.tmpdir, "tingtong")
tempfile = File.new(tempfilename, "w")
tempfile.puts "This is a temporary file"
tempfile.close
File.delete(tempfilename)

Esse código cria um arquivo temporário, grava dados nele e o exclui. A biblioteca padrão do
Ruby também inclui uma biblioteca chamada Tempfile que pode criar arquivos temporários
para você -

require 'tempfile'
f = Tempfile.new('tingtong')
f.puts "Hello"
puts f.path
f.close

Aqui estão as funções embutidas do ruby para processar arquivos eFunções incorporadas
diretórios -

Classe de arquivo e métodos .

Classe Dir e Métodos .

A execução e a exceção sempre andam juntas. Se você está abrindo um arquivo, o que não
existe, então se você não lidou com esta situação corretamente, então seu programa é
considerado de má qualidade.

O programa pára se ocorrer uma exceção. Portanto, as exceções são usadas para lidar com
vários tipos de erros, que podem ocorrer durante a execução de um programa e tomar a
ação apropriada, em vez de interromper completamente o programa.

Ruby fornece um bom mecanismo para lidar com exceções. Colocamos o código que poderia
levantar uma exceção em um bloco begin / end e usar cláusulas de resgate para dizer ao
Ruby os tipos de exceções que queremos manipular.

Sintaxe

begin
# -
rescue OneTypeOfException
# -
rescue AnotherTypeOfException
# -
else
# Other exceptions
ensure
# Always will be executed
end

Tudo desde o início até o resgate é protegido. Se ocorrer uma exceção durante a execução
deste bloco de código, o controle é passado para o bloco entre resgate e fim .

Para cada cláusula de salvamento no bloco inicial, Ruby compara a exceção levantada com
cada um dos parâmetros. A correspondência será bem-sucedida se a exceção nomeada na
cláusula rescue for a mesma do tipo da exceção lançada atualmente ou se for uma
superclasse dessa exceção.

Em um evento em que uma exceção não corresponde a nenhum dos tipos de erro
especificados, temos permissão para usar uma cláusula else após todas as cláusulas de
resgate .
#!/usr/bin/ruby

begin
file = open("/unexistant_file")
if file
puts "File opened successfully"
end
rescue
file = STDIN
end
print file, "==", STDIN, "\n"

Isso produzirá o seguinte resultado. Você pode ver que STDIN é substituído pelo arquivo
porque a abertura falhou.

#<IO:0xb7d16f84>==#<IO:0xb7d16f84>

Você pode capturar uma exceção usando o bloco deUsando a declaração de repetição
recuperação e, em seguida, usar a instrução de repetição para
executar o bloco de início desde o início.

begin
# Exceptions raised by this code will
# be caught by the following rescue clause
rescue
# This block will capture all types of exceptions
retry # This will move control to the beginning of begin
end

#!/usr/bin/ruby

begin
file = open("/unexistant_file")
if file
puts "File opened successfully"
end
rescue
fname = "existant_file"
retry
end

O seguinte é o fluxo do processo -

Uma exceção ocorreu em aberto.

Fui resgatar. fname foi reatribuído.

Por tentativa foi para o começo do começo.


Este arquivo de tempo é aberto com sucesso.

Continuou o processo essencial.

OBSERVAÇÃO - Observe que, se o arquivo de nome re-substituído não existir, este código
de exemplo será repetido infinitamente. Tenha cuidado se você usar novamente para um
processo de exceção.

Você pode usar a instrução raise para lançar uma exceção. O Usando declaração de aumento
método a seguir gera uma exceção sempre que é chamado. Sua
segunda mensagem será impressa.

raise

OR

raise "Error Message"

OR

raise ExceptionType, "Error Message"

OR

raise ExceptionType, "Error Message" condition

O primeiro formulário simplesmente ressalta a exceção atual (ou um RuntimeError se não


houver uma exceção atual). Isso é usado em manipuladores de exceção que precisam
interceptar uma exceção antes de transmiti-la.

O segundo formulário cria uma nova exceção RuntimeError , configurando sua mensagem
para a cadeia especificada. Esta exceção é então levantada a pilha de chamadas.

A terceira forma usa o primeiro argumento para criar uma exceção e, em seguida, define a
mensagem associada ao segundo argumento.

A quarta forma é semelhante à terceira forma, mas você pode adicionar qualquer instrução
condicional como , a menos, para gerar uma exceção.

#!/usr/bin/ruby

begin
puts 'I am before the raise.'
raise 'An error has occurred.'
puts 'I am after the raise.'
rescue
puts 'I am rescued.'
end
puts 'I am after the begin block.'

Isso produzirá o seguinte resultado -

I am before the raise.


I am rescued.
I am after the begin block.

Mais um exemplo mostrando o uso de aumento -

#!/usr/bin/ruby

begin
raise 'A test exception.'
rescue Exception => e
puts e.message
puts e.backtrace.inspect
end

Isso produzirá o seguinte resultado -

A test exception.
["main.rb:4"]

Às vezes, você precisa garantir que algum processamento sejaUsando a declaração de garantia
feito no final de um bloco de código, independentemente de
uma exceção ter sido gerada. Por exemplo, você pode ter um arquivo aberto na entrada do
bloco e você precisa ter certeza de que ele será fechado quando o bloco sair.

A cláusula de garantia faz exatamente isso. assegura que vai após a última cláusula rescue
e contém um pedaço de código que sempre será executado quando o bloco terminar. Não
importa se o bloco sai normalmente, se ele dispara e resgata uma exceção, ou se ele é
terminado por uma exceção não identificada, o bloco de garantia será executado.

begin
#.. process
#..raise exception
rescue
#.. handle error
ensure
#.. finally ensure execution
#.. This will always execute.
end

begin
raise 'A test exception.'
rescue Exception => e
puts e.message
puts e.backtrace.inspect
ensure
puts "Ensuring execution"
end

Isso produzirá o seguinte resultado -

A test exception.
["main.rb:4"]
Ensuring execution

Se a cláusula else está presente, ela vai após as cláusulas de resgate Usando outra declaração
e antes de qualquer garantia .

O corpo de uma cláusula else é executado apenas se nenhuma exceção for levantada pelo
corpo principal do código.

begin
#.. process
#..raise exception
rescue
# .. handle error
else
#.. executes if there is no exception
ensure
#.. finally ensure execution
#.. This will always execute.
end

begin
# raise 'A test exception.'
puts "I'm not raising exception"
rescue Exception => e
puts e.message
puts e.backtrace.inspect
else
puts "Congratulations-- no errors!"
ensure
puts "Ensuring execution"
end

Isso produzirá o seguinte resultado -

I'm not raising exception


Congratulations-- no errors!
Ensuring execution
Mensagem de erro levantada pode ser capturada usando $! variável.

Embora o mecanismo de exceção de raise e resgate seja ótimo para abandonarPegar e jogar
a execução quando as coisas dão errado, às vezes é bom poder saltar de
alguma construção profundamente aninhada durante o processamento normal. É aqui que o
catch e o throw são úteis.

A captura define um bloco rotulado com o nome fornecido (que pode ser um símbolo ou
uma string). O bloco é executado normalmente até que um lance seja encontrado.

throw :lablename
#.. this will not be executed
catch :lablename do
#.. matching catch will be executed after a throw is encountered.
end

OR

throw :lablename condition


#.. this will not be executed
catch :lablename do
#.. matching catch will be executed after a throw is encountered.
end

O exemplo a seguir usa um lance para encerrar a interação com o usuário se '!' é digitado
em resposta a qualquer solicitação.

def promptAndGet(prompt)
print prompt
res = readline.chomp
throw :quitRequested if res == "!"
return res
end

catch :quitRequested do
name = promptAndGet("Name: ")
age = promptAndGet("Age: ")
sex = promptAndGet("Sex: ")
# ..
# process information
end
promptAndGet("Name:")

Você deve experimentar o programa acima na sua máquina porque ele precisa de interação
manual. Isso produzirá o seguinte resultado -

Name: Ruby on Rails


Age: 3
Sex: !
Name:Just Ruby

As classes e módulos padrão do Ruby geram exceções. Todas as classes deExceção de Classe
exceção formam uma hierarquia, com a exceção de classe no topo. O
próximo nível contém sete tipos diferentes -

Interromper

NoMemoryError

SignalException

Erro de script

Erro padrão

SystemExit

Existe uma outra exceção neste nível, Fatal , mas o interpretador Ruby só usa isso
internamente.

Tanto ScriptError quanto StandardError possuem várias subclasses, mas não precisamos
entrar nos detalhes aqui. O importante é que, se criarmos nossas próprias classes de
exceção, elas precisam ser subclasses de qualquer exceção de classe ou um de seus
descendentes.

Vamos olhar um exemplo -

class FileSaveError < StandardError


attr_reader :reason
def initialize(reason)
@reason = reason
end
end

Agora, veja o exemplo a seguir, que usará essa exceção -

File.open(path, "w") do |file|


begin
# Write out the data ...
rescue
# Something went wrong!
raise FileSaveError.new($!)
end
end

A linha importante aqui é raise FileSaveError.new ($!) . Chamamos raise para sinalizar que
ocorreu uma exceção, passando-lhe uma nova instância de FileSaveError, com o motivo de
essa exceção específica ter causado a falha na gravação dos dados.
Ruby é uma linguagem pura orientada a objetos e tudo parece para Ruby como um objeto.
Todo valor em Ruby é um objeto, até mesmo os mais primitivos: strings, números e até true
e false. Até mesmo uma classe em si é um objeto que é uma instância da classe Class . Este
capítulo irá levá-lo através de todas as principais funcionalidades relacionadas ao Ruby
Orientado a Objetos.

Uma classe é usada para especificar a forma de um objeto e combina representação de


dados e métodos para manipular esses dados em um pacote puro. Os dados e métodos
dentro de uma classe são chamados de membros da classe.

Quando você define uma classe, você define um blueprint para um tipo de dados. Isso não
define realmente nenhum dado, mas define o que o nome da classe significa, ou seja, em
que um objeto da classe consistirá e quais operações podem ser executadas em tal objeto.

Uma definição de classe começa com a classe de palavra-chave seguida pelo nome da
classe e é delimitada por um final . Por exemplo, definimos a classe Box usando a classe
de palavra-chave da seguinte maneira:

class Box
code
end

O nome deve começar com uma letra maiúscula e os nomes das convenções que contêm
mais de uma palavra são executados juntamente com cada palavra em maiúscula e nenhum
caractere separador (CamelCase).

Uma classe fornece os blueprints para objetos, então, basicamente, um objeto é criado a
partir de uma classe. Nós declaramos objetos de uma classe usando uma nova palavra-
chave. As seguintes declarações declaram dois objetos da classe Box -

box1 = Box.new
box2 = Box.new

O método initialize é um método de classe padrão Ruby e funciona quase da mesma


maneira que o construtor funciona em outras linguagens de programação orientadas a
objeto. O método initialize é útil quando você deseja inicializar algumas variáveis de classe
no momento da criação do objeto. Este método pode ter uma lista de parâmetros e, como
qualquer outro método ruby, seria precedido pela palavra-chave def como mostrado abaixo
-

class Box
def initialize(w,h)
@width, @height = w, h
end
end

As variáveis de instância são tipos de atributos de classe e tornam-se propriedades de


objetos depois que os objetos são criados usando a classe. Os atributos de cada objeto são
atribuídos individualmente e não compartilham nenhum valor com outros objetos. Eles são
acessados usando o operador @ dentro da classe, mas para acessá-los fora da classe,
usamos métodos públicos , que são chamados de métodos de acesso . Se tomarmos a
classe definida acima Box , @width e @height são variáveis de instância para a classe Box.

class Box
def initialize(w,h)
# assign instance variables
@width, @height = w, h
end
end

Para disponibilizar as variáveis fora da classe, elas devem ser definidas dentro dos métodos
acessadores , esses métodos acessadores também são conhecidos como métodos getter. O
exemplo a seguir mostra o uso de métodos de acesso -

#!/usr/bin/ruby -w

# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end

# accessor methods
def printWidth
@width
end

def printHeight
@height
end
end

# create an object
box = Box.new(10, 20)

# use accessor methods


x = box.printWidth()
y = box.printHeight()

puts "Width of the box is : #{x}"


puts "Height of the box is : #{y}"
Quando o código acima é executado, produz o seguinte resultado -

Width of the box is : 10


Height of the box is : 20

Semelhante aos métodos de acesso, que são usados para acessar o valor das variáveis,
Ruby fornece uma maneira de definir os valores dessas variáveis de fora da classe usando
métodos setter , que são definidos abaixo -

#!/usr/bin/ruby -w

# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end

# accessor methods
def getWidth
@width
end
def getHeight
@height
end

# setter methods
def setWidth=(value)
@width = value
end
def setHeight=(value)
@height = value
end
end

# create an object
box = Box.new(10, 20)

# use setter methods


box.setWidth = 30
box.setHeight = 50

# use accessor methods


x = box.getWidth()
y = box.getHeight()

puts "Width of the box is : #{x}"


puts "Height of the box is : #{y}"

Quando o código acima é executado, produz o seguinte resultado -

Width of the box is : 30


Height of the box is : 50

Os métodos de instância também são definidos da mesma forma que definimos qualquer
outro método usando a palavra-chave def e eles podem ser usados usando uma instância
de classe somente como mostrado abaixo. Sua funcionalidade não se limita a acessar as
variáveis de instância, mas também podem fazer muito mais de acordo com sua
necessidade.

#!/usr/bin/ruby -w

# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# instance method
def getArea
@width * @height
end
end

# create an object
box = Box.new(10, 20)

# call instance methods


a = box.getArea()
puts "Area of the box is : #{a}"

Quando o código acima é executado, produz o seguinte resultado -

Area of the box is : 200

As variáveis de classe são uma variável, que é compartilhada entre todas as instâncias de
uma classe. Em outras palavras, há uma instância da variável e ela é acessada por
instâncias de objetos. Variáveis de classe são prefixadas com dois caracteres @ (@@). Uma
variável de classe deve ser inicializada dentro da definição de classe, conforme mostrado
abaixo.

Um método de classe é definido usando def self.methodname () , que termina com o


delimitador final e seria chamado usando o nome da classe como
classname.methodname, conforme mostrado no exemplo a seguir -

#!/usr/bin/ruby -w

class Box
# Initialize our class variables
@@count = 0
def initialize(w,h)
# assign instance avriables
@width, @height = w, h

@@count += 1
end
def self.printCount()
puts "Box count is : #@@count"
end
end

# create two object


box1 = Box.new(10, 20)
box2 = Box.new(30, 100)

# call class method to print box count


Box.printCount()

Quando o código acima é executado, produz o seguinte resultado -

Box count is : 2

Qualquer classe que você definir deve ter um método de instância to_s para retornar uma
representação de string do objeto. A seguir, um exemplo simples para representar um
objeto Box em termos de largura e altura -

#!/usr/bin/ruby -w

class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# define to_s method
def to_s
"(w:#@width,h:#@height)" # string formatting of the object.
end
end

# create an object
box = Box.new(10, 20)

# to_s method will be called in reference of string automatically.


puts "String representation of box is : #{box}"

Quando o código acima é executado, produz o seguinte resultado -

String representation of box is : (w:10,h:20)

O Ruby oferece três níveis de proteção no nível de métodos da instância,Controle de acesso


que podem ser públicos, privados ou protegidos . Ruby não aplica
nenhum controle de acesso sobre variáveis de instância e classe.

Métodos públicos - métodos públicos podem ser chamados por qualquer pessoa.
Os métodos são públicos por padrão, exceto para initialize, que é sempre privado.

Métodos privados - os métodos privados não podem ser acessados nem exibidos
de fora da turma. Apenas os métodos de classe podem acessar membros privados.
Métodos Protegidos - Um método protegido pode ser chamado apenas por objetos
da classe de definição e suas subclasses. O acesso é mantido dentro da família.

A seguir, um exemplo simples para mostrar a sintaxe de todos os três modificadores de


acesso -

#!/usr/bin/ruby -w

# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end

# instance method by default it is public


def getArea
getWidth() * getHeight
end

# define private accessor methods


def getWidth
@width
end
def getHeight
@height
end
# make them private
private :getWidth, :getHeight

# instance method to print area


def printArea
@area = getWidth() * getHeight
puts "Big box area is : #@area"
end
# make it protected
protected :printArea
end

# create an object
box = Box.new(10, 20)

# call instance methods


a = box.getArea()
puts "Area of the box is : #{a}"

# try to call protected or methods


box.printArea()

Quando o código acima é executado, produz o seguinte resultado. Aqui, o primeiro método
é chamado com sucesso, mas o segundo método deu um problema.

Area of the box is : 200


test.rb:42: protected method `printArea' called for #
<Box:0xb7f11280 @height = 20, @width = 10> (NoMethodError)
Um dos conceitos mais importantes na programação orientada a objetos é o da herança. A
herança nos permite definir uma classe em termos de outra classe, o que facilita a criação e
manutenção de um aplicativo.

A herança também oferece uma oportunidade de reutilizar a funcionalidade do código e o


rápido tempo de implementação, mas infelizmente o Ruby não suporta múltiplos níveis de
heranças, mas o Ruby suporta mixins . Um mixin é como uma implementação especializada
de herança múltipla, na qual apenas a parte da interface é herdada.

Ao criar uma classe, em vez de escrever membros de dados e funções de membro


completamente novos, o programador pode designar que a nova classe deve herdar os
membros de uma classe existente. Essa classe existente é chamada de classe base ou
superclasse e a nova classe é chamada de classe ou subclasse derivada .

Ruby também suporta o conceito de subclassificação, isto é, herança e o exemplo a seguir


explica o conceito. A sintaxe para estender uma classe é simples. Basta adicionar um
caractere <e o nome da superclasse ao seu comando de classe. Por exemplo, a seguir
define uma classe BigBox como uma subclasse de Box -

#!/usr/bin/ruby -w

# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# instance method
def getArea
@width * @height
end
end

# define a subclass
class BigBox < Box

# add a new instance method


def printArea
@area = @width * @height
puts "Big box area is : #@area"
end
end

# create an object
box = BigBox.new(10, 20)

# print the area


box.printArea()

Quando o código acima é executado, produz o seguinte resultado -

Big box area is : 200


Embora você possa adicionar nova funcionalidade em uma classe derivada, mas às vezes
você gostaria de alterar o comportamento do método já definido em uma classe pai. Você
pode fazer isso simplesmente mantendo o mesmo nome do método e substituindo a
funcionalidade do método, conforme mostrado abaixo no exemplo -

#!/usr/bin/ruby -w

# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# instance method
def getArea
@width * @height
end
end

# define a subclass
class BigBox < Box

# change existing getArea method as follows


def getArea
@area = @width * @height
puts "Big box area is : #@area"
end
end

# create an object
box = BigBox.new(10, 20)

# print the area using overriden method.


box.getArea()

Gostaríamos que o operador + realizasse a adição vetorial de dois objetos Box usando +, o
operador * para multiplicar uma largura e altura de caixa por um escalar e o operador
unário para negar a largura e a altura da caixa. Aqui está uma versão da classe Box com
operadores matemáticos definidos -

class Box
def initialize(w,h) # Initialize the width and height
@width,@height = w, h
end

def +(other) # Define + to do vector addition


Box.new(@width + other.width, @height + other.height)
end

def -@ # Define unary minus to negate width and height


Box.new(-@width, -@height)
end

def *(scalar) # To perform scalar multiplication


Box.new(@width*scalar, @height*scalar)
end
end

Às vezes, queremos impedir que um objeto seja alterado. O método freeze em Object nos
permite fazer isso, transformando efetivamente um objeto em uma constante. Qualquer
objeto pode ser congelado chamando Object.freeze . Um objeto congelado não pode ser
modificado: você não pode alterar suas variáveis de instância.

Você pode verificar se um determinado objeto já está congelado ou não usando


Object.frozen? método, que retorna true caso o objeto esteja congelado, caso contrário,
um valor falso é retornado. O exemplo a seguir apaga o conceito -

#!/usr/bin/ruby -w

# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end

# accessor methods
def getWidth
@width
end
def getHeight
@height
end

# setter methods
def setWidth=(value)
@width = value
end
def setHeight=(value)
@height = value
end
end

# create an object
box = Box.new(10, 20)

# let us freez this object


box.freeze
if( box.frozen? )
puts "Box object is frozen object"
else
puts "Box object is normal object"
end

# now try using setter methods


box.setWidth = 30
box.setHeight = 50

# use accessor methods


x = box.getWidth()
y = box.getHeight()

puts "Width of the box is : #{x}"


puts "Height of the box is : #{y}"

Quando o código acima é executado, produz o seguinte resultado -

Box object is frozen object


test.rb:20:in `setWidth=': can't modify frozen object (TypeError)
from test.rb:39

Você pode definir uma constante dentro de uma classe atribuindo um valor numérico ou de
seqüência direta a uma variável, que é definida sem usar @ ou @@. Por convenção, nós
mantemos nomes constantes em maiúsculas.

Uma vez que uma constante é definida, você não pode alterar seu valor, mas você pode
acessar uma constante diretamente dentro de uma classe como uma variável, mas se você
quiser acessar uma constante fora da classe, você deve usar classname :: constant como
mostrado o exemplo abaixo.

#!/usr/bin/ruby -w

# define a class
class Box
BOX_COMPANY = "TATA Inc"
BOXWEIGHT = 10
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# instance method
def getArea
@width * @height
end
end

# create an object
box = Box.new(10, 20)

# call instance methods


a = box.getArea()
puts "Area of the box is : #{a}"
puts Box::BOX_COMPANY
puts "Box weight is: #{Box::BOXWEIGHT}"

Quando o código acima é executado, produz o seguinte resultado -

Area of the box is : 200


TATA Inc
Box weight is: 10

Constantes de classe são herdadas e podem ser substituídas como métodos de instância.
Pode haver uma situação em que você deseja criar um objeto sem chamar seu construtor
de inicializar, ou seja, usando o novo método, nesse caso, você pode chamar allocate , que
criará um objeto não inicializado para você, como no exemplo a seguir -

#!/usr/bin/ruby -w

# define a class
class Box
attr_accessor :width, :height

# constructor method
def initialize(w,h)
@width, @height = w, h
end

# instance method
def getArea
@width * @height
end
end

# create an object using new


box1 = Box.new(10, 20)

# create another object using allocate


box2 = Box.allocate

# call instance method using box1


a = box1.getArea()
puts "Area of the box is : #{a}"

# call instance method using box2


a = box2.getArea()
puts "Area of the box is : #{a}"

Quando o código acima é executado, produz o seguinte resultado -

Area of the box is : 200


test.rb:14: warning: instance variable @width not initialized
test.rb:14: warning: instance variable @height not initialized
test.rb:14:in `getArea': undefined method `*'
for nil:NilClass (NoMethodError) from test.rb:29

Se as definições de classe forem executáveis, isso significa que elas sãoInformações de Classe
executadas no contexto de algum objeto: self deve referenciar alguma
coisa. Vamos descobrir o que é isso.

#!/usr/bin/ruby -w

class Box
# print class information
puts "Type of self = #{self.type}"
puts "Name of self = #{self.name}"
end

Quando o código acima é executado, produz o seguinte resultado -

Type of self = Class


Name of self = Box

Isso significa que uma definição de classe é executada com essa classe como o objeto atual.
Isso significa que os métodos na metaclasse e suas superclasses estarão disponíveis
durante a execução da definição do método.

Uma expressão regular é uma sequência especial de caracteres que ajuda você a encontrar
ou encontrar outras strings ou conjuntos de strings usando uma sintaxe especializada
mantida em um padrão.

Um literal de expressão regular é um padrão entre barras ou entre delimitadores arbitrários


seguidos por% r como segue -

Sintaxe

/pattern/
/pattern/im # option can be specified
%r!/usr/local! # general delimited regular expression

#!/usr/bin/ruby

line1 = "Cats are smarter than dogs";


line2 = "Dogs also like meat";

if ( line1 =~ /Cats(.*)/ )
puts "Line1 contains Cats"
end
if ( line2 =~ /Cats(.*)/ )
puts "Line2 contains Dogs"
end

Isso produzirá o seguinte resultado -

Line1 contains Cats

Os literais de expressões regulares podem incluir um modificador opcional para controlar


vários aspectos da correspondência. O modificador é especificado após o segundo caractere
de barra, conforme mostrado anteriormente e pode ser representado por um desses
caracteres -
Sr. Modificador e Descrição
Não.

Eu
1
Ignora o caso ao corresponder ao texto.

2 Executa interpolações # {} apenas uma vez, a primeira vez que o literal de


expressão regular é avaliado.

x
3
Ignora o espaço em branco e permite comentários em expressões regulares.

m
4
Corresponde a várias linhas, reconhecendo novas linhas como caracteres normais.

u, e, s, n

Interpreta o regexp como Unicode (UTF-8), EUC, SJIS ou ASCII. Se nenhum


5
desses modificadores for especificado, presume-se que a expressão regular use a
codificação de origem.

Como os literais de string delimitados com% Q, Ruby permite que você inicie suas
expressões regulares com% r seguido por um delimitador de sua escolha. Isso é útil quando
o padrão que você está descrevendo contém muitos caracteres de barra que você não quer
escapar -

# Following matches a single slash character, no escape required


%r|/|

# Flag characters are allowed with this syntax, too


%r[</(.*)>]i

Exceto pelos caracteres de controle, (+?. * ^ $ () [] {} | \) , Todos os caracteres são


compatíveis. Você pode escapar de um caractere de controle precedendo-o com uma barra
invertida.

A tabela a seguir lista a sintaxe da expressão regular disponível em Ruby.


Personagens Literal

Classes de Personagem

Classes Especiais de Personagem

Casos de Repetição

Repetição não gananciosa

Agrupando com Parênteses

Referências de volta

Alternativas

Âncoras

Sintaxe Especial com Parênteses

Alguns dos métodos String mais importantes que usam expressões regulares são sub e
gsub e suas variantes in-loco sub! e gsub! .

Todos esses métodos executam uma operação de pesquisa e substituição usando um padrão
Regexp. O sub e sub! substitui a primeira ocorrência do padrão e gsub & gsub! substitui
todas as ocorrências.

O sub e o gsub retornam uma nova string, deixando o original não modificado como sub! e
gsub! Modifique a cadeia na qual eles são chamados.

A seguir está o exemplo -

#!/usr/bin/ruby

phone = "2004-959-559 #This is Phone Number"


# Delete Ruby-style comments
phone = phone.sub!(/#.*$/, "")
puts "Phone Num : #{phone}"

# Remove anything other than digits


phone = phone.gsub!(/\D/, "")
puts "Phone Num : #{phone}"

Isso produzirá o seguinte resultado -

Phone Num : 2004-959-559


Phone Num : 2004959559

A seguir, outro exemplo -

#!/usr/bin/ruby

text = "rails are rails, really good Ruby on Rails"

# Change "rails" to "Rails" throughout


text.gsub!("rails", "Rails")

# Capitalize the word "Rails" throughout


text.gsub!(/\brails\b/, "Rails")
puts "#{text}"

Isso produzirá o seguinte resultado -

Rails are Rails, really good Ruby on Rails

Este capítulo ensina como acessar um banco de dados usando Ruby. O módulo Ruby DBI
fornece uma interface independente de banco de dados para scripts Ruby semelhantes aos
do módulo Perl DBI.

DBI significa Database Independent Interface for Ruby, o que significa que o DBI fornece
uma camada de abstração entre o código Ruby e o banco de dados subjacente, permitindo
que você mude as implementações do banco de dados com muita facilidade. Ele define um
conjunto de métodos, variáveis e convenções que fornecem uma interface de banco de
dados consistente, independente do banco de dados real que está sendo usado.

DBI pode interagir com o seguinte -

ADO (ActiveX Data Objects)

DB2

Base Frontal

mSQL

MySQL

ODBC

Oráculo
OCI8 (Oracle)

PostgreSQL

Servidor proxy

SQLite

SQLRelay

O DBI é independente de qualquer banco de dados disponível no back-end. Você pode usar
o DBI se estiver trabalhando com Oracle, MySQL ou Informix, etc. Isso fica claro no
diagrama de arquitetura a seguir.

A arquitetura geral do Ruby DBI usa duas camadas -

A camada da interface do banco de dados (DBI). Essa camada é independente de


banco de dados e fornece um conjunto de métodos de acesso comuns que são
usados da mesma maneira, independentemente do tipo de servidor de banco de
dados com o qual você está se comunicando.

A camada do driver do banco de dados (DBD). Essa camada é dependente do banco


de dados; drivers diferentes fornecem acesso a diferentes mecanismos de banco de
dados. Existe um driver para o MySQL, outro para o PostgreSQL, outro para o
InterBase, outro para o Oracle e assim por diante. Cada driver interpreta solicitações
da camada DBI e as mapeia em solicitações apropriadas para um determinado tipo
de servidor de banco de dados.

Se você quiser escrever scripts Ruby para acessar bancos de dados MySQL,Pré-requisitos
você precisará ter o módulo Ruby MySQL instalado.

Este módulo funciona como um DBD, conforme explicado acima, e pode ser baixado em
https://www.tmtm.org/en/mysql/ruby/

Você pode baixar e instalar o módulo Ruby DBI no seguinte local -

https://imgur.com/NFEuWe4/embed
Antes de iniciar esta instalação, certifique-se de ter o privilégio de root. Agora, siga os
passos abaixo -

$ tar zxf dbi-0.2.0.tar.gz

Vá no diretório de distribuição dbi-0.2.0 nd configure-o usando o script setup.rb nesse


diretório. O comando de configuração mais geral se parece com isso, sem argumentos após
o argumento de configuração. Este comando configura a distribuição para instalar todos os
drivers por padrão.

$ ruby setup.rb config

Para ser mais específico, forneça uma opção --with que lista as partes específicas da
distribuição que você deseja usar. Por exemplo, para configurar apenas o módulo DBI
principal e o driver do nível do DBD do MySQL, emita o comando a seguir -

$ ruby setup.rb config --with = dbi,dbd_mysql

O passo final é construir o driver e instalá-lo usando os seguintes comandos -

$ ruby setup.rb setup


$ ruby setup.rb install

Supondo que vamos trabalhar com banco de dados MySQL, antes de conectar a um banco
de dados, certifique-se do seguinte -

Você criou um banco de dados TESTDB.

Você criou EMPLOYEE em TESTDB.

Esta tabela tem os campos FIRST_NAME, LAST_NAME, AGE, SEX e INCOME.

O ID do usuário "testuser" e a senha "test123" estão configurados para acessar o


TESTDB.

Ruby Module DBI está instalado corretamente em sua máquina.

Você passou pelo tutorial do MySQL para entender o MySQL Basics.

A seguir, o exemplo de conexão com o banco de dados MySQL "TESTDB"

#!/usr/bin/ruby -w

require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
# get server version string and display it
row = dbh.select_one("SELECT VERSION()")
puts "Server version: " + row[0]
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
ensure
# disconnect from server
dbh.disconnect if dbh
end

Ao executar este script, ele produz o seguinte resultado em nossa máquina Linux.

Server version: 5.0.45

Se uma conexão for estabelecida com a fonte de dados, um Database Handle será
retornado e salvo em dbh para uso posterior, caso contrário, dbh é definido como valor
nulo e e.err e e :: errstr retornam código de erro e uma string de erro respectivamente.

Finalmente, antes de sair, certifique-se de que a conexão com o banco de dados esteja
fechada e os recursos sejam liberados.

A operação INSERT é necessária quando você deseja criar seus registros em uma tabela de
banco de dados.

Uma vez que uma conexão de dados é estabelecida, estamos prontos para criar tabelas ou
registros nas tabelas de banco de dados usando fazer método ou preparar e executar
método.

Instruções que não retornam linhas podem ser emitidas invocando o método do
manipulador do banco de dados. Esse método usa um argumento de string de instrução e
retorna uma contagem do número de linhas afetadas pela instrução.

dbh.do("DROP TABLE IF EXISTS EMPLOYEE")


dbh.do("CREATE TABLE EMPLOYEE (
FIRST_NAME CHAR(20) NOT NULL,
LAST_NAME CHAR(20),
AGE INT,
SEX CHAR(1),
INCOME FLOAT )" );

Da mesma forma, você pode executar a instrução SQL INSERT para criar um registro na
tabela EMPLOYEE.

#!/usr/bin/ruby -w
require "dbi"

begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
dbh.do( "INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, INCOME)
VALUES ('Mac', 'Mohan', 20, 'M', 2000)" )
puts "Record has been created"
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# disconnect from server
dbh.disconnect if dbh
end

Você pode usar preparar e executar métodos da classe DBI para executar a instrução SQL
através do código Ruby.

Criação de registro leva as seguintes etapas -

Preparando a instrução SQL com a instrução INSERT. Isso será feito usando o
método prepare .

Executando consulta SQL para selecionar todos os resultados do banco de dados.


Isso será feito usando o método de execução .

Liberando o identificador da instrução. Isso será feito usando a API de acabamento

Se tudo correr bem, confirme essa operação, caso contrário, você poderá reverter
a transação completa.

A seguir está a sintaxe para usar esses dois métodos -

sth = dbh.prepare(statement)
sth.execute
... zero or more SQL operations ...
sth.finish

Esses dois métodos podem ser usados para transmitir valores de ligação para instruções
SQL. Pode haver um caso em que os valores a serem inseridos não sejam dados
antecipadamente. Nesse caso, os valores de ligação são usados. Um ponto de interrogação (
? ) É usado no lugar dos valores reais e, em seguida, os valores reais são passados pela API
execute ().

A seguir, o exemplo para criar dois registros na tabela EMPLOYEE -

#!/usr/bin/ruby -w
require "dbi"

begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
sth = dbh.prepare( "INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, INCOME)
VALUES (?, ?, ?, ?, ?)" )
sth.execute('John', 'Poul', 25, 'M', 2300)
sth.execute('Zara', 'Ali', 17, 'F', 1000)
sth.finish
dbh.commit
puts "Record has been created"
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# disconnect from server
dbh.disconnect if dbh
end

Se houver vários INSERTs por vez, preparar uma instrução primeiro e, em seguida, executá-
la várias vezes em um loop é mais eficiente do que invocar cada vez durante o loop.

LEITURA Operação em qualquer banco de dados significa buscar algumas informações úteis
do banco de dados.

Uma vez estabelecida a nossa conexão com o banco de dados, estamos prontos para fazer
uma consulta neste banco de dados. Podemos usar tanto fazer método ou preparar e
executar métodos para buscar valores de uma tabela de banco de dados.

A obtenção de registros leva os seguintes passos -

Preparando a consulta SQL com base nas condições necessárias. Isso será feito
usando o método prepare .

Executando consulta SQL para selecionar todos os resultados do banco de dados.


Isso será feito usando o método de execução .

Buscando todos os resultados um por um e imprimindo esses resultados. Isso será


feito usando o método fetch .

Liberando o identificador da instrução. Isso será feito usando o método de


acabamento .

A seguir, o procedimento para consultar todos os registros da tabela EMPLOYEE com salário
maior que 1000.

#!/usr/bin/ruby -w

require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
sth = dbh.prepare("SELECT * FROM EMPLOYEE WHERE INCOME > ?")
sth.execute(1000)

sth.fetch do |row|
printf "First Name: %s, Last Name : %s\n", row[0], row[1]
printf "Age: %d, Sex : %s\n", row[2], row[3]
printf "Salary :%d \n\n", row[4]
end
sth.finish
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
ensure
# disconnect from server
dbh.disconnect if dbh
end

Isso produzirá o seguinte resultado -

First Name: Mac, Last Name : Mohan


Age: 20, Sex : M
Salary :2000

First Name: John, Last Name : Poul


Age: 25, Sex : M
Salary :2300

Existem mais métodos de atalho para buscar registros do banco de dados. Se você estiver
interessado, então vá até Buscar o Resultado. Caso contrário, vá para a próxima seção.

ATUALIZAÇÃO Operação em qualquer banco de dados significa atualizar um ou mais


registros, que já estão disponíveis no banco de dados. A seguir, o procedimento para
atualizar todos os registros que possuem SEX como 'M'. Aqui, nós aumentaremos AGE de
todos os machos em um ano. Isso levará três etapas -

Preparando a consulta SQL com base nas condições necessárias. Isso será feito
usando o método prepare .

Executando consulta SQL para selecionar todos os resultados do banco de dados.


Isso será feito usando o método de execução .

Liberando o identificador da instrução. Isso será feito usando o método de


acabamento .

Se tudo correr bem, submeta essa operação, caso contrário, você poderá reverter
a transação completa.
#!/usr/bin/ruby -w

require "dbi"

begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
sth = dbh.prepare("UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = ?")
sth.execute('M')
sth.finish
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# disconnect from server
dbh.disconnect if dbh
end

A operação DELETE é necessária quando você deseja excluir alguns registros do banco de
dados. A seguir, o procedimento para excluir todos os registros do EMPLOYEE, nos quais a
idade é superior a 20. Essa operação seguirá as etapas a seguir.

Preparando a consulta SQL com base nas condições necessárias. Isso será feito
usando o método prepare .

Executando consulta SQL para excluir registros necessários do banco de dados. Isso
será feito usando o método de execução .

Liberando o identificador da instrução. Isso será feito usando o método de


acabamento .

Se tudo correr bem, submeta essa operação, caso contrário, você poderá reverter
a transação completa.

#!/usr/bin/ruby -w

require "dbi"

begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
sth = dbh.prepare("DELETE FROM EMPLOYEE WHERE AGE > ?")
sth.execute(20)
sth.finish
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# disconnect from server
dbh.disconnect if dbh
end

As transações são um mecanismo que garante a consistência dos dados. As transações


devem ter as quatro propriedades a seguir -

Atomicidade - Uma transação é concluída ou nada acontece.

Consistência - Uma transação deve começar em um estado consistente e deixar o


sistema com um estado consistente.

Isolamento - Resultados intermediários de uma transação não são visíveis fora da


transação atual.

Durabilidade - Uma vez que uma transação foi confirmada, os efeitos são
persistentes, mesmo após uma falha do sistema.

O DBI fornece dois métodos para confirmar ou reverter uma transação. Há mais um método
chamado transação, que pode ser usado para implementar transações. Existem duas
abordagens simples para implementar transações -

A primeira abordagem usa os métodos de confirmação e reversão do DBI para confirmar ou


cancelar explicitamente a transação -

dbh['AutoCommit'] = false # Set auto commit to false.


begin
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'John'")
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'Zara'")
dbh.commit
rescue
puts "transaction failed"
dbh.rollback
end
dbh['AutoCommit'] = true

A segunda abordagem usa o método de transação . Isso é mais simples, porque é


necessário um bloco de códigos contendo as instruções que compõem a transação. O
método de transação executa o bloco e invoca commit ou rollback automaticamente,
dependendo se o bloco é bem-sucedido ou falha -

dbh['AutoCommit'] = false # Set auto commit to false.


dbh.transaction do |dbh|
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'John'")
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1 WHERE FIRST_NAME = 'Zara'")
end
dbh['AutoCommit'] = true
Commit é a operação, que dá um sinal verde ao banco de dados para finalizar as mudanças
e, após essa operação, nenhuma alteração pode ser revertida.

Aqui está um exemplo simples para chamar o método commit .

dbh.commit

Se você não estiver satisfeito com uma ou mais das alterações e quiser reverter essas
alterações completamente, use o método de reversão .

Aqui está um exemplo simples para chamar o método de reversão .

dbh.rollback

Para desconectar a conexão com o banco de dados, use a API de desconexão.

dbh.disconnect

Se a conexão com um banco de dados for fechada pelo usuário com o método de
desconexão, todas as transações pendentes serão revertidas pelo DBI. No entanto, em vez
de depender de qualquer um dos detalhes de implementação do DBI, seria melhor que seu
aplicativo chamasse o commit ou o rollback explicitamente.

Existem muitas fontes de erros. Alguns exemplos são um erro de sintaxeManipulando Erros
em uma instrução SQL executada, uma falha de conexão ou a chamada do
método de busca para um identificador de instrução já cancelado ou concluído.

Se um método DBI falhar, o DBI levantará uma exceção. Os métodos DBI podem gerar
vários tipos de exceção, mas as duas classes de exceção mais importantes são DBI ::
InterfaceError e DBI :: DatabaseError .

Objetos de exceção dessas classes têm três atributos chamados err , errstr e state , que
representam o número do erro, uma string de erro descritiva e um código de erro padrão.
Os atributos são explicados abaixo -

err - Retorna uma representação de inteiro do erro ocorrido ou nil se isto não for
suportado pelo DBD. O DBD do Oracle, por exemplo, retorna a parte numérica de
uma mensagem de erro ORA-XXXX .

errstr - Retorna uma representação de string do erro ocorrido.

estado - Retorna o código SQLSTATE do erro ocorrido. O SQLSTATE é uma cadeia


de cinco caracteres. A maioria dos DBDs não suporta isso e retorna nil.
Você viu o seguinte código acima na maioria dos exemplos -

rescue DBI::DatabaseError => e


puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
dbh.rollback
ensure
# disconnect from server
dbh.disconnect if dbh
end

Para obter informações de depuração sobre o que seu script está fazendo enquanto ele é
executado, você pode ativar o rastreamento. Para fazer isso, você deve primeiro carregar o
módulo dbi / trace e, em seguida, chamar o método de rastreio que controla o modo de
rastreio e o destino de saída -

require "dbi/trace"
..............

trace(mode, destination)

O valor do modo pode ser 0 (desligado), 1, 2 ou 3 e o destino deve ser um objeto IO. Os
valores padrão são 2 e STDERR, respectivamente.

Existem alguns métodos que criam alças. Esses métodos podem ser chamados com um
bloco de códigos. A vantagem de usar o bloco de códigos junto com métodos é que eles
fornecem o identificador para o bloco de código como seu parâmetro e automaticamente
limpa o identificador quando o bloco termina. Existem alguns exemplos para entender o
conceito.

DBI.connect - Esse método gera um identificador de banco de dados e é


recomendável chamar a desconexão no final do bloco para desconectar o banco de
dados.

dbh.prepare - Esse método gera um identificador de instrução e é recomendável


terminar no final do bloco. Dentro do bloco, você deve invocar executar método para
executar a instrução.

dbh.execute - Este método é semelhante, exceto que não precisamos invocar a


execução dentro do bloco. O identificador de instrução é executado
automaticamente.

O DBI.connect pode pegar um bloco de código, passar o identificador do banco de dados


para ele e desconectar automaticamente o identificador no final do bloco da seguinte
maneira.
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123") do |dbh|

dbh.prepare pode pegar um bloco de código, passar o identificador de instrução para ele e
as chamadas automaticamente terminam no final do bloco da seguinte maneira.

dbh.prepare("SHOW DATABASES") do |sth|


sth.execute
puts "Databases: " + sth.fetch_all.join(", ")
end

O dbh.execute pode pegar um bloco de código, passar o identificador de instrução para ele
e as chamadas automaticamente terminam no final do bloco da seguinte maneira -

dbh.execute("SHOW DATABASES") do |sth|


puts "Databases: " + sth.fetch_all.join(", ")
end

O método de transação DBI também aceita um bloco de código que foi descrito acima.

O DBI permite que os drivers do banco de dados forneçam funções adicionais específicas do
banco de dados, que podem ser chamadas pelo usuário através do método func de qualquer
objeto Handle.

Atributos específicos do driver são suportados e podem ser configurados ou obtidos usando
os métodos [] = ou [] .

DBD :: Mysql implementa as seguintes funções específicas do driver -

#!/usr/bin/ruby

require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", "testuser", "test123")
puts dbh.func(:client_info)
puts dbh.func(:client_version)
puts dbh.func(:host_info)
puts dbh.func(:proto_info)
puts dbh.func(:server_info)
puts dbh.func(:thread_id)
puts dbh.func(:stat)
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
ensure
dbh.disconnect if dbh
end

Isso produzirá o seguinte resultado -

5.0.45
50045
Localhost via UNIX socket
10
5.0.45
150621
Uptime: 384981 Threads: 1 Questions: 1101078 Slow queries: 4 \
Opens: 324 Flush tables: 1 Open tables: 64 \
Queries per second avg: 2.860

Ruby é uma linguagem de propósito geral; ele não pode ser chamado de linguagem da web
. Mesmo assim, aplicações web e ferramentas web em geral estão entre os usos mais
comuns do Ruby.

Não apenas você pode escrever seu próprio servidor SMTP, daemon FTP ou servidor Web em
Ruby, mas você também pode usar Ruby para tarefas mais usuais como programação CGI
ou como um substituto para PHP.

Por favor, passe alguns minutos com o Tutorial de programação CGI para mais detalhes
sobre a programação CGI.

O script CGI mais básico se parece com isso -

#!/usr/bin/ruby

puts "HTTP/1.0 200 OK"


puts "Content-type: text/html\n\n"
puts "<html><body>This is a test</body></html>"

Se você chamar esse script de test.cgi e carregá -lo em um provedor de hospedagem


baseado em Unix com as permissões corretas, poderá usá-lo como um script CGI.

Por exemplo, se você tiver o site https://www.example.com/ hospedado em um provedor


de hospedagem Web Linux e fizer o upload de test.cgi para o diretório principal e conceder
permissões de execução, visite https: // www. example.com/test.cgi deve retornar uma
página HTML dizendo Isto é um teste .

Aqui, quando test.cgi é solicitado a partir de um navegador da Web, o servidor Web procura
por test.cgi no site e, em seguida, o executa usando o interpretador Ruby. O script Ruby
retorna um cabeçalho HTTP básico e retorna um documento HTML básico.
O Ruby vem com uma biblioteca especial chamada cgi que permite interações mais
sofisticadas do que aquelas com o script CGI anterior.

Vamos criar um script CGI básico que usa cgi -

#!/usr/bin/ruby

require 'cgi'
cgi = CGI.new

puts cgi.header
puts "<html><body>This is a test</body></html>"

Aqui, você criou um objeto CGI e usou-o para imprimir a linha de cabeçalho para você.

Usando a classe CGI, você tem acesso aos parâmetros de consulta HTML de duas maneiras.
Suponha que recebamos uma URL de /cgi-bin/test.cgi?FirstName = Zara & LastName = Ali.

Você pode acessar os parâmetros FirstName e LastName usando CGI # [] diretamente como
segue -

#!/usr/bin/ruby

require 'cgi'
cgi = CGI.new
cgi['FirstName'] # => ["Zara"]
cgi['LastName'] # => ["Ali"]

Existe outra maneira de acessar essas variáveis de formulário. Este código lhe dará um hash
de todas as chaves e valores -

#!/usr/bin/ruby

require 'cgi'
cgi = CGI.new
h = cgi.params # => {"FirstName"=>["Zara"],"LastName"=>["Ali"]}
h['FirstName'] # => ["Zara"]
h['LastName'] # => ["Ali"]

A seguir está o código para recuperar todas as chaves -

#!/usr/bin/ruby

require 'cgi'
cgi = CGI.new
cgi.keys # => ["FirstName", "LastName"]

Se um formulário contiver vários campos com o mesmo nome, os valores correspondentes


serão retornados ao script como uma matriz. O acessador [] retorna apenas o primeiro
deles.index o resultado do método params para obtê-los todos.
Neste exemplo, suponha que o formulário tenha três campos chamados "nome" e inserimos
três nomes "Zara", "Huma" e "Nuha" -

#!/usr/bin/ruby

require 'cgi'
cgi = CGI.new
cgi['name'] # => "Zara"
cgi.params['name'] # => ["Zara", "Huma", "Nuha"]
cgi.keys # => ["name"]
cgi.params # => {"name"=>["Zara", "Huma", "Nuha"]}

Nota - Ruby cuidará dos métodos GET e POST automaticamente. Não há tratamento
separado para esses dois métodos diferentes.

Um formulário associado, mas básico, que poderia enviar os dados corretos teria o código
HTML como assim -

<html>
<body>
<form method = "POST" action = "http://www.example.com/test.cgi">
First Name :<input type = "text" name = "FirstName" value = "" />
<br />
Last Name :<input type = "text" name = "LastName" value = "" />
<input type = "submit" value = "Submit Data" />
</form>
</body>
</html>

O CGI contém um grande número de métodos usados para criar HTML. Você encontrará um
método por tag. Para habilitar esses métodos, você deve criar um objeto CGI chamando
CGI.new.

Para facilitar o aninhamento de tags, esses métodos pegam seu conteúdo como blocos de
código. Os blocos de código devem retornar uma String , que será usada como conteúdo da
tag. Por exemplo -

#!/usr/bin/ruby

require "cgi"
cgi = CGI.new("html4")
cgi.out {
cgi.html {
cgi.head { "\n"+cgi.title{"This Is a Test"} } +
cgi.body { "\n"+
cgi.form {"\n"+
cgi.hr +
cgi.h1 { "A Form: " } + "\n"+
cgi.textarea("get_text") +"\n"+
cgi.br +
cgi.submit
}
}
}
}

OBSERVAÇÃO : o método de formulário da classe CGI pode aceitar um parâmetro de


método, que definirá o método HTTP (GET, POST, etc.) a ser usado no envio de formulários.
O padrão, usado neste exemplo, é POST.

Isso produzirá o seguinte resultado -

Content-Type: text/html
Content-Length: 302

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Final//EN">

<HTML>
<HEAD>
<TITLE>This Is a Test</TITLE>
</HEAD>
<BODY>
<FORM METHOD = "post" ENCTYPE = "application/x-www-form-urlencoded">
<HR>
<H1>A Form: </H1>
<TEXTAREA COLS = "70" NAME = "get_text" ROWS = "10"></TEXTAREA>
<BR>
<INPUT TYPE = "submit">
</FORM>
</BODY>
</HTML>

Ao lidar com URLs e código HTML, você deve ter cuidado ao citar certos caracteres. Por
exemplo, um caractere de barra (/) tem um significado especial em um URL, portanto, ele
deve ser de escape se não fizer parte do nome do caminho.

Por exemplo, qualquer / na parte da consulta da URL será traduzida para a string% 2F e
deverá ser traduzida de volta para a / para você usá-la. Espaço e e comercial também são
caracteres especiais. Para lidar com isso, o CGI fornece as rotinas CGI.escape e
CGI.unescape .

#!/usr/bin/ruby

require 'cgi'
puts CGI.escape(Zara Ali/A Sweet & Sour Girl")

Isso produzirá o seguinte resultado -

Zara+Ali%2FA Sweet+%26+Sour+Girl")
#!/usr/bin/ruby

require 'cgi'
puts CGI.escapeHTML('<h1>Zara Ali/A Sweet & Sour Girl</h1>')

Isso produzirá o seguinte resultado -

&lt;h1&gt;Zara Ali/A Sweet & Sour Girl&lt;/h1&gt;'

Aqui está a lista de métodos relacionados à classe CGI -

O CGI do Ruby - Métodos relacionados à biblioteca CGI padrão.

Nós explicamos esses dois conceitos em diferentes seções. Por favor, siga as seções -

Os cookies CGI do Ruby - Como lidar com cookies CGI.

The Ruby CGI Sessions - Como gerenciar sessões CGI.

Você pode verificar o seguinte tópico na Internet para hospedar seu site em um servidor
baseado em Unix -

Hospedagem na Web baseada em Unix

O SMTP (Simple Mail Transfer Protocol) é um protocolo que manipula o envio de email e o
roteamento de emails entre servidores de email.

Ruby fornece a classe Net :: SMTP para conexão do lado do cliente SMTP (Simple Mail
Transfer Protocol) e fornece dois métodos de classe new e start .

O novo leva dois parâmetros -

O nome do servidor padrão para localhost.

O número da porta padrão para a porta bem conhecida 25.

O método start pega esses parâmetros -

O servidor - nome do IP do servidor SMTP, padronizando para localhost.

A porta - Número da porta, com o padrão de 25.

O domínio - Domínio do remetente do email, padronizado como ENV


["HOSTNAME"].
A conta - nome de usuário, o padrão é nulo.

A senha - Senha do usuário, cujo valor é nulo.

O authtype - Tipo de Autorização, padronizando a cram_md5 .

Um objeto SMTP tem um método de instância chamado sendmail, que normalmente será
usado para fazer o trabalho de enviar uma mensagem. Leva três parâmetros -

A fonte - Uma string ou array ou qualquer coisa com um iterador de cada um


retornando uma string de cada vez.

O remetente - Uma string que aparecerá no campo from do email.

Os destinatários - Uma string ou uma matriz de strings representando o (s)


destinatário (s) do destinatário.

Aqui está uma maneira simples de enviar um email usando o script Ruby. Tente uma vez -

require 'net/smtp'

message = <<MESSAGE_END
From: Private Person <me@fromdomain.com>
To: A Test User <test@todomain.com>
Subject: SMTP e-mail test

This is a test e-mail message.


MESSAGE_END

Net::SMTP.start('localhost') do |smtp|
smtp.send_message message, 'me@fromdomain.com', 'test@todomain.com'
end

Aqui, você colocou um e-mail básico em uma mensagem, usando um documento, tomando
o cuidado de formatar os cabeçalhos corretamente. Os e-mails exigem um cabeçalho De ,
Para e Assunto , separados do corpo do e-mail com uma linha em branco.

Para enviar o e-mail, use Net :: SMTP para se conectar ao servidor SMTP na máquina local e
use o método send_message junto com a mensagem, o endereço de e o endereço de
destino como parâmetros (mesmo que os endereços de e para sejam dentro do próprio
e-mail, eles nem sempre são usados para rotear e-mail).

Se você não estiver executando um servidor SMTP em sua máquina, poderá usar o Net ::
SMTP para se comunicar com um servidor SMTP remoto. A menos que você esteja usando
um serviço de webmail (como o Hotmail ou o Yahoo! Mail), seu provedor de e-mail
fornecerá detalhes do servidor de e-mail de saída que você pode fornecer para o Net ::
SMTP, como segue:

Net::SMTP.start('mail.your-domain.com')

Essa linha de código se conecta ao servidor SMTP na porta 25 de mail.seudominio.com sem


usar nenhum nome de usuário ou senha. Se você precisar, no entanto, você pode especificar
o número da porta e outros detalhes. Por exemplo -

Net::SMTP.start('mail.your-domain.com',
25,
'localhost',
'username', 'password' :plain)

Este exemplo conecta-se ao servidor SMTP em mail.seudominio.com usando um nome de


usuário e senha em formato de texto simples. Ele identifica o nome do host do cliente como
localhost.

Quando você envia uma mensagem de texto usando Ruby, todo o conteúdo será tratado
como texto simples. Mesmo se você incluir tags HTML em uma mensagem de texto, ela será
exibida como texto simples e as tags HTML não serão formatadas de acordo com a sintaxe
HTML. Mas Ruby Net :: SMTP fornece opção para enviar uma mensagem HTML como
mensagem HTML real.

Ao enviar uma mensagem de e-mail, você pode especificar uma versão do Mime, um tipo de
conteúdo e um conjunto de caracteres para enviar um e-mail em HTML.

A seguir, o exemplo para enviar conteúdo HTML como um email. Tente uma vez -

require 'net/smtp'

message = <<MESSAGE_END
From: Private Person <me@fromdomain.com>
To: A Test User <test@todomain.com>
MIME-Version: 1.0
Content-type: text/html
Subject: SMTP e-mail test

This is an e-mail message to be sent in HTML format

<b>This is HTML message.</b>


<h1>This is headline.</h1>
MESSAGE_END

Net::SMTP.start('localhost') do |smtp|
smtp.send_message message, 'me@fromdomain.com', 'test@todomain.com'
end

Para enviar um email com conteúdo misto, é necessário definir o cabeçalho do tipo de
conteúdo para multipart / mixed . Em seguida, as seções de texto e anexo podem ser
especificadas dentro dos limites .

Um limite é iniciado com dois hífens seguidos por um número exclusivo, que não pode
aparecer na parte da mensagem do email. Um limite final indicando a seção final do e-mail
também deve terminar com dois hífens.

Arquivos anexados devem ser codificados com a função pack ("m") para ter a codificação
base64 antes da transmissão.

A seguir, o exemplo, que enviará um arquivo /tmp/test.txt como anexo.

require 'net/smtp'

filename = "/tmp/test.txt"
# Read a file and encode it into base64 format
filecontent = File.read(filename)
encodedcontent = [filecontent].pack("m") # base64

marker = "AUNIQUEMARKER"
body = <<EOF
This is a test email to send an attachement.
EOF

# Define the main headers.


part1 = <<EOF
From: Private Person <me@fromdomain.net>
To: A Test User <test@todmain.com>
Subject: Sending Attachement
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary = #{marker}
--#{marker}
EOF

# Define the message action


part2 = <<EOF
Content-Type: text/plain
Content-Transfer-Encoding:8bit

#{body}
--#{marker}
EOF

# Define the attachment section


part3 = <<EOF
Content-Type: multipart/mixed; name = \"#{filename}\"
Content-Transfer-Encoding:base64
Content-Disposition: attachment; filename = "#{filename}"

#{encodedcontent}
--#{marker}--
EOF

mailtext = part1 + part2 + part3

# Let's put our code in safe area


begin
Net::SMTP.start('localhost') do |smtp|
smtp.sendmail(mailtext, 'me@fromdomain.net', ['test@todmain.com'])
end
rescue Exception => e
print "Exception occured: " + e
end

NOTA - Você pode especificar vários destinos dentro da matriz, mas eles devem ser
separados por vírgula.

O Ruby fornece dois níveis de acesso aos serviços de rede. Em um nível baixo, você pode
acessar o suporte a soquete básico no sistema operacional subjacente, o que permite
implementar clientes e servidores para protocolos orientados a conexão e sem conexão.

O Ruby também possui bibliotecas que fornecem acesso de nível superior a protocolos de
rede específicos no nível do aplicativo, como FTP, HTTP e assim por diante.

Este capítulo dá-lhe uma compreensão sobre o conceito mais famoso em Networking -
Socket Programming.

Soquetes são os pontos finais de um canal de comunicação bidirecional. Soquetes podem se


comunicar dentro de um processo, entre processos na mesma máquina ou entre processos
em diferentes continentes.

Sockets podem ser implementados em vários tipos de canais diferentes: sockets de domínio
Unix, TCP, UDP e assim por diante. O soquete fornece classes específicas para manipular os
transportes comuns, bem como uma interface genérica para manipular o restante.

Soquetes tem seu próprio vocabulário -

Sr. Termo e Descrição


Não.

domínio

1 A família de protocolos que será usada como mecanismo de transporte. Esses


valores são constantes, como PF_INET, PF_UNIX, PF_X25 e assim por diante.

tipo

O tipo de comunicação entre os dois pontos de extremidade, geralmente


2
SOCK_STREAM para protocolos orientados a conexão e SOCK_DGRAM para
protocolos sem conexão.

protocolo

3 Normalmente zero, isso pode ser usado para identificar uma variante de um
protocolo dentro de um domínio e tipo.
nome de anfitrião

O identificador de uma interface de rede -

Uma string, que pode ser um nome de host, um endereço com quatro pontos ou
um endereço IPV6 na notação de dois-pontos (e possivelmente ponto)
4
Uma string "<broadcast>", que especifica um endereço INADDR_BROADCAST.

Uma cadeia de comprimento zero, que especifica INADDR_ANY ou

Um Integer, interpretado como um endereço binário na ordem de bytes do host.

porta

Cada servidor escuta os clientes que ligam em uma ou mais portas. Uma porta
5
pode ser um número de porta Fixnum, uma cadeia contendo um número de porta
ou o nome de um serviço.

Aqui vamos escrever um programa cliente muito simples, que abrirá uma conexão com uma
determinada porta e um determinado host. A classe Ruby TCPSocket fornece uma função
aberta para abrir esse soquete.

O TCPSocket.open (hosname, port) abre uma conexão TCP para o hostname na porta .

Depois de ter um soquete aberto, você pode ler como qualquer objeto IO. Quando terminar,
lembre-se de fechá-lo, pois você fecharia um arquivo.

O código a seguir é um cliente muito simples que se conecta a um determinado host e


porta, lê qualquer dado disponível do soquete e sai -

require 'socket' # Sockets are in standard library

hostname = 'localhost'
port = 2000

s = TCPSocket.open(hostname, port)

while line = s.gets # Read lines from the socket


puts line.chop # And print with platform line terminator
end
s.close # Close the socket when done

Para gravar servidores da Internet, usamos a classe TCPServer . Um objeto TCPServer é


uma fábrica para objetos TCPSocket.

Agora, chame TCPServer.open (hostname, port function para especificar uma porta para
seu serviço e criar um objeto TCPServer .

Em seguida, chamar a aceitar método do objeto TCPServer retornado. Esse método aguarda
até que um cliente se conecte à porta especificada e, em seguida, retorna um objeto
TCPSocket que representa a conexão com esse cliente.

require 'socket' # Get sockets from stdlib

server = TCPServer.open(2000) # Socket to listen on port 2000


loop { # Servers run forever
client = server.accept # Wait for a client to connect
client.puts(Time.now.ctime) # Send the time to the client
client.puts "Closing the connection. Bye!"
client.close # Disconnect from the client
}

Agora, execute este servidor em segundo plano e, em seguida, execute o cliente acima para
ver o resultado.

A maioria dos servidores na Internet é projetada para lidar com um grande número de
clientes a qualquer momento.

A classe Thread de Ruby facilita a criação de um servidor multithread.one que aceita


solicitações e cria imediatamente um novo thread de execução para processar a conexão
enquanto permite que o programa principal aguarde mais conexões -

require 'socket' # Get sockets from stdlib

server = TCPServer.open(2000) # Socket to listen on port 2000


loop { # Servers run forever
Thread.start(server.accept) do |client|
client.puts(Time.now.ctime) # Send the time to the client
client.puts "Closing the connection. Bye!"
client.close # Disconnect from the client
end
}

Neste exemplo, você tem um loop permanente e, quando server.accept responde, um novo
thread é criado e iniciado imediatamente para manipular a conexão que acaba de ser aceita,
usando o objeto de conexão passado para o thread. No entanto, o programa principal
retorna imediatamente e aguarda novas conexões.

Usar Ruby Thread dessa forma significa que o código é portátil e será executado da mesma
maneira no Linux, OS X e Windows.

Podemos usar a biblioteca de sockets para implementar qualquer protocolo da Internet.


Aqui, por exemplo, é um código para buscar o conteúdo de uma página da web -
require 'socket'

host = 'www.tutorialspoint.com' # The web server


port = 80 # Default HTTP port
path = "/index.htm" # The file we want

# This is the HTTP request we send to fetch a file


request = "GET #{path} HTTP/1.0\r\n\r\n"

socket = TCPSocket.open(host,port) # Connect to server


socket.print(request) # Send request
response = socket.read # Read complete response
# Split response at first blank line into headers and body
headers,body = response.split("\r\n\r\n", 2)
print body # And display it

Para implementar o Web client similar, você pode usar uma biblioteca pré-construída como o
Net :: HTTP para trabalhar com HTTP. Aqui está o código que faz o equivalente ao código
anterior -

require 'net/http' # The library we need


host = 'www.tutorialspoint.com' # The web server
path = '/index.htm' # The file we want

http = Net::HTTP.new(host) # Create a connection


headers, body = http.get(path) # Request the file
if headers.code == "200" # Check the status code
print body
else
puts "#{headers.code} #{headers.message}"
end

Por favor, verifique bibliotecas semelhantes para trabalhar com protocolos FTP, SMTP, POP e
IMAP.

Nós demos-lhe um início rápido na programação do soquete. É um assunto grande, por isso
é recomendado que você vá através da Ruby Socket Library e Class Methods para
encontrar mais detalhes.

A XML (Extensible Markup Language) é uma linguagem de marcação muitoO que é XML?
semelhante a HTML ou SGML. Isso é recomendado pelo World Wide Web
Consortium e disponível como padrão aberto.

XML é uma linguagem de código aberto e portátil que permite aos programadores
desenvolver aplicativos que podem ser lidos por outros aplicativos, independentemente do
sistema operacional e / ou da linguagem de desenvolvimento.

O XML é extremamente útil para rastrear quantidades pequenas a médias de dados sem
exigir um backbone baseado em SQL.
Existem dois sabores diferentes disponíveis para analisadores XML -

SAX-like (interfaces de fluxo) - Aqui você registra callbacks para eventos de


interesse e então deixa o analisador prosseguir através do documento. Isso é útil
quando seus documentos são grandes ou você tem limitações de memória, analisa o
arquivo como ele lê do disco e o arquivo inteiro nunca é armazenado na memória.

DOM-like (Object tree interfaces) - Esta é uma recomendação do World Wide


Web Consortium, na qual o arquivo inteiro é lido na memória e armazenado em um
formulário hierárquico (baseado em árvore) para representar todos os recursos de
um documento XML.

O SAX obviamente não pode processar informações tão rápido quanto o DOM ao trabalhar
com arquivos grandes. Por outro lado, usar o DOM exclusivamente pode realmente matar
seus recursos, especialmente se usado em muitos arquivos pequenos.

SAX é somente leitura, enquanto o DOM permite alterações no arquivo XML. Como essas
duas APIs diferentes literalmente se complementam, não há motivo para que você não
possa usá-las para grandes projetos.

A maneira mais comum de manipular XML é com a biblioteca REXML por Sean Russell.
Desde 2002, o REXML faz parte da distribuição padrão do Ruby.

O REXML é um processador XML pure-Ruby em conformidade com o padrão XML 1.0. É um


processador sem validação , passando em todos os testes de conformidade de não validação
do OASIS.

O analisador de REXML tem as seguintes vantagens sobre outros analisadores disponíveis -

Está escrito 100% em Ruby.

Pode ser usado para análise de SAX e DOM.

É leve, menos de 2000 linhas de código.

Métodos e classes são realmente fáceis de entender.

API baseada em SAX2 e suporte total ao XPath.

Fornecido com instalação Ruby e nenhuma instalação separada é necessária.

Para todos os nossos exemplos de código XML, vamos usar um arquivo XML simples como
uma entrada -

<collection shelf = "New Arrivals">


<movie title = "Enemy Behind">
<type>War, Thriller</type>
<format>DVD</format>
<year>2003</year>
<rating>PG</rating>
<stars>10</stars>
<description>Talk about a US-Japan war</description>
</movie>
<movie title = "Transformers">
<type>Anime, Science Fiction</type>
<format>DVD</format>
<year>1989</year>
<rating>R</rating>
<stars>8</stars>
<description>A schientific fiction</description>
</movie>
<movie title = "Trigun">
<type>Anime, Action</type>
<format>DVD</format>
<episodes>4</episodes>
<rating>PG</rating>
<stars>10</stars>
<description>Vash the Stampede!</description>
</movie>
<movie title = "Ishtar">
<type>Comedy</type>
<format>VHS</format>
<rating>PG</rating>
<stars>2</stars>
<description>Viewable boredom</description>
</movie>
</collection>

Vamos primeiro analisar nossos dados XML em forma de árvore . Começamos exigindo a
biblioteca rexml / document ; muitas vezes fazemos um include REXML para importar
para o namespace de nível superior por conveniência.

#!/usr/bin/ruby -w

require 'rexml/document'
include REXML

xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)

# Now get the root element


root = xmldoc.root
puts "Root element : " + root.attributes["shelf"]

# This will output all the movie titles.


xmldoc.elements.each("collection/movie"){
|e| puts "Movie Title : " + e.attributes["title"]
}

# This will output all the movie types.


xmldoc.elements.each("collection/movie/type") {
|e| puts "Movie Type : " + e.text
}
# This will output all the movie description.
xmldoc.elements.each("collection/movie/description") {
|e| puts "Movie Description : " + e.text
}

Isso produzirá o seguinte resultado -

Root element : New Arrivals


Movie Title : Enemy Behind
Movie Title : Transformers
Movie Title : Trigun
Movie Title : Ishtar
Movie Type : War, Thriller
Movie Type : Anime, Science Fiction
Movie Type : Anime, Action
Movie Type : Comedy
Movie Description : Talk about a US-Japan war
Movie Description : A schientific fiction
Movie Description : Vash the Stampede!
Movie Description : Viewable boredom

Para processar os mesmos dados, filmes.xml , arquivo de uma maneira orientada a fluxo ,
definiremos uma classe de ouvinte cujos métodos serão o destino dos retornos de chamada
do analisador.

OBSERVAÇÃO : não é recomendável usar a análise parecida com o SAX para um arquivo
pequeno, isso é apenas para um exemplo de demonstração.

#!/usr/bin/ruby -w

require 'rexml/document'
require 'rexml/streamlistener'
include REXML

class MyListener
include REXML::StreamListener
def tag_start(*args)
puts "tag_start: #{args.map {|x| x.inspect}.join(', ')}"
end

def text(data)
return if data =~ /^\w*$/ # whitespace only
abbrev = data[0..40] + (data.length > 40 ? "..." : "")
puts " text : #{abbrev.inspect}"
end
end

list = MyListener.new
xmlfile = File.new("movies.xml")
Document.parse_stream(xmlfile, list)

Isso produzirá o seguinte resultado -


tag_start: "collection", {"shelf"=>"New Arrivals"}
tag_start: "movie", {"title"=>"Enemy Behind"}
tag_start: "type", {}
text : "War, Thriller"
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
text : "Talk about a US-Japan war"
tag_start: "movie", {"title"=>"Transformers"}
tag_start: "type", {}
text : "Anime, Science Fiction"
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
text : "A schientific fiction"
tag_start: "movie", {"title"=>"Trigun"}
tag_start: "type", {}
text : "Anime, Action"
tag_start: "format", {}
tag_start: "episodes", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
text : "Vash the Stampede!"
tag_start: "movie", {"title"=>"Ishtar"}
tag_start: "type", {}
tag_start: "format", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
text : "Viewable boredom"

Uma maneira alternativa de visualizar o XML é o XPath. Esse é um tipo de pseudo-


linguagem que descreve como localizar elementos e atributos específicos em um documento
XML, tratando esse documento como uma árvore ordenada lógica.

O REXML tem suporte a XPath por meio da classe XPath . Ele pressupõe a análise baseada
em árvore (modelo de objeto de documento) como vimos acima.

#!/usr/bin/ruby -w
require 'rexml/document'
include REXML

xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)

# Info for the first movie found


movie = XPath.first(xmldoc, "//movie")
p movie

# Print out all the movie types


XPath.each(xmldoc, "//type") { |e| puts e.text }

# Get an array of all of the movie formats.


names = XPath.match(xmldoc, "//format").map {|x| x.text }
p names

Isso produzirá o seguinte resultado -

<movie title = 'Enemy Behind'> ... </>


War, Thriller
Anime, Science Fiction
Anime, Action
Comedy
["DVD", "DVD", "DVD", "VHS"]

Existem dois analisadores XSLT disponíveis que o Ruby pode usar. Uma breve descrição de
cada um é dada aqui.

Este analisador é escrito e mantido por Masayoshi Takahashi. Isso é escrito principalmente
para o Linux OS e requer as seguintes bibliotecas -

Sablot

Iconv

Expat

Você pode encontrar este módulo em Ruby-Sablotron .

O XSLT4R é escrito por Michael Neumann e pode ser encontrado no RAA na seção Library
em XML. O XSLT4R usa uma interface de linha de comando simples, embora possa ser
usado alternativamente em um aplicativo de terceiros para transformar um documento XML.

O XSLT4R precisa que o XMLScan opere, que está incluído no arquivo XSLT4R e que também
é um módulo 100 por cento Ruby. Esses módulos podem ser instalados usando o método de
instalação padrão do Ruby (por exemplo, ruby install.rb).
XSLT4R possui a seguinte sintaxe -

ruby xslt.rb stylesheet.xsl document.xml [arguments]

Se você quiser usar o XSLT4R dentro de um aplicativo, você pode incluir o XSLT e inserir os
parâmetros necessários. Aqui está o exemplo -

require "xslt"

stylesheet = File.readlines("stylesheet.xsl").to_s
xml_doc = File.readlines("document.xml").to_s
arguments = { 'image_dir' => '/....' }
sheet = XSLT::Stylesheet.new( stylesheet, arguments )

# output to StdOut
sheet.apply( xml_doc )

# output to 'str'
str = ""
sheet.output = [ str ]
sheet.apply( xml_doc )

Para obter detalhes completos sobre o REXML Parser, consulte aLeitura Adicional
documentação padrão da documentação do REXML Parser .

Você pode baixar o XSLT4R do Repositório RAA .

O protocolo SOAP (Simple Object Access Protocol) é um protocolo RPC de plataforma


cruzada e independente de linguagem baseado em XML e, geralmente (mas não
necessariamente) HTTP.

Ele usa XML para codificar as informações que fazem a chamada de procedimento remoto e
HTTP para transportar essas informações através de uma rede de clientes para servidores e
vice-versa.

O SOAP tem várias vantagens sobre outras tecnologias como COM, CORBA, etc: por
exemplo, seus custos relativamente baixos de implantação e depuração, sua extensibilidade
e facilidade de uso, e a existência de várias implementações para diferentes linguagens e
plataformas.

Por favor, consulte o nosso tutorial simples SOAP para entendê-lo em detalhes.

Este capítulo familiariza você com a implementação do SOAP para Ruby (SOAP4R). Este é
um tutorial básico, portanto, se você precisar de um detalhe profundo, precisará consultar
outros recursos.
SOAP4R é a implementação SOAP para Ruby desenvolvida por Hiroshi Nakamura e pode ser
baixada de -

NOTA - Pode haver uma grande chance de você já ter instalado este componente.

Download SOAP

Se você está ciente do utilitário gem , então você pode usar o seguinte comando para
instalar o SOAP4R e os pacotes relacionados.

$ gem install soap4r --include-dependencies

Se você estiver trabalhando no Windows, será necessário fazer o download de um arquivo


zipado do local acima e precisar instalá-lo usando o método de instalação padrão
executando ruby install.rb .

O SOAP4R suporta dois tipos diferentes de servidores -

Baseado em CGI / FastCGI (SOAP :: RPC :: CGIStub)

Standalone (SOAP :: RPC: StandaloneServer)

Este capítulo fornece detalhes sobre como escrever um servidor autônomo. As etapas a
seguir estão envolvidas na gravação de um servidor SOAP.

Para implementar seu próprio servidor autônomo, você precisa escrever uma nova classe,
que será filha de SOAP :: StandaloneServer da seguinte maneira -

class MyServer < SOAP::RPC::StandaloneServer


...............
end

OBSERVAÇÃO - Se você quiser gravar um servidor baseado em FastCGI, será necessário


usar SOAP :: RPC :: CGIStub como classe pai; o restante do procedimento permanecerá o
mesmo.

O segundo passo é escrever seus métodos de Serviços da Web, que você gostaria de expor
ao mundo exterior.

Eles podem ser escritos como métodos simples de Ruby. Por exemplo, vamos escrever dois
métodos para adicionar dois números e dividir dois números -

class MyServer < SOAP::RPC::StandaloneServer


...............

# Handler methods
def add(a, b)
return a + b
end
def div(a, b)
return a / b
end
end

O próximo passo é adicionar nossos métodos definidos ao nosso servidor. O método initialize
é usado para expor métodos de serviço com um dos dois métodos a seguir -

class MyServer < SOAP::RPC::StandaloneServer


def initialize(*args)
add_method(receiver, methodName, *paramArg)
end
end

Aqui está a descrição dos parâmetros -

Sr. Parâmetro e Descrição


Não.

receptor

1 O objeto que contém o método methodName. Você define os métodos de serviço


na mesma classe que o método methodDef, esse parâmetro é self .

methodName
2
O nome do método que é chamado devido a uma solicitação de RPC.

paramArg

3 Especifica, quando fornecido, os nomes dos parâmetros e os modos de


parâmetros.

Para entender o uso de parâmetros inout ou out , considere o seguinte método de serviço
que usa dois parâmetros (inParam e inoutParam), retorna um valor de retorno normal
(retVal) e dois outros parâmetros: inoutParam e outParam -

def aMeth(inParam, inoutParam)


retVal = inParam + inoutParam
outParam = inParam . inoutParam
inoutParam = inParam * inoutParam
return retVal, inoutParam, outParam
end

Agora, podemos expor este método da seguinte forma -

add_method(self, 'aMeth', [
%w(in inParam),
%w(inout inoutParam),
%w(out outParam),
%w(retval return)
])

A etapa final é iniciar seu servidor instanciando uma instância da classe derivada e
chamando o método start .

myServer = MyServer.new('ServerName', 'urn:ruby:ServiceName', hostname, port)

myServer.start

Aqui está a descrição dos parâmetros necessários -

Sr. Parâmetro e Descrição


Não.

Nome do servidor
1
Um nome de servidor, você pode dar o que você mais gosta.

urn: ruby: ServiceName

2 Aqui urn: ruby é constante, mas você pode fornecer um nome exclusivo de
ServiceName para este servidor.

nome de anfitrião
3
Especifica o nome do host no qual este servidor irá escutar.

porta
4
Um número de porta disponível a ser usado para o serviço da web.

Agora, usando as etapas acima, vamos escrever um servidor autônomo -

require "soap/rpc/standaloneserver"

begin
class MyServer < SOAP::RPC::StandaloneServer

# Expose our services


def initialize(*args)
add_method(self, 'add', 'a', 'b')
add_method(self, 'div', 'a', 'b')
end
# Handler methods
def add(a, b)
return a + b
end
def div(a, b)
return a / b
end
end
server = MyServer.new("MyServer",
'urn:ruby:calculation', 'localhost', 8080)
trap('INT){
server.shutdown
}
server.start
rescue => err
puts err.message
end

Quando executado, este aplicativo do servidor inicia um servidor SOAP independente no


host local e atende a solicitações na porta 8080. Ele expõe um método de serviço, add e div
, que recebe dois parâmetros e retorna o resultado.

Agora, você pode executar este servidor em segundo plano da seguinte maneira -

$ ruby MyServer.rb&

A classe SOAP :: RPC :: Driver fornece suporte para gravar aplicativos cliente SOAP. Este
capítulo descreve essa classe e demonstra seu uso com base em um aplicativo.

A seguir está a informação mínima que você precisaria para chamar um serviço SOAP -

A URL do serviço SOAP (URL do terminal SOAP).

O namespace dos métodos de serviço (URI do Namespace do Método).

Os nomes dos métodos de serviço e seus parâmetros.

Agora, escreveremos um cliente SOAP que chamaria métodos de serviço definidos no


exemplo acima, chamados add e div .

Aqui estão as principais etapas para criar um cliente SOAP.

Criamos uma instância de SOAP :: RPC :: Driver chamando seu novo método da seguinte
maneira -

SOAP::RPC::Driver.new(endPoint, nameSpace, soapAction)

Aqui está a descrição dos parâmetros necessários -

Sr. Parâmetro e Descrição


Não.
endPoint
1
URL do servidor SOAP para se conectar.

namespace

2 O namespace a ser usado para todos os RPCs feitos com esse objeto SOAP :: RPC
:: Driver.

sabãoAção

3 Um valor para o campo SOAPAction do cabeçalho HTTP. Se nil, o padrão é a string


vazia "".

Para adicionar um método de serviço SOAP a um SOAP :: RPC :: Driver , podemos chamar o
seguinte método usando a instância SOAP :: RPC :: Driver -

driver.add_method(name, *paramArg)

Aqui está a descrição dos parâmetros -

Sr. Parâmetro e Descrição


Não.

nome
1
O nome do método de serviço da web remoto.

paramArg
2
Especifica os nomes dos parâmetros dos procedimentos remotos.

A etapa final é faturar o serviço SOAP usando a instância SOAP :: RPC :: Driver da seguinte
maneira -

result = driver.serviceMethod(paramArg...)

Aqui serviceMethod é o método de serviço web atual e paramArg ... são os parâmetros de
lista necessários para passar no método de serviço.

Exemplo

Com base nos passos acima, vamos escrever um cliente SOAP da seguinte forma -

#!/usr/bin/ruby -w
require 'soap/rpc/driver'

NAMESPACE = 'urn:ruby:calculation'
URL = 'http://localhost:8080/'

begin
driver = SOAP::RPC::Driver.new(URL, NAMESPACE)

# Add remote sevice methods


driver.add_method('add', 'a', 'b')

# Call remote service methods


puts driver.add(20, 30)
rescue => err
puts err.message
end

Eu expliquei apenas conceitos muito básicos de Web Services com Ruby. Se você quiser
aprofundá-lo ainda mais, há um link a seguir para encontrar mais detalhes sobre o Web
Services com Ruby .

A interface gráfica de usuário padrão (GUI) para Ruby é Tk. Tk começou como aIntrodução
GUI para a linguagem de script Tcl desenvolvida por John Ousterhout.

Tk tem a distinção única de ser a única GUI multiplataforma. O Tk é executado no Windows,


Mac e Linux e fornece uma aparência nativa em cada sistema operacional.

O componente básico de um aplicativo baseado em Tk é chamado de widget. Um


componente também é algumas vezes chamado de janela, uma vez que, em Tk, "janela" e
"widget" são freqüentemente usados de forma intercambiável.

Os aplicativos tk seguem uma hierarquia de widgets em que qualquer número de widgets


pode ser colocado dentro de outro widget e aqueles widgets dentro de outro widget, ad
infinitum. O widget principal em um programa Tk é referido como o widget raiz e pode ser
criado fazendo uma nova instância da classe TkRoot.

A maioria dos aplicativos baseados em Tk segue o mesmo ciclo: crie os widgets,


coloque-os na interface e, finalmente, ligue os eventos associados a cada widget a
um método.

Existem três gerenciadores de geometria; lugar, grade e pacote que são


responsáveis por controlar o tamanho e a localização de cada um dos widgets na
interface.

As ligações do Ruby Tk são distribuídas com o Ruby, mas o Tk é uma instalaçãoInstalação


separada. Os usuários do Windows podem baixar uma instalação Tk de um único
clique do ActiveTcl da ActiveState .

Os usuários de Mac e Linux podem não precisar instalá-lo, pois há uma grande chance de
que ele já esteja instalado junto com o SO, mas, se não, você pode baixar pacotes pré-
construídos ou obter o código-fonte do Tcl Developer Xchange .

Uma estrutura típica para programas Ruby / Tk é criar a janela principal ou raiz (uma
instância de TkRoot), adicionar widgets a ela para construir a interface do usuário e, em
seguida, iniciar o loop de eventos principal chamando Tk.mainloop .

O tradicional Olá, mundo! exemplo para Ruby / Tk é algo como isto -

require 'tk'

root = TkRoot.new { title "Hello, World!" }


TkLabel.new(root) do
text 'Hello, World!'
pack { padx 15 ; pady 15; side 'left' }
end
Tk.mainloop

Aqui, depois de carregar o módulo de extensão tk, criamos um quadro de nível raiz usando
TkRoot.new . Em seguida, criamos um widget TkLabel como filho do quadro raiz, definindo
várias opções para o rótulo. Por fim, empacotamos o quadro raiz e inserimos o loop de
eventos da GUI principal.

Se você executasse este script, produziria o seguinte resultado -

Há uma lista de várias classes Ruby / Tk, que podem ser usadas para criar uma GUI
desejada usando Ruby / Tk.

TkFrame Cria e manipula widgets de quadros.

TkButton Cria e manipula widgets de botões.

TkLabel Cria e manipula widgets de rótulo.

TkEntry Cria e manipula widgets de entrada.

TkCheckButton Cria e manipula widgets de check-button.

TkRadioButton Cria e manipula widgets de radiobutton.


TkListbox Cria e manipula widgets de caixas de listagem.

TkComboBox Cria e manipula widgets de caixas de listagem.

TkMenu Cria e manipula widgets de menu.

TkMenubutton Cria e manipula widgets de submenu.

Tk.messageBox Cria e manipula um diálogo de mensagem.

TkScrollbar Cria e manipula widgets da barra de rolagem.

TkCanvas Cria e manipula widgets de tela.

TkScale Cria e manipula widgets de escala.

TkText Cria e manipula widgets de texto.

TkToplevel Cria e manipula widgets de nível superior.

TkSpinbox Cria e manipula widgets Spinbox.

TkProgressBar Cria e manipula widgets da barra de progresso.

Caixa de Diálogo Cria e manipula os widgets da Caixa de Diálogo.

Tk :: Tile :: Notebook Exibe várias janelas em espaço limitado com a metáfora do


notebook.

Tk :: Tile :: Paned Exibe um número de subjanelas, empilhadas na vertical ou na


horizontal.

Tk :: Tile :: Separator Exibe uma barra separadora horizontal ou vertical.

Ruby / Tk Font, cores e imagens Noções básicas sobre fontes Ruby / Tk, cores e
imagens

Todos os widgets possuem várias opções de configuração diferentes, que geralmente


controlam como elas são exibidas ou como elas se comportam. As opções disponíveis
dependem da classe do widget, é claro.

Aqui está uma lista de todas as opções de configuração padrão, que podem ser aplicáveis a
qualquer widget Ruby / Tk.

Existem outras opções específicas do widget, que seriam explicadas junto com os
widgets.

O Geometry Management lida com o posicionamento de diferentes widgets conforme o


requisito. O gerenciamento de geometria no Tk depende do conceito de widgets mestre e
escravo.

Um mestre é um widget, geralmente uma janela de nível superior ou um quadro, que


conterá outros widgets, chamados de escravos. Você pode imaginar um gerenciador de
geometria assumindo o controle do widget principal e decidindo o que será exibido nele.

O gerenciador de geometria perguntará a cada tamanho de widget de cada escravo, ou


quão grande seria ideal para ser exibido. Em seguida, ele pega essa informação e a combina
com quaisquer parâmetros fornecidos pelo programa quando ele pede ao gerenciador de
geometria para gerenciar esse widget escravo em particular.

Existem três gerentes de geometria place, grid e pack que são responsáveis por controlar o
tamanho e a localização de cada um dos widgets na interface.

grid Gerenciador de geometria que organiza widgets em uma grade.

embalar gerente geometria que as embalagens em torno das bordas da cavidade.

coloque o gerenciador de geometria para posicionamento fixo ou de folha de


borracha.

Ruby / Tk suporta o loop de eventos , que recebe eventos do sistema operacional. Essas são
coisas como pressionamentos de botões, pressionamentos de tecla, movimento do mouse,
redimensionamento de janela e assim por diante.

Ruby / Tk cuida de gerenciar este evento para você. Ele irá descobrir em qual widget o
evento se aplica (o usuário clicou neste botão? Se uma tecla foi pressionada, qual caixa de
texto tinha o foco?), E despacha-a de acordo. Os widgets individuais sabem como responder
aos eventos, portanto, por exemplo, um botão pode mudar de cor quando o mouse se move
sobre ele e reverter quando o mouse sai.

Em um nível mais alto, Ruby / Tk invoca callbacks em seu programa para indicar que algo
significativo aconteceu em um widget. Para ambos os casos, você pode fornecer um bloco
de código ou um objeto Ruby Proc que especifica como o aplicativo responde ao evento ou
callback.

Vamos dar uma olhada em como usar o método bind para associar eventos básicos do
sistema de janelas com os procedimentos Ruby que os manipulam. A forma mais simples de
ligação recebe como entrada uma string indicando o nome do evento e um bloco de código
que o Tk usa para manipular o evento.

Por exemplo, para capturar o evento ButtonRelease para o primeiro botão do mouse em
algum widget, você escreveria -

someWidget.bind('ButtonRelease-1') {
....code block to handle this event...
}

Um nome de evento pode incluir modificadores e detalhes adicionais. Um modificador é uma


string como Shift , Control ou Alt , indicando que uma das teclas modificadoras foi
pressionada.

Assim, por exemplo, para capturar o evento que é gerado quando o usuário mantém
pressionada a tecla Ctrl e clica no botão direito do mouse.

someWidget.bind('Control-ButtonPress-3', proc { puts "Ouch!" })

Muitos widgets Ruby / Tk podem acionar retornos de chamada quando o usuário os ativa, e
você pode usar o retorno de chamada do comando para especificar que um determinado
bloco de código ou procedimento é invocado quando isso acontece. Como visto
anteriormente, você pode especificar o procedimento de retorno de chamada do comando
ao criar o widget -

helpButton = TkButton.new(buttonFrame) {
text "Help"
command proc { showHelp }
}

Ou você pode atribuí-lo mais tarde, usando o método de comando do widget -

helpButton.command proc { showHelp }

Como o método de comando aceita procedimentos ou blocos de código, você também pode
escrever o exemplo de código anterior como -

helpButton = TkButton.new(buttonFrame) {
text "Help"
command { showHelp }
}

Você pode usar os seguintes tipos básicos de eventos em seu aplicativo Ruby / Tk -

O método configure pode ser usado para definir e recuperar quaisquer valores de
configuração do widget. Por exemplo, para alterar a largura de um botão, você pode chamar
o método configure a qualquer momento da seguinte forma:

require "tk"

button = TkButton.new {
text 'Hello World!'
pack
}
button.configure('activebackground', 'blue')
Tk.mainloop
Para obter o valor de um widget atual, basta fornecê-lo sem um valor da seguinte forma:

color = button.configure('activebackground')

Você também pode chamar o configure sem nenhuma opção, o que lhe dará uma listagem
de todas as opções e seus valores.

Para simplesmente recuperar o valor de uma opção, configure retorna mais informações do
que geralmente deseja. O método cget retorna apenas o valor atual.

color = button.cget('activebackground')

Ruby / LDAP é uma biblioteca de extensões para Ruby. Ele fornece a interface para algumas
bibliotecas LDAP, como OpenLDAP, UMich LDAP, Netscape SDK e ActiveDirectory.

A API comum para desenvolvimento de aplicativos é descrita no RFC1823 e é suportada


pelo Ruby / LDAP.

Você pode baixar e instalar um pacote Ruby / LDAP completo em SOURCEFORGE.NET .

Antes de instalar o Ruby / LDAP, certifique-se de ter os seguintes componentes -

Ruby 1.8.x (pelo menos 1.8.2 se você quiser usar o ldap / control).

OpenLDAP, Netscape SDK, Windows 2003 ou Windows XP.

Agora, você pode usar o método padrão de instalação do Ruby. Antes de começar, se você
quiser ver as opções disponíveis para o extconf.rb, execute-o com a opção '--help'.

$ ruby extconf.rb [--with-openldap1|--with-openldap2| \


--with-netscape|--with-wldap32]
$ make
$ make install

OBSERVAÇÃO : se você estiver criando o software no Windows, talvez seja necessário usar
o nmake em vez do make .

Este é um processo de duas etapas -

A seguir está a sintaxe para criar uma conexão com um diretório LDAP.
LDAP::Conn.new(host = 'localhost', port = LDAP_PORT)

host - Esse é o ID do host que está executando o diretório LDAP. Nós vamos levá-lo
como localhost .

porta - esta é a porta que está sendo usada para o serviço LDAP. As portas LDAP
padrão são 636 e 389. Verifique se a porta está sendo usada em seu servidor, caso
contrário, você poderá usar LDAP :: LDAP_PORT.

Esta chamada retorna uma nova conexão LDAP :: Conn para o servidor, host , na porta da
porta .

É aqui que geralmente especificamos o nome de usuário e a senha que usaremos para o
restante da sessão.

A seguir está a sintaxe para vincular uma conexão LDAP, usando o método DN, dn ,
credential, pwd e bind, método -

conn.bind(dn = nil, password = nil, method = LDAP::LDAP_AUTH_SIMPLE)do


....
end

Você pode usar o mesmo método sem um bloco de código. Nesse caso, você precisaria
desvincular a conexão explicitamente da seguinte maneira -

conn.bind(dn = nil, password = nil, method = LDAP::LDAP_AUTH_SIMPLE)


....
conn.unbind

Se um bloco de código é dado, o self é cedido ao bloco.

Agora podemos realizar buscas, adicionar, modificar ou excluir operações dentro do bloco do
método bind (entre bind e unbind), desde que tenhamos as permissões apropriadas.

Exemplo

Assumindo que estamos trabalhando em um servidor local, vamos colocar as coisas em


conjunto com o host, domínio, id de usuário e senha apropriados, etc.

#/usr/bin/ruby -w

require 'ldap'

$HOST = 'localhost'
$PORT = LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)


conn.bind('cn = root, dc = localhost, dc = localdomain','secret')
....
conn.unbind
Adicionar uma entrada LDPA é um processo de duas etapas -

Precisamos passar o objeto LDAP :: Mod para o método conn.add para criar uma entrada.
Aqui está uma sintaxe simples para criar o objeto LDAP :: Mod -

Mod.new(mod_type, attr, vals)

mod_type - Uma ou mais opções LDAP_MOD_ADD, LDAP_MOD_REPLACE ou


LDAP_MOD_DELETE.

attr - deve ser o nome do atributo no qual operar.

vals - é uma matriz de valores pertencentes ao attr . Se vals contiver dados


binários, mod_type deve ser logicamente OR'ed (|) com LDAP_MOD_BVALUES.

Essa chamada retorna o objeto LDAP :: Mod , que pode ser passado para os métodos da
classe LDAP :: Conn, como Conn # add, Conn # add_ext, Conn # modify e Conn #
modify_ext.

Quando estivermos prontos com o objeto LDAP :: Mod , podemos chamar o método
conn.add para criar uma entrada. Aqui está uma sintaxe para chamar esse método -

conn.add(dn, attrs)

Este método adiciona uma entrada com o DN, dn e os atributos attrs . Aqui, attrs deve ser
uma matriz de objetos LDAP :: Mod ou um hash de pares de matriz de atributo / valor.

Exemplo

Aqui está um exemplo completo, que criará duas entradas de diretório -

#/usr/bin/ruby -w

require 'ldap'

$HOST = 'localhost'
$PORT = LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)


conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
entry1 = [
LDAP.mod(LDAP::LDAP_MOD_ADD,'objectclass',['top','domain']),
LDAP.mod(LDAP::LDAP_MOD_ADD,'o',['TTSKY.NET']),
LDAP.mod(LDAP::LDAP_MOD_ADD,'dc',['localhost']),
]
entry2 = [
LDAP.mod(LDAP::LDAP_MOD_ADD,'objectclass',['top','person']),
LDAP.mod(LDAP::LDAP_MOD_ADD, 'cn', ['Zara Ali']),
LDAP.mod(LDAP::LDAP_MOD_ADD | LDAP::LDAP_MOD_BVALUES, 'sn',
['ttate','ALI', "zero\000zero"]),
]

begin
conn.add("dc = localhost, dc = localdomain", entry1)
conn.add("cn = Zara Ali, dc = localhost, dc = localdomain", entry2)
rescue LDAP::ResultError
conn.perror("add")
exit
end
conn.perror("add")
conn.unbind

Modificar uma entrada é semelhante a adicionar uma. Apenas chame o método modify em
vez de adicionar com os atributos para modificar. Aqui está uma sintaxe simples do método
de modificação .

conn.modify(dn, mods)

Este método modifica uma entrada com o DN, dn e os atributos mods . Aqui, os mods
devem ser uma matriz de objetos LDAP :: Mod ou um hash de pares de matriz de atributo /
valor.

Para modificar o sobrenome da entrada, que adicionamos na seção anterior, escreveríamos:

#/usr/bin/ruby -w

require 'ldap'

$HOST = 'localhost'
$PORT = LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)


conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
entry1 = [
LDAP.mod(LDAP::LDAP_MOD_REPLACE, 'sn', ['Mohtashim']),
]

begin
conn.modify("cn = Zara Ali, dc = localhost, dc = localdomain", entry1)
rescue LDAP::ResultError
conn.perror("modify")
exit
end
conn.perror("modify")
conn.unbind
Para excluir uma entrada, chame o método delete com o nome distinto como parâmetro.
Aqui está uma sintaxe simples do método delete .

conn.delete(dn)

Este método exclui uma entrada com o DN, dn .

Para excluir a entrada Zara Mohtashim , que adicionamos na seção anterior, escreveríamos:

#/usr/bin/ruby -w

require 'ldap'

$HOST = 'localhost'
$PORT = LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)


conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
begin
conn.delete("cn = Zara-Mohtashim, dc = localhost, dc = localdomain")
rescue LDAP::ResultError
conn.perror("delete")
exit
end
conn.perror("delete")
conn.unbind

Não é possível modificar o nome distinto de uma entrada com o método de modificação .
Em vez disso, use o método modrdn . Aqui está a sintaxe simples do método modrdn -

conn.modrdn(dn, new_rdn, delete_old_rdn)

Este método modifica o RDN da entrada com DN, dn , dando a ele o novo RDN, new_rdn .
Se delete_old_rdn for true , o valor RDN antigo será excluído da entrada.

Suponha que tenhamos a seguinte entrada -

dn: cn = Zara Ali,dc = localhost,dc = localdomain


cn: Zara Ali
sn: Ali
objectclass: person

Então, podemos modificar seu nome distinto com o seguinte código -

#/usr/bin/ruby -w
require 'ldap'

$HOST = 'localhost'
$PORT = LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT)


conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
begin
conn.modrdn("cn = Zara Ali, dc = localhost, dc = localdomain", "cn = Zara Mohtashim", true)
rescue LDAP::ResultError
conn.perror("modrdn")
exit
end
conn.perror("modrdn")
conn.unbind

Para realizar uma pesquisa em um diretório LDAP, use o método de pesquisa com um dos
três modos de pesquisa diferentes -

LDAP_SCOPE_BASEM - Pesquisar apenas o nó base.

LDAP_SCOPE_ONELEVEL - Pesquisar todos os filhos do nó base.

LDAP_SCOPE_SUBTREE - Pesquisar a subárvore inteira, incluindo o nó base.

Aqui, vamos pesquisar toda a subárvore de entrada dc = localhost, dc = localdomain para


objetos de pessoa -

#/usr/bin/ruby -w

require 'ldap'

$HOST = 'localhost'
$PORT = LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT

base = 'dc = localhost,dc = localdomain'


scope = LDAP::LDAP_SCOPE_SUBTREE
filter = '(objectclass = person)'
attrs = ['sn', 'cn']

conn = LDAP::Conn.new($HOST, $PORT)


conn.bind('cn = root, dc = localhost, dc = localdomain','secret')

conn.perror("bind")
begin
conn.search(base, scope, filter, attrs) { |entry|
# print distinguished name
p entry.dn
# print all attribute names
p entry.attrs
# print values of attribute 'sn'
p entry.vals('sn')
# print entry as Hash
p entry.to_hash
}
rescue LDAP::ResultError
conn.perror("search")
exit
end
conn.perror("search")
conn.unbind

Isso invoca o bloco de código fornecido para cada entrada correspondente em que a entrada
LDAP é representada por uma instância da classe LDAP :: Entry. Com o último parâmetro de
pesquisa, você pode especificar os atributos nos quais está interessado, omitindo todos os
outros. Se você passar nulo aqui, todos os atributos serão retornados da mesma forma que
"SELECT *" nos bancos de dados relacionais.

O método dn (alias para get_dn) da classe LDAP :: Entry retorna o nome distinto da
entrada, e com o método to_hash, você pode obter uma representação hash de seus
atributos (incluindo o nome distinto). Para obter uma lista dos atributos de uma entrada,
use o método attrs (alias para get_attributes). Além disso, para obter a lista de valores de
um atributo específico, use o método vals (alias para get_values).

Ruby / LDAP define duas classes de exceção diferentes - Manipulando Erros

Em caso de erro, os métodos new, bind ou unbind levantam uma exceção LDAP ::
Error.

Em caso de adicionar, modificar, excluir ou pesquisar um diretório LDAP, crie um


LDAP :: ResultError.

Para obter detalhes completos sobre métodos LDAP, consulte aLeitura Adicional
documentação padrão da documentação do LDAP .

Os programas tradicionais têm um único encadeamento de execução, as instruções ou


instruções que compõem o programa são executadas seqüencialmente até o término do
programa.

Um programa multithread tem mais de um thread de execução. Dentro de cada thread, as


instruções são executadas sequencialmente, mas os próprios threads podem ser executados
em paralelo em uma CPU multicore, por exemplo. Geralmente, em uma única máquina de
CPU, vários encadeamentos não são realmente executados em paralelo, mas o paralelismo é
simulado pela intercalação da execução dos encadeamentos.

Ruby facilita a escrita de programas multi-thread com a classe Thread . Os encadeamentos


Ruby são uma maneira leve e eficiente de obter simultaneidade em seu código.
Para iniciar um novo thread, associe um bloco a uma chamada para Thread.new . Um novo
thread será criado para executar o código no bloco, e o thread original retornará de
Thread.new imediatamente e retomará a execução com a próxima instrução -

# Thread #1 is running here


Thread.new {
# Thread #2 runs this code
}
# Thread #1 runs this code

Aqui está um exemplo, que mostra como podemos usar o programa Ruby multi-threaded.

#!/usr/bin/ruby

def func1
i = 0
while i<=2
puts "func1 at: #{Time.now}"
sleep(2)
i = i+1
end
end

def func2
j = 0
while j<=2
puts "func2 at: #{Time.now}"
sleep(1)
j = j+1
end
end

puts "Started At #{Time.now}"


t1 = Thread.new{func1()}
t2 = Thread.new{func2()}
t1.join
t2.join
puts "End at #{Time.now}"

Isto irá produzir o resultado seguinte -

Started At Wed May 14 08:21:54 -0700 2008


func1 at: Wed May 14 08:21:54 -0700 2008
func2 at: Wed May 14 08:21:54 -0700 2008
func2 at: Wed May 14 08:21:55 -0700 2008
func1 at: Wed May 14 08:21:56 -0700 2008
func2 at: Wed May 14 08:21:56 -0700 2008
func1 at: Wed May 14 08:21:58 -0700 2008
End at Wed May 14 08:22:00 -0700 2008
Um novos segmentos são criados com Thread.new . Você também pode usar os sinônimos
Thread.start e Thread.fork .

Não há necessidade de iniciar um thread após criá-lo, ele começa a ser executado
automaticamente quando os recursos da CPU se tornam disponíveis.

A classe Thread define vários métodos para consultar e manipular o encadeamento


enquanto ele está em execução. Um thread executa o código no bloco associado à chamada
para Thread.new e, em seguida, ele para de executar.

O valor da última expressão nesse bloco é o valor do encadeamento e pode ser obtido
chamando o método de valor do objeto Thread. Se o encadeamento tiver sido executado até
a conclusão, o valor retornará o valor do encadeamento imediatamente. Caso contrário, o
método value é bloqueado e não retorna até que o encadeamento seja concluído.

O método de classe Thread.current retorna o objeto Thread que representa o segmento


atual. Isso permite que os threads se manipulem. O método de classe Thread.main retorna
o objeto Thread que representa o thread principal. Este é o thread inicial de execução que
começou quando o programa Ruby foi iniciado.

Você pode esperar que um segmento específico termine chamando o método Thread.join
desse segmento . O segmento de chamada irá bloquear até que o segmento determinado
seja concluído.

Se uma exceção é levantada no thread principal e não é tratada em lugar algum, o


interpretador Ruby imprime uma mensagem e sai. Em encadeamentos, além do segmento
principal, as exceções não tratadas fazem com que o encadeamento pare de ser executado.

Se um encadeamento t sair devido a uma exceção não tratada e outro encadeamento s


chamar t.join ou t.value, a exceção ocorrida em t será levantada no encadeamento s .

Se Thread.abort_on_exception for false , a condição padrão, uma exceção não tratada


simplesmente mata o thread atual e todo o resto continua a ser executado.

Se você quiser que qualquer exceção não tratada em qualquer thread faça com que o
intérprete saia, defina o método de classe Thread.abort_on_exception como true .

t = Thread.new { ... }
t.abort_on_exception = true

Um thread pode acessar normalmente as variáveis que estão no escopo quando o thread é
criado. Variáveis locais para o bloco de um segmento são locais para o segmento e não são
compartilhadas.

A classe de encadeamento apresenta um recurso especial que permite que variáveis locais
de encadeamento sejam criadas e acessadas pelo nome. Você simplesmente trata o objeto
thread como se fosse um hash, escrevendo para elementos usando [] = e lendo-os de volta
usando [].

Neste exemplo, cada thread registra o valor atual da contagem de variáveis em uma
variável threadlocal com a chave mycount .

#!/usr/bin/ruby

count = 0
arr = []

10.times do |i|
arr[i] = Thread.new {
sleep(rand(0)/10.0)
Thread.current["mycount"] = count
count += 1
}
end

arr.each {|t| t.join; print t["mycount"], ", " }


puts "count = #{count}"

Isso produz o seguinte resultado -

8, 0, 3, 7, 2, 1, 6, 5, 4, 9, count = 10

O thread principal aguarda que as sub-threads terminem e depois imprime o valor da


contagem capturada por cada uma.

O primeiro fator que afeta o planejamento de encadeamentos é a prioridade do


encadeamento: encadeamentos de alta prioridade são planejados antes de encadeamentos
de baixa prioridade. Mais precisamente, um encadeamento só terá tempo de CPU se não
houver encadeamentos de prioridade mais alta esperando para serem executados.

Você pode definir e consultar a prioridade de um objeto Ruby Thread com prioridade = e
prioridade . Um encadeamento recém-criado começa com a mesma prioridade que o
encadeamento que o criou. O thread principal começa na prioridade 0.

Não há como definir a prioridade de um thread antes de começar a execução. Um thread


pode, no entanto, aumentar ou diminuir sua própria prioridade como primeira ação.

Se dois encadeamentos compartilharem acesso aos mesmos dados e pelo menos um dos
encadeamentos modificar esses dados, você deverá tomar cuidado especial para garantir
que nenhum encadeamento possa ver os dados em um estado inconsistente. Isso é
chamado de exclusão de thread .

Mutex é uma classe que implementa um bloqueio de semáforo simples para acesso
mutuamente exclusivo a algum recurso compartilhado. Ou seja, apenas um thread pode
conter o bloqueio em um determinado momento. Outros segmentos podem optar por
esperar na fila para que o bloqueio fique disponível ou simplesmente optar por obter um
erro imediato, indicando que o bloqueio não está disponível.

Ao colocar todos os acessos aos dados compartilhados sob o controle de um mutex ,


garantimos consistência e operação atômica. Vamos tentar exemplos, primeiro sem mutax e
segundo com mutax -

#!/usr/bin/ruby
require 'thread'

count1 = count2 = 0
difference = 0
counter = Thread.new do
loop do
count1 += 1
count2 += 1
end
end
spy = Thread.new do
loop do
difference += (count1 - count2).abs
end
end
sleep 1
puts "count1 : #{count1}"
puts "count2 : #{count2}"
puts "difference : #{difference}"

Isso produzirá o seguinte resultado -

count1 : 1583766
count2 : 1583766
difference : 0

#!/usr/bin/ruby
require 'thread'
mutex = Mutex.new

count1 = count2 = 0
difference = 0
counter = Thread.new do
loop do
mutex.synchronize do
count1 += 1
count2 += 1
end
end
end
spy = Thread.new do
loop do
mutex.synchronize do
difference += (count1 - count2).abs
end
end
end
sleep 1
mutex.lock
puts "count1 : #{count1}"
puts "count2 : #{count2}"
puts "difference : #{difference}"

Isso produzirá o seguinte resultado -

count1 : 696591
count2 : 696591
difference : 0

Quando começamos a usar objetos Mutex para exclusão de encadeamentos, devemos ter
cuidado para evitar o deadlock . Deadlock é a condição que ocorre quando todos os threads
estão aguardando para adquirir um recurso mantido por outro thread. Como todos os
encadeamentos estão bloqueados, eles não podem liberar os bloqueios que eles mantêm. E
como eles não podem liberar as travas, nenhum outro thread pode adquirir esses bloqueios.

É aqui que as variáveis de condição entram em cena. Uma variável de condição é


simplesmente um semáforo que está associado a um recurso e é usado dentro da proteção
de um mutex específico . Quando você precisa de um recurso que não está disponível, você
espera em uma variável de condição. Essa ação libera o bloqueio no mutex correspondente .
Quando algum outro segmento sinaliza que o recurso está disponível, o thread original sai
da espera e simultaneamente recupera o bloqueio na região crítica.

#!/usr/bin/ruby
require 'thread'
mutex = Mutex.new

cv = ConditionVariable.new
a = Thread.new {
mutex.synchronize {
puts "A: I have critical section, but will wait for cv"
cv.wait(mutex)
puts "A: I have critical section again! I rule!"
}
}

puts "(Later, back at the ranch...)"

b = Thread.new {
mutex.synchronize {
puts "B: Now I am critical, but am done with cv"
cv.signal
puts "B: I am still critical, finishing up"
}
}
a.join
b.join

Isso produzirá o seguinte resultado -

A: I have critical section, but will wait for cv


(Later, back at the ranch...)
B: Now I am critical, but am done with cv
B: I am still critical, finishing up
A: I have critical section again! I rule!

Existem cinco possíveis valores de retorno correspondentes aos cinco estados possíveis,
conforme mostrado na tabela a seguir. O status status retorna o estado do encadeamento.

Estado da linha Valor de retorno

Runnable corre

adormecido adormecido

Abortando abortando

Terminado normalmente falso

Terminado com exceção nada

Os métodos a seguir são fornecidos pela classe Thread e são aplicáveis a todos os
encadeamentos disponíveis no programa. Esses métodos serão chamados usando o nome
da classe Thread da seguinte maneira -

Thread.abort_on_exception = true

Aqui está a lista completa de todos os métodos de classe disponíveis -

Esses métodos são aplicáveis a uma instância de um segmento. Esses métodos serão
chamados como usando uma instância de um thread da seguinte maneira -

#!/usr/bin/ruby

thr = Thread.new do # Calling a class method new


puts "In second thread"
raise "Raise exception"
end
thr.join # Calling an instance method join

Aqui está a lista completa de todos os métodos de instância disponíveis -

Como o módulo Kernel está incluído na classe Object , seus métodos estão disponíveis em
todos os lugares no programa Ruby. Eles podem ser chamados sem um receptor (forma
funcional). Portanto, eles são freqüentemente chamados de funções.

Uma lista completa de funções internas é dada aqui para sua referência -

Aqui está uma lista de funções internas relacionadas ao número. Eles devem ser usados da
seguinte maneira -

#!/usr/bin/ruby

num = 12.40
puts num.floor # 12
puts num + 10 # 22.40
puts num.integer? # false as num is a float.

Isso produzirá o seguinte resultado -

12
22.4
false

Assumindo, n é um número -

Aqui está uma lista de funções internas do Ruby especialmente para números
flutuantes. Supondo que temos um número flutuador f -

Aqui está uma lista de funções matemáticas internas do Ruby -

A função sprintf (fmt [, arg ...]) e format (fmt [, arg ...]) retorna uma string na qual arg é
formatada de acordo com fmt. As especificações de formatação são essencialmente as
mesmas para sprintf na linguagem de programação C. Os especificadores de conversão (%
seguidos pelo especificador de campo de conversão) em fmt são substituídos pela string
formatada do argumento correspondente.

Os seguintes especificadores de conversão são suportados pelo formato do Ruby -

A seguir está o exemplo de uso -

#!/usr/bin/ruby

str = sprintf("%s\n", "abc") # => "abc\n" (simplest form)


puts str

str = sprintf("d=%d", 42) # => "d=42" (decimal output)


puts str

str = sprintf("%04x", 255) # => "00ff" (width 4, zero padded)


puts str

str = sprintf("%8s", "hello") # => " hello" (space padded)


puts str

str = sprintf("%.2s", "hello") # => "he" (trimmed by precision)


puts str

Isso produzirá o seguinte resultado -

abc
d = 42
00ff
hello
he

O teste de função (teste, f1 [, f2]) executa um dos seguintes testes de arquivo especificados
pelo teste de caractere . Para melhorar a legibilidade, você deve usar métodos de classe de
arquivo (por exemplo, File :: readable?) Em vez dessa função.

Aqui estão os testes de arquivo com um argumento -

Testes de arquivo com dois argumentos são os seguintes -

A seguir, o exemplo de uso. Assumindo que main.rb existe com permissões de leitura,
gravação e não execução -

#!/usr/bin/ruby

puts test(?r, "main.rb" ) # => true


puts test(?w, "main.rb" ) # => true
puts test(?x, "main.rb" ) # => false

Isso produzirá o seguinte resultado -

true
false
false

As variáveis predefinidas de Ruby afetam o comportamento de todo o programa, portanto,


seu uso em bibliotecas não é recomendado.

Os valores na maioria das variáveis predefinidas podem ser acessados por meios
alternativos.

A tabela a seguir lista todas as variáveis predefinidas do Ruby.

Sr. Nome e descrição da variável


Não.

$!

1 O último objeto de exceção gerado. O objeto de exceção também pode ser


acessado usando => na cláusula rescue .

$@

O backtrace de pilha para a última exceção levantada. As informações de


2
rastreamento de pilha podem ser recuperadas pelo método Exception # backtrace
da última exceção.

$/

3 O separador de registro de entrada (nova linha por padrão). Obtém, readline, etc,
tome seu separador de registro de entrada como argumento opcional.

$\
4
O separador de registro de saída (nil por padrão).

$,

5 O separador de saída entre os argumentos para imprimir e Array # join (nil por
padrão). Você pode especificar o separador explicitamente como Array # join.

$;
6
O separador padrão para divisão (nulo por padrão). Você pode especificar o
separador explicitamente para String # split.

$.

7 O número da última linha lida do arquivo de entrada atual. Equivalente a


ARGF.lineno.

$<
8
Sinônimo para ARGF.

$>
9
Sinônimo para $ defout.

$0
10
O nome do atual programa Ruby sendo executado.

$$
11
O processo pid do atual programa Ruby sendo executado.

$?
12
O status de saída do último processo foi finalizado.

$:
13
Sinônimo para $ LOAD_PATH.

$ DEBUG
14
Verdadeiro se a opção de linha de comando -d ou --debug for especificada.

$ defout
15
A saída de destino para print e printf ( $ stdout por padrão).

$F

A variável que recebe a saída da divisão quando -a é especificado. Essa variável é


16
definida se a opção da linha de comandos -a for especificada junto com a opção -p
ou -n.
$ FILENAME
17
O nome do arquivo atualmente sendo lido do ARGF. Equivalente a ARGF.filename.

$ LOAD_PATH

18 Uma matriz que mantém os diretórios a serem pesquisados ao carregar arquivos


com a carga e exigir métodos.

$ SAFE

O nível de segurança

0 → Nenhuma verificação é executada nos dados fornecidos externamente


(contaminados). (padrão)

19 1 → Operações potencialmente perigosas usando dados contaminados são


proibidas.

2 → Operações potencialmente perigosas em processos e arquivos são proibidas.

3 → Todos os objetos recém-criados são considerados contaminados.

4 → A modificação de dados globais é proibida.

$ stdin
20
Entrada padrão (STDIN por padrão).

$ stdout
21
Saída padrão (STDOUT por padrão).

$ stderr
22
Erro padrão (STDERR por padrão).

$ VERBOSE
23
Verdadeiro se a opção da linha de comandos -v, -w ou --verbose for especificada.

$-x

24 O valor da opção do interpretador -x (x = 0, a, d, F, i, K, l, p, v). Estas opções


estão listadas abaixo

$ -0
25
O valor da opção do interpretador -x e alias de $ /.
A tabela a seguir lista todas as constantes predefinidas do Ruby -

NOTA - VERDADEIRO, FALSO e NIL são compatíveis com versões anteriores. É preferível
usar true, false e nil.

Sr. Nome Constante e Descrição


Não.

VERDADE
1
Sinônimo de verdadeiro.

FALSO
2
Sinônimo de falso.

NADA
3
Sinônimo para nil.

ARGF

Um objeto que fornece acesso à concatenação virtual de arquivos passados como


4
argumentos de linha de comando ou entrada padrão, se não houver argumentos
de linha de comando. Um sinônimo para $ <.

ARGV

5 Uma matriz contendo os argumentos da linha de comando passados para o


programa. Um sinônimo para $ *.

DADOS

6 Um fluxo de entrada para ler as linhas de código seguindo a diretiva __END__. Não
definido se __END__ não estiver presente no código.

ENV

7 Um objeto semelhante a um hash contendo as variáveis de ambiente do programa.


ENV pode ser tratado como um hash.

RUBY_PLATFORM
8
Uma string indicando a plataforma do interpretador Ruby.
RUBY_RELEASE_DATE
9
Uma string indicando a data de lançamento do interpretador Ruby

RUBY_VERSION
10
Uma string indicando a versão do interpretador Ruby.

STDERR
11
Fluxo de saída de erro padrão. Valor padrão de $ stderr .

STDIN
12
Fluxo de entrada padrão. Valor padrão de $ stdin.

STDOUT
13
Fluxo de saída padrão. Valor padrão de $ stdout.

TOPLEVEL_BINDING
14
Um objeto de ligação no nível superior do Ruby.

A distribuição padrão do Ruby contém ferramentas úteis junto com o interpretador e


bibliotecas padrão -

Essas ferramentas ajudam você a depurar e melhorar seus programas Ruby sem gastar
muito esforço. Este tutorial lhe dará um bom começo com essas ferramentas.

RubyGems -

O RubyGems é um utilitário de pacote para o Ruby, que instala pacotes de software


Ruby e os mantém atualizados.

Depurador Rubi -

Para ajudar a lidar com erros, a distribuição padrão do Ruby inclui um depurador.
Isso é muito semelhante ao utilitário gdb , que pode ser usado para depurar
programas complexos.

Ruby Interativo (irb) -

O irb (Interactive Ruby) foi desenvolvido por Keiju Ishitsuka. Ele permite inserir
comandos no prompt e fazer o interpretador responder como se você estivesse
executando um programa. O irb é útil para experimentar ou explorar o Ruby.

Ruby Profiler -

O profiler Ruby ajuda você a melhorar o desempenho de um programa lento


encontrando o gargalo.

Existem outras ferramentas úteis que não vêm incluídas na distribuição padrão do Ruby. No
entanto, você precisa instalá-los você mesmo.

eRuby: Ruby Embeded -

eRuby significa Ruby incorporado. É uma ferramenta que incorpora fragmentos de


código Ruby em outros arquivos, como arquivos HTML similares a ASP, JSP e PHP.

ri: Ruby Interactive Reference -

Quando você tem uma pergunta sobre o comportamento de um determinado


método, você pode invocar o ri para ler a breve explicação do método.

Para mais informações sobre ferramentas e recursos Ruby, dê uma olhada nos Recursos
Úteis do Ruby .

Página anterior Próxima página

Potrebbero piacerti anche