self en los métodos
Parte de la sección Programación orientada a objetos del Journey de Ruby de Coddy. Lección 9 de 57.
Dentro de un método, name = value siempre crea una variable local, incluso cuando la clase tiene un setter name=. Para llamar al setter, escribe el 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.levelSalida:
level is a new local variable here, still nil
2Los lectores no necesitan self.: level y self.level llaman al mismo método. El estilo habitual escribe self. solo donde Ruby lo necesita, delante de un 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!.areaSalida:
24Llamar al setter desde initialize con self. hace que los objetos nuevos pasen la misma comprobación que los cambios posteriores, por lo que la regla está en un solo 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
endSalida:
5
price must be positiveLo que es self depende de dónde se ejecuta el código. Dentro de un método de instancia, es la instancia; en el cuerpo de la clase, fuera de todos los métodos, es la propia clase:
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.whoamiSalida:
in the class body, self is Robot
in a method, self is a RobotDesafío
FácilLa clase Account tiene un setter personalizado balance= que genera ArgumentError con balance cannot be negative para un valor inferior a 0. Completa initialize(owner, balance), deposit(amount) y withdraw(amount) para que cada cambio del saldo pase por ese setter con self., incluido el saldo inicial.
El código proporcionado lee el propietario y el saldo inicial, y después los comandos +n (depósito) o -n (retiro). Imprime Ada: 120 después de cada comando, o el mensaje de error y el saldo sin cambios. Un saldo inicial no válido imprime únicamente el mensaje de error.
Tu código debe ir en account.rb. main.rb contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
require_relative 'account'
# Código de entrada/salida suministrado: déjalo 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 lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesVariables de instanciaMétodos y selfto_s e inspectRepaso: tarjeta de biblioteca4Encapsulación
Métodos privadosMétodos protegidosAsignadores privadosProtección del estadoRepaso: máquina expendedora7Polimorfismo y tipado pato
PolimorfismoTipado patoMétodos abstractoscase y clasesRepaso: métodos de pago2Accesores y self
Lectores y escritoresSetters personalizadosself en los métodosIdentidad e igualdadRepaso: lista de contactos5Herencia
SubclasesSobrescritura de métodosLlamar a superis_a? y ancestrosRepaso - Nómina del personal8Métodos especiales
Igualdad y hashMétodos de operadoresIndexación y adiciónColecciones personalizadasRepaso: fracciones11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de librosPractica por tu cuenta: Compilador de Ruby online