Primeiros passos com Ruby

Gabriel Willemann

Curso ministrado na UDESC durante a SEMESO (Seminário de Engenharia de Software)

Ibirama, SC - 14/09/2018

Paradigma Ruby

  • Mente aberta a novas ideias
  • Não seja resistente
  • Não tente comparar com outras linguagens
  • Misto de vários paradigmas de programação
  • Resistência só atrapalha o aprendizado
  • "Deixa o Ruby te levar"

O que é Ruby?

  • Linguagem de programação
  • Criada no Japão em 1995
  • Criador: Yukihiro Matsumoto (conhecido por Matz)
  • Objetivo: Desenvolver uma linguagem com uma sintaxe simples para reduzir a sobrecarga nos programadores
  • Algumas inspirações: Python, Perl, Smalltalk

O que é Ruby?

"Eu queria uma linguagem de script que fosse mais poderosa do que Perl, e mais orientada a objetos do que Python. É por isso que eu decidi desenvolver minha própria linguagem." - Matz

Ruby: Características

  • Linguagem de programação Interpretada
  • Open Source
  • Orientação a objetos: Forte, implícita e dinâmica
  • Principle of Least Surprise: Tudo se comporta de maneira previsível e sem surpresas ao programador

O que eu posso fazer com Ruby?

  • Posso criar sites? Sim
  • Posso criar mobile apps? Sim, mas esse não é foco
  • Posso criar desktop apps? Sim, mas esse não é foco
  • Uso comum do Ruby: Linguagem de servidor, normalmente utilizado para Backend Web/Mobile

Mas eu quero...

  • Eu quero uma linguagem que eu possa utilizar meu código em várias plataformas!
  • Já que vou aprender uma linguagem, que seja uma linguagem que eu consiga usar em tudo!
  • Então, por que aprender Ruby?

Por que aprender Ruby?

  • Resposta: Mudança de mentalidade
  • Foco do Ruby: Produtividade do programador
  • Depois de aprender Ruby, você pode utilizar outras linguagens
  • A diferença, é que você utilizará com outra mentalidade
  • Uma mentalidade mais simples e produtiva

Tecnologias baseadas na cultura Ruby

  • Laravel (PHP)
  • SailsJs (NodeJS)
  • Play (Java)
  • Crystal (Fast as C, Slick as Ruby)
  • Elixir (Progamação Funcional)

Comunidade Ruby

  • É considerada grande
  • Embora seja menor do que Java e PHP
  • Mas é uma comunidade muita ativa
  • No Brasil a comunidade ainda é pequena
  • Muito popular entre Startups
  • Muito popular na Ásia (Japão)
  • 8ª linguagem mais utilizada no mundo em 2018
  • https://olhardigital.com.br/noticia/as-10-linguagens-de-programacao-mais-populares-do-mundo-em-2018/74538

Quem utiliza Ruby

  • No mundo: Github, Grupon, Airnbn, Soundcloud, Bloomberg...
  • No Brasil: Locaweb, Resultados Digitais, Plataformatec...
  • As primeiras versões do Twitter foram contruídas com RoR
  • https://codificar.com.br/blog/porque-utilizar-o-ruby-on-rails-em-seu-projeto/

IDE

  • Esqueçam NetBeans, Eclipse...
  • Programador Ruby precisa de: Editor de texto e console/shell/terminal
  • Eu utilizo ATOM, mas é a escolha livre
  • Pode ser Notepad++, VSCode, VIM

Executando o Ruby

  • www.ruby-lang.org/pt/documentation/installation
  • Após instalação, adicionar o diretório "rubydir/bin" na variável PATH
  • Para Windows é importante instalar o DevKit
  • Executar scripts por meio do console: ruby teste.rb

Tipos primitivos

  • Não existem tipos primitivos em Ruby
  • Tudo é representado por Classes e Objetos
  • Exemplos: Integer, Float, String, Symbol, Boolean*, Array, Hash

Exemplo 1


						myint = 1
						myfloat = 1.45
						mystring = 'abc'

						puts myint, myint.class
						puts myfloat, myfloat.class
						puts mystring, mystring.class
					

Integer e Float

  • Operadores matemáticos são métodos: + - * /
  • Parenteses é opcional na chamada de métodos
  • Isso é possível graças ao SyntaxSugar
  • Lista completa de métodos:
  • https://ruby-doc.org/core-2.5.0/Integer.html
  • https://ruby-doc.org/core-2.5.0/Float.html

Exemplo 2


						a = 1
						b = 2
						puts a+b
						puts a + b
						puts a.+ b
						puts a.+(b)
					

Strings

  • Podem ser declaradas com aspas simples ou duplas
  • Aspas duplas permitem interpolação: "Conteúdo da variável é #{my_variable}"
  • As Strings ocupam endereços de memória diferentes
  • puts 'teste'.object_id > 40777940
  • puts 'teste'.object_id > 40777760

Symbols

  • Symbols são Strings que sempre possuem o mesmo endereço de memória
  • São declaradas com dois pontos no seu início
  • myvariable = :test
  • puts :test.object_id > 917788
  • puts :test.object_id > 917788
  • Muito útil em configurações e parâmetros
  • Economiza memória

Exemplo 3


						puts 'test'.object_id
						puts 'test'.object_id
						puts :test.object_id
						puts :test.object_id
					

Boolean

  • Não existe tipo "boolean"
  • Existem duas classes: TrueClass e FalseClass
  • Operadores de comparação também são métodos: == !=
  • https://ruby-doc.org/core-2.5.0/FalseClass.html
  • https://ruby-doc.org/core-2.5.0/TrueClass.html

Exemplo 4


						a = true
						puts a, a.class

						b = false
						puts b, b.class

						puts "Igual? #{b == a}"
					

Array

  • Lista que utiliza um índice sequencial

Exemplo 5


						a = [55,'aa']
						a << 'bb'

						puts a.size
						puts a[0]
						puts a[1]
						puts a[2]
					

Hash

  • Lista ordenada por um índice de qualquer tipo
  • Normalmente estes índices são Symbols

Exemplo 6


						a = {'a' => 100, 2 => 101}
						a[:c] = 103

						puts a.size
						puts a['a']
						puts a[2]
						puts a[:c]
					

Exemplo 7 - Condições


						a = 1
						if a == 1
						  puts 'a é igual 1'
						elsif a == 2
						  puts 'a é igual 2'
						else
						  puts 'a é diferente de 1 e 2'
						end

						b = 0
						puts 'a é igual 1 e b é igual 1' if a == 1 && b == 1
						puts 'a é igual 1 ou b é igual 1' if a == 1 || b == 1
					

Exemplo 8 - Iterações


						i = 0
						while i < 10
						  puts i
						  i = i.next
						end

						for i in 0..9
						  puts i
						end
					

Iterações com Array e Hash

  • Em ruby "evita-se" utilizar o FOR para percorrer Array e Hash
  • Existem métodos específicos para percorrer estes objetos

Exemplo 9


						a = [6,7,2,1,9]
						a.each do |value|
						  puts value
						end
						a.each_with_index do |value, key|
						  puts "#{key} = #{value}"
						end

						h = {:a => 1, :b => 2, :c => 3}
						h.each do |key, value|
						  puts "#{key} = #{value}"
						end
					

Orientação a objetos - Métodos

  • Precedidos por "def"
  • Finalizados com "end"
  • "return" é opcional
  • Caso "return" não seja informado, é retornado a última linha

Orientação a objetos - Propriedades

  • Precedidas com "@"
  • Sempre são private
  • Get e Set são implementados, mas do jeito "ruby"

Exemplo 10


						class Person
						  def initialize(name, age)
						    @name = name
						    @age = age
						  end
						  def name=(name)
						    @name = name
						  end
						  def name
						    @name
						  end
						  def to_s
						    "Nome: #{@name} - Idade: #{@age}"
						  end
						end
					

						p = Person.new('João', 30);
						puts p
						p.name = 'José'
						puts p
					

Orientação a objetos - Get e Set

  • Ruby facilita a implementação do Get e Set
  • Basta declarar "attr_accessor :PROPERTY_NAME"
  • Também pode ser utilizado: attr_reader e attr_writer
  • Recurso de metaprogramação
  • Injeta códigos dentro da classe, neste injeta os métodos

Exemplo 11


						class Person
						  attr_accessor :name, :age
						  def initialize(name, age)
						    @name = name
						    @age = age
						  end
						  def to_s
						    "Nome: #{@name} - Idade: #{@age}"
						  end
						end

						p = Person.new('João', 30);
						p.name = 'José'
						puts p
					

Visibilidade dos Métodos

  • Por padrão todos os métodos são "public"
  • Para métodos privados: Declarar "private" e todos os métodos posteriores serão privados
  • Para métodos protegidos: Declarar "protected"

Métodos Estáticos

  • Precedidos pela palavra "self"
  • "def self.name_method CODE end"
  • Método pertence à classe
  • Método não pertence ao objeto

Exemplo 12


						class MyFavoriteClass
						  def method_public
						    "#{my_method_private} => #{method_protected} => entry on method_public1"
						  end
						  def self.method_static
						    'entry on method_static'
						  end

						  private
						  def my_method_private
						    'entry on method_private'
						  end

						  protected
						  def method_protected
						    'entry on method_protected'
						  end
						end

						puts MyFavoriteClass::method_static

						obj = MyFavoriteClass.new
						puts obj.method_public
						puts obj.method_static # Display ERROR
						puts obj.method_protected # Display ERROR
					

Orientação a objetos - Heranças

  • Herança são realizadas por meio do caracter "<"
  • class Animal
  • class Dog < Animal

Orientação a objetos - Module e Mixins

  • Module são usados para definir "namespace"
  • Também são utilizados para "heranças múltiplas"

Exemplo 13


						module System1
						  class Person
						    attr_accessor :name, :age
						  end
						end

						p = System1::Person.new
					

Exemplo 14


						module CommonMethods
						  def default_message
						    'executed successfully'
						  end
						end

						class Person
						  include CommonMethods
						  attr_accessor :name, :age
						end

						puts Person.new.default_message
					

Múltiplos arquivos

  • Requisição a outros arquivos é feito pelo comando: "require"
  • require './file.rb'

Exemplo 15


						class Person
						  attr_accessor :name, :age
						  def to_s
						    "Nome: #{@name} - Idade: #{@age}"
						  end
						end
					

						require './person.rb'

						p = Person.new
						p.name = 'João'
						p.age = 27
						puts p
					

Exceções

  • Lançar exceção: raise 'Exception descripetion'
  • Tratar exceção: begin CODE rescue CODE end
  • Classe Exception é pai de todas as exceções
  • Suas Exceptions devem herdar StandardError
  • Herança de Exception é destinado a erros de sintaxe, memória, fileloads

Exemplo 16


						class InvalidNameError < StandardError
						end

						class Person
						  def name=(name)
						    raise InvalidNameError, "#{name} is a invalid name" if name.nil? || name.size <= 3
						    @name = name
						  end
						  def name
						    @name
						  end
						end

						begin
						  p = Person.new
						  p.name = 'Bob'
						  puts p
						rescue InvalidNameError => e
						  puts "Incorrect name: #{e}"
						rescue => e
						  puts "Unknown expcetion: #{e}"
						end
					

Exemplo 17


						class MyClass
						  def my_method
						    raise 'Exception description'
						  rescue => e
						    puts e
						  end
						end
						MyClass.new.my_method

						# DANGER: Rescue inline no have class filters
						my_variable = raise 'exception' rescue 0
						puts "my_variable is #{my_variable}"
					

Padrões e convenções

  • Indentação: 2 espaços
  • Nomes de classes: CamelCase
  • Nomes de variáveis e métodos: snake_case
  • Existem vários, mas estes são os mais importantes

Gems

  • É um Gerenciador de pacotes
  • Ferramenta para gerenciar bibliotecas
  • Facilita a disponibilização e a instalação
  • Essas bibliotecas devem possuir um formato auto-suficiente (baixo acoplamento)
  • Gems vem do inglês "joias"
  • Componentização é algo estimulado na comunidade Ruby
  • Repositório padrão de bibliteocas Ruby: rubygems.org

Gems

  • Se você criou alguma biblioteca interessante, disponibilize para toda comunidade
  • Exemplo: Criei um rotina para ler arquivos CSV de uma maneira ultra rápida. É fácil disponibilizar para toda comunidade utilizadando o RubyGems.

Utilizando as GEMS

  • Passo 1: Procurar no repositório RubyGems
  • Passo 2: Executar o comando "gem install NAME_GEM"
  • GEM instalada com sucesso e pronta para uso
  • Comando para ver todas as Gems instaladas: "gem list"

GEM para manipulação de CSV

Executar o comando "gem install csv"


						require 'csv'

						csv_string = CSV.generate(:col_sep => ';') do |csv|
						  csv << ['Name','Age']
						  csv << ['João',30]
						  csv << ['José',20]
						  csv << ['Gabriel',50]
						end
						File.write('./people.csv', csv_string)

						CSV.foreach('./people.csv', :col_sep => ';') do |row|
						  row.each do |value|
						    puts value
						  end
						end
					

Bundler

  • Pense que seu projeto possui 50 gems
  • Você vai instalar todas manualmente? Uma por uma?
  • Bundler uma GEM que automatiza a instalação de outras gems

Bundler

  • Passo 1: "gem install bundler"
  • Passo 2: Criar um arquivo na pasta do projeto chamado "Gemfile" (sem extensão)
  • Passo 3: No Gemfile, adicionar o comando "gem 'rtf', '~> 0.3.3'"
  • Passo 4: Na pasta do projeto, executar o comando "bundle install"

Exemplo 19


						# Gemfile
						source 'https://rubygems.org'

						gem 'rtf', '~> 0.3.3'
					

						require 'rtf'

						document = RTF::Document.new(RTF::Font.new(RTF::Font::ROMAN, 'Times New Roman'))

						document.paragraph << 'The first paragraph'
						document.paragraph << 'The second paragraph'

						File.write('new.rtf', document.to_rtf)
					

Ruby: Web Frameworks

  • Ruby on Rails: Web framework MVC (mais popular)
  • Sinatra: Web framework (microestrutura)
  • Hanami: Web framework com uma estrutura modular e com baixo acoplamento

Perguntas?

  • Download em:
  • https://github.com/gabrielwillemann/ruby-introduction-course-presentation