On Github jlucasps / ruby-tutorial
João Lucas Pereira de Santana
João Lucas Pereira de Santana
Open source desde 2004
David Heinemeier Hansson (DHH)
Maio/2014
jlucasps@lotus:~/Projects/ruby$ irb-ruby-2.0.0-p353
> 2 + 7
=> 9
> "Joao Lucas".capitalize
=> "Joao lucas"
> "Joao Lucas".upcase
=> "JOAO LUCAS"
>
t = Time.now
puts "Hoje é dia #{ t.strftime( '%m/%d/%Y' ) }."
print "Hora atual: #{ t.strftime(' %I:%M%p' ) }. "
puts "Tenha uma boa semana!"
Em seguida, execute o arquivo utilizando o interpretador:
jlucasps@lotus:~/Projects/ruby$ ruby today.rb
Hoje é dia 05/14/2014.
Hora atual: 02:30AM. Tenha uma boa semana!
jlucasps@lotus:~/Projects/ruby$
jlucasps@lotus:~/Projects/ruby$ irb-ruby-2.0.0-p353
> class Book; end
=> nil
> Book.new.class
=> Book
> Book.new.object_id
=> 7256240
> Book.class
=> Class
> Book.object_id
=> 7359560
Classes também são objetos!
class Book
def initialize(title)
@title = title
end
def title
@title
end
end
jlucasps@elrond:~/Projects/ruby$ irb
> require './book'
=> true
> book = Book.new "Eloquent Ruby"
=> #<Book:0x0000000173e870 @title="Eloquent Ruby">
> book.title
=> "Eloquent Ruby"
> book.send(:title)
=> "Eloquent Ruby"
>
Chamadas de métodos em objetos
> 2.send(:+, 2)
=> 4
> arr = [:a, :b, :c]
=> [:a, :b, :c]
> arr.send(:[]=, 3, :d)
=> :d
> arr
=> [:a, :b, :c, :d]
>
> arr << :e
=> [:a, :b, :c, :d, :e]
Até mesmo operações são métodos
> x = 3
=> 3
> if ( x.send( :==, 3 ) )
> puts "X é igual a 3"
> end
X é igual a 3
=> nil
> def sum(a, b)
> a + b
> end
=> nil
> sum( 3, 4 )
=> 7
> self.send(:sum, 5, 6)
=> 11
> def my_func(a, b, c)
> res = a
> puts res.class
> # ...
> res = b
> puts res.class
> # more code here ...
> res = c
> puts res.class
> end
=> nil
> my_func("v1", :v2, 3)
String
Symbol
Fixnum
=> nil
>
Variável armazena objetos de qualquer tipo
> def other_func(d, e)
> res = d
> puts res.object_id
> # more code here ...
> res = e
> puts res.object_id
> end
=> nil
> other_func(:d, ['e'])
373928
11939060
=> nil
Objetos e identificadores
class Book
def initialize(title)
@title = title
end
def title
@title
end
def title=(title)
@title = title
end
end
class Book
attr_accessor :title
def initialize(title)
@title = title
end
end
jlucasps@elrond:~/Projects/ruby$ irb
> require './book'
=> true
> book = Book.new( "Eloquent Ruby" )
=> #<Book:0x000000015d3b20 @title="Eloquent Ruby">
> book.title
=> "Eloquent Ruby"
>
jlucasps@elrond:~/Projects/ruby$ irb
> require './book'
=> true
> book = Book.new ( "Eloquent Ruby" )
=> #<Book:0x0000000138a288 @title="Eloquent Ruby">
> book.respond_to?(:title)
=> true
> book.respond_to?(:content)
=> false
Inspecionando objetos
> require './book'
=> true
> book = Book.new "Eloquent Ruby"
=> #<Book:0x00000002845330 @title="Eloquent Ruby">
> book.methods
=> [:title, :title=, :nil?, :===, :=~, :!~, :eql?, :hash, :<=>,
:class, :singleton_class, :clone, :dup, :taint, :tainted?,
:untaint, :untrust, :untrusted?, :trust, :freeze, :frozen?,
:to_s, :inspect, :methods, :singleton_methods, :protected_methods,
:private_methods, :public_methods, :instance_variables,
:instance_variable_get, :instance_variable_set,
:instance_variable_defined?, :remove_instance_variable,
:instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send,
:respond_to?, :extend, :display, :method, :public_method,
:define_singleton_method, :object_id, :to_enum, :enum_for,
:==, :equal?, :!, :!=, :instance_eval, :instance_exec,
:__send__, :__id__]
>
class Magazine
# ...
end
Métodos e variáveis usam snake_case
def number_of_pages
# some code here ...
end
def is_web_magazine?
# more code ...
end
def change_folder!
# code code code ...
end
class Magazine
MAX_PAGES = 30
end
Variáveis de instância
class Magazine
def initialize
@max_pages = 30 # instance variable
end
end
Variáveis de classe
class Magazine
@@max_pages = 30 # class variable
def initialize
# ...
end
end
> class Magazine
> MAX_PAGES = 30
> end
=> 30
> Magazine::MAX_PAGES
=> 30
> class Magazine
> def initialize
> @max_pages = 30 # instance variable
> end
> def max_pages
> @max_pages
> end
> end
=> nil
> m = Magazine.new
=> #<Magazine:0x000000024c5610 @max_pages=30>
> m.max_pages
=> 30
> class Magazine
> @@max_pages = 30 # class variable
> def initialize
> # ...
> end
> def self.max_pages
> @@max_pages
> end
> end
=> nil
> Magazine.max_pages
=> 30
languagem = :ruby
framework = :rails
system = :linux
"String's imutáveis cujo valor é o próprio símbolo"
> lang = :ruby
=> :ruby
> lang.to_s
=> "ruby"
> framework = "rails".to_sym
=> :rails
> new_lang = "ruby".to_sym
=> :ruby
> new_lang.object_id
=> 321608
> lang.object_id
=> 321608
Coleção de objetos ordenados
Indexados por números inteiros começando em 0
> arr = [1, "2", :c, {"name" => "Joao Lucas"}, 5]
=> [1, "2", :c, {"name"=>"Joao Lucas"}, 5]
> arr[0]
=> 1
> arr.last
=> 5
> numbers = [1, 2, 3, 4, 5, 6]
=> [1, 2, 3, 4, 5, 6]
> numbers.min
=> 1
> numbers.max
=> 6
> numbers.reverse
=> [6, 5, 4, 3, 2, 1]
> numbers
=> [1, 2, 3, 4, 5, 6]
> numbers.shuffle
=> [1, 4, 6, 3, 2, 5]
> numbers.push 7
=> [1, 2, 3, 4, 5, 6, 7]
> numbers << 8
=> [1, 2, 3, 4, 5, 6, 7, 8]
> numbers.pop
=> 8
> numbers
=> [1, 2, 3, 4, 5, 6, 7]
Coleçao de pares chave-valor
Indexados por objetos de qualquer tipo
> h = {"lang" => "Ruby", "os" => "Linus", "db" => "Postgres"}
=> {"lang"=>"Ruby", "os"=>"Linus", "db"=>"PostgreSQL"}
> h.keys
=> ["lang", "os", "db"]
> h.values
=> ["Ruby", "Linus", "PostgreSQL"]
> h[10] = "Ruby classes"
=> "Ruby classes"
> h
=> {"lang"=>"Ruby", "os"=>"Linus", "db"=>"PostgreSQL", 10=>"Ruby classes"}
> h[{"a" => "b"}] = "C"
=> "C"
> h.delete("db")
=> "PostgreSQL"
> h
=> {"lang"=>"Ruby", "os"=>"Linus", 10=>"Ruby classes", {"a"=>"b"}=>"C"}
Ruby 1.8
> tools = {:lang => "Ruby", :framework => "Rails"}
=> {:lang=>"Ruby", :framework=>"Rails"}
Ruby 1.9
> tools = {lang: "Ruby", framework: "Rails"}
=> {:lang=>"Ruby", :framework=>"Rails"}
# ...
user.name
user é o receptor ao qual enviamos uma chamada de método
Considerando que user responde à chamada name
# ...
user.name() # ou user.send(:name)
Yukihiro "Matz" Matsumoto
O código deve ser bastante claro
+
O código deve ser conciso
=
Código simples, efetivo e fazer exatamente o que ser propôe a fazer
Armando Fox, University of California, Berkeley
def print_key_value( hash )
hash.each_pair { |key, value| puts "chave: #{key} - value: #{value}" }
end
> print_key_value({ user: "Joao lucas", email: "jlucasps" })
> print_key_value( user: "Joao lucas", email: "jlucasps" )
> print_key_value user: "Joao lucas", email: "jlucasps"
chave: user - value: Joao lucas
chave: email - value: jlucasps@gmail.com
user.age.should(be() >= 18)
user.age.should be >= 18
if !logged_in?() # unless logged_in?()
(redirect_to(login_page)) and return()
end
# ...
(redirect_to(login_page)) and return() unless logged_in?()
# ...
redirect_to login_page and return unless logged_in?
arr = [1, 2, 3, 4, 5]
arr.map do |n|
n + 30
end
=> [31, 32, 33, 34, 35]
Criar um novo método iterate! e adicionar à classe Array
class Array
def iterate!
self.each_with_index do |n, i|
self[i] = yield n
end
end
end
> array = [1, 2, 3, 4]
=> [1, 2, 3, 4]
> array.iterate! { |n|
> (n * 3) + 5
> }
=> [8, 11, 14, 17]
Ao chamar o yield, iremos executar o bloco de código fornecido ao método
class Array
def iterate!( &code )
self.each_with_index do |n, i|
self[i] = code.call( n )
end
end
end
> array = [10, 11, 12, 13]
=> [10, 11, 12, 13]
> array.iterate! do |n|
> n ** 2
> end
=> [100, 121, 144, 169]
class Caller
def self.exec_before( method_name)
@@before = method_name
end
def self.exec_after( method_name )
@@after = method_name
end
def execute( &code )
method(@@before).call if defined? @@before
code.call
method(@@after).call if defined? @@after
end
end
Métodos de classe para salvar símbolos nos atributos da classe
Método para executar uma Proc entre duas chamadas de métodos
class Executor < Caller
exec_before( :say_hello )
exec_after( :say_bye )
def say_hello
puts "Hello, I'm here!"
end
def say_bye
puts "Good bye!"
end
end
Classe com dois métodos configurados para serem executados como before e after
exec = Executor.new
exec.execute do
puts "I do my job"
end
# Hello, I'm here!
# I do my job
# Good bye!
Callbacks executados