self nos Métodos
Parte da seção Programação orientada a objetos do Journey de Ruby da Coddy. Lição 9 de 57.
Dentro de um método, name = value sempre cria uma variável local, mesmo quando a classe tem um setter name=. Para chamar o setter, escreva o receptor: self.name = value:
class Player
attr_accessor :level
def initialize
@level = 1
end
def broken_level_up
level = level + 1
rescue NoMethodError
puts "level is a new local variable here, still nil"
end
def level_up
self.level = level + 1
end
end
p1 = Player.new
p1.broken_level_up
p1.level_up
puts p1.levelSaída:
level is a new local variable here, still nil
2Os leitores não precisam de self.: level e self.level chamam o mesmo método. O estilo usual escreve self. apenas onde o Ruby precisa dele, antes de um setter:
class Rect
attr_accessor :w, :h
def initialize(w, h)
@w = w
@h = h
end
def area
w * h
end
def double!
self.w = w * 2
self.h = self.h * 2
self
end
end
puts Rect.new(2, 3).double!.areaSaída:
24Chamar o setter a partir de initialize com self. faz com que os novos objetos passem pela mesma verificação que as alterações posteriores, portanto a regra fica em um só lugar:
class Product
attr_reader :price
def initialize(price)
self.price = price
end
def price=(value)
raise ArgumentError, "price must be positive" if value <= 0
@price = value
end
end
puts Product.new(5).price
begin
Product.new(0)
rescue ArgumentError => e
puts e.message
endSaída:
5
price must be positiveO que self representa depende de onde o código é executado. Dentro de um método de instância, ele é a instância; no corpo da classe, fora de qualquer método, ele é a própria classe:
class Robot
puts "in the class body, self is #{self}"
def whoami
"in a method, self is a #{self.class}"
end
end
puts Robot.new.whoamiSaída:
in the class body, self is Robot
in a method, self is a RobotDesafio
FácilA classe Account tem um setter personalizado balance= que gera ArgumentError com balance cannot be negative para um valor abaixo de 0. Complete initialize(owner, balance), deposit(amount) e withdraw(amount) para que toda alteração do saldo passe por esse setter com self., incluindo o saldo inicial.
O código fornecido lê o proprietário e o saldo inicial, depois recebe os comandos +n (depósito) ou -n (saque). Ele imprime Ada: 120 após cada comando, ou a mensagem de erro e o saldo inalterado. Um saldo inicial inválido imprime apenas a mensagem de erro.
Seu código deve ser colocado em account.rb. main.rb contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
require_relative 'account'
# Código de entrada/saída fornecido: mantenha-o como está
input = []
while (line = gets)
input << line.chomp
end
begin
account = Account.new(input[0], input[1].to_i)
input.drop(2).each do |cmd|
begin
amount = cmd[1..].to_i
cmd.start_with?("+") ? account.deposit(amount) : account.withdraw(amount)
rescue ArgumentError => e
puts e.message
end
puts "#{account.owner}: #{account.balance}"
end
rescue ArgumentError => e
puts e.message
end
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesVariáveis de InstânciaMétodos e selfto_s e inspectRevisão - Cartão da Biblioteca4Encapsulamento
Métodos privadosMétodos protegidosSetters privadosProtegendo o estadoRevisão - Máquina de venda automática7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMétodos Abstratoscase e ClassesRevisão - Métodos de Pagamento2Acessores e self
Leitores e GravadoresSetters Personalizadosself nos MétodosIdentidade e IgualdadeRecapitulação - Lista de Contatos5Herança
SubclassesSobrescrita de métodosChamando superis_a? e ancestraisRevisão - Folha de pagamento da equipe8Métodos Especiais
Igualdade e hashMétodos de OperadoresIndexação e AdiçãoColeções PersonalizadasRevisão - Frações11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Compilador de Ruby online