Nesta aula iremos aprender o inicio da metaprogramação, veremos como o Ruby injeta métodos em objetos, tudo em tempo de execução.
São programas que escrevem ou manipulam outros programas (ou a si próprios) assim como seus dados, ou que fazem parte do trabalho em tempo de execução.
Obs.: OBJETO = ESTADO + COMPORTAMENTO
Com a Metaprogramação conseguimos definir um método em tempo de execução. Dado exemplo:
class Carro
def initialize
@nome = "teste"
end
def show
@nome
end
end
Então observamos que um comportamento altera um estado, onde nossa variável é o estado e o método show a ação que altera ela.
Simplificadamente um estado pode ser uma variável e um comportamento uma ação que altera esse estado.
O problema de utilizarmos o polimorfismo para herdar as classes, é que podemos acabar com uma "classe base" guiando o desenvolvimento da nossa aplicação, dificultando o desenvolvimento.
No exemplo abaixo a instância já está definida, e em momento de execução alteramos o comportamento dela, dando muito mais agilidade e flexibilidade, dando liberdade para trocarmos em alguns casos o polimorfismo pela metaprogramação.
a = "Danilo"
def a.mostrar
"#{self}---"
end
Lembrando que self
é referente a classe que ele está, se ele não está dentro de nenhuma classe,
irá referenciar a classe main.
Como de praxe copie os arquivos das aulas anteriores para seguir conforme o padrão.
Para o arquivo aula.rb
faça:
require 'byebug'
debugger
a = "Danilo"
def a.mostrar
"#{self}---"
end
Com o código abaixo rodando linha-a-linha com o debugger
conseguimos observar que antes da linha
onde definimos o método a.mostrar_nova_string
require 'byebug'
a = "Danilo"
def a.mostrar
"#{self}---"
end
def a.mostrar_nova_string
"nova string"
end
Com o código abaixo rodando linha-a-linha com o debugger
conseguimos observar que antes da linha
onde definimos o método a.mostrar_nova_string
require 'byebug'
a = "Danilo"
debugger
def a.mostrar_nova_string
"nova string"
end
def a.mostrar_nova_string
"nova string"
end
Classe Carro que fizemos na aula de polimorfismo.
class Carro
def initialize(nome = "Modelo Padrão")
@nome = nome
end
attr_accessor :nome, :porta, :painel, :roda
attr_reader :pneu
def mostrar(marca="Marca Padrão")
puts "Marca: #{marca} - Modelo: #{self.nome} - #{algo_mais}"
end
private
def algo_mais
"este é um método privado para retornar algo a mais"
end
end
fiesta = Carro.new
golf = Carro.new
def golf.mostrar
"Mostrar do Golf"
end
def fiesta.mostrar
"Mostrar do Fiesta"
end
debugger
x = ""
Na execução alteramos o método das instâncias atribuindo uma nova ação para eles. Isso mostra um dos beneficios metaprogramação.
Com o self.classe
podemos criar um método de classe.
def self.metodo_de_classe
"de classe"
end
end
def Carro.metodo_de_classe2
"de classe"
end
No código acima observe que os dois métodos de classe, sendo o que self
representa a classe
Carro
neste contexto.
Para o último aprenderemos sobre o self
.
Arquivo aula.rb
final:
require 'byebug'
# def String.mostrar_nova_string2
# "nova string"
# end
# a = "danilo"
# debugger
# def a.mostrar_nova_string
# "nova string"
# end
# x = ""
puts "[[[[Inicio: #{self}]]]]"
class Carro
puts "[[[[Class: #{self}]]]]"
def initialize(nome = "Modelo padrão")
@nome = nome
end
attr_accessor :nome, :porta, :painel, :roda
attr_reader :pneu
def mostrar(marca="Marca padrão")
puts "[[[[Method: #{self}]]]]"
"Marca: #{marca} - Modelo: #{self.nome}"
end
def self.metodo_de_classe
"de classe"
end
end
def Carro.metodo_de_classe2
"de classe"
end
puts "[[[[Fim: #{self}]]]]"
fiesta = Carro.new
golf = Carro.new
# def fiesta.mostrar
# "Mostrar do fiesta"
# end
# def golf.mostrar
# "Mostrar do golf"
# end
debugger
x = ""
Nesta aula iremos aprender o inicio da metaprogramação, veremos como o Ruby injeta métodos em objetos, tudo em tempo de execução.
São programas que escrevem ou manipulam outros programas (ou a si próprios) assim como seus dados, ou que fazem parte do trabalho em tempo de execução.
Obs.: OBJETO = ESTADO + COMPORTAMENTO
Com a Metaprogramação conseguimos definir um método em tempo de execução. Dado exemplo:
class Carro
def initialize
@nome = "teste"
end
def show
@nome
end
end
Então observamos que um comportamento altera um estado, onde nossa variável é o estado e o método show a ação que altera ela.
Simplificadamente um estado pode ser uma variável e um comportamento uma ação que altera esse estado.
O problema de utilizarmos o polimorfismo para herdar as classes, é que podemos acabar com uma "classe base" guiando o desenvolvimento da nossa aplicação, dificultando o desenvolvimento.
No exemplo abaixo a instância já está definida, e em momento de execução alteramos o comportamento dela, dando muito mais agilidade e flexibilidade, dando liberdade para trocarmos em alguns casos o polimorfismo pela metaprogramação.
a = "Danilo"
def a.mostrar
"#{self}---"
end
Lembrando que self
é referente a classe que ele está, se ele não está dentro de nenhuma classe,
irá referenciar a classe main.
Como de praxe copie os arquivos das aulas anteriores para seguir conforme o padrão.
Para o arquivo aula.rb
faça:
require 'byebug'
debugger
a = "Danilo"
def a.mostrar
"#{self}---"
end
Com o código abaixo rodando linha-a-linha com o debugger
conseguimos observar que antes da linha
onde definimos o método a.mostrar_nova_string
require 'byebug'
a = "Danilo"
def a.mostrar
"#{self}---"
end
def a.mostrar_nova_string
"nova string"
end
Com o código abaixo rodando linha-a-linha com o debugger
conseguimos observar que antes da linha
onde definimos o método a.mostrar_nova_string
require 'byebug'
a = "Danilo"
debugger
def a.mostrar_nova_string
"nova string"
end
def a.mostrar_nova_string
"nova string"
end
Classe Carro que fizemos na aula de polimorfismo.
class Carro
def initialize(nome = "Modelo Padrão")
@nome = nome
end
attr_accessor :nome, :porta, :painel, :roda
attr_reader :pneu
def mostrar(marca="Marca Padrão")
puts "Marca: #{marca} - Modelo: #{self.nome} - #{algo_mais}"
end
private
def algo_mais
"este é um método privado para retornar algo a mais"
end
end
fiesta = Carro.new
golf = Carro.new
def golf.mostrar
"Mostrar do Golf"
end
def fiesta.mostrar
"Mostrar do Fiesta"
end
debugger
x = ""
Na execução alteramos o método das instâncias atribuindo uma nova ação para eles. Isso mostra um dos beneficios metaprogramação.
Com o self.classe
podemos criar um método de classe.
def self.metodo_de_classe
"de classe"
end
end
def Carro.metodo_de_classe2
"de classe"
end
No código acima observe que os dois métodos de classe, sendo o que self
representa a classe
Carro
neste contexto.
Para o último aprenderemos sobre o self
.
Arquivo aula.rb
final:
require 'byebug'
# def String.mostrar_nova_string2
# "nova string"
# end
# a = "danilo"
# debugger
# def a.mostrar_nova_string
# "nova string"
# end
# x = ""
puts "[[[[Inicio: #{self}]]]]"
class Carro
puts "[[[[Class: #{self}]]]]"
def initialize(nome = "Modelo padrão")
@nome = nome
end
attr_accessor :nome, :porta, :painel, :roda
attr_reader :pneu
def mostrar(marca="Marca padrão")
puts "[[[[Method: #{self}]]]]"
"Marca: #{marca} - Modelo: #{self.nome}"
end
def self.metodo_de_classe
"de classe"
end
end
def Carro.metodo_de_classe2
"de classe"
end
puts "[[[[Fim: #{self}]]]]"
fiesta = Carro.new
golf = Carro.new
# def fiesta.mostrar
# "Mostrar do fiesta"
# end
# def golf.mostrar
# "Mostrar do golf"
# end
debugger
x = ""