En Ruby, la única forma de cambiar el estado de un objeto, es invocando uno de sus métodos: si controlas el acceso a laso métodos, controlarás el acceso a los objetos. Una buena regla, es cerrar el acceso a los métodos que puedan dejar al objeto en un estado no válido.
class ControlAcceso
def m1 # este método es público
end
protected
def m2 # este método es protegido
end
private
def m3 # este método es privado
end
def m4
end
end
ca = ControlAcceso.new
ca.m1
ca.m2
ca.m3
La privacidad de los métodos, también se pueden especificar de esta forma:
class ControlAcceso
def m1 # este método es público
end
def m2 # este método es protegido
end
def m3 # este método es privado
end
def m4 # este método es privado
public :m1
protected :m2
private :m3, :m4
end
ca = ControlAcceso.new
ca.m1
ca.m2
ca.m3
Tal vez el nivel de acceso protegido (protected) sea un poco lioso de entender. Es mejor verlo con un ejemplo:
class Persona
def initialize(edad)
@edad = edad
end
def edad
@edad
end
def comparar_edad(op) # op = otra persona
if op.edad > edad
'La edad de la otra persona es mayor.'
else
'La edad de la otra persona es la misma o menor.'
end
end
protected :edad
end
pedro = Persona.new(15)
almudena = Persona.new(17)
puts Pedro.comparar_edad(almudena) # La edad ... es mayor
El objeto que hace la comparación (pedro
) necesita preguntar al otro objeto (almudena
) su edad, lo que significa que ejecute su método edad. Por eso el nivel de acceso es protegido y no privado: al estar protegido pedro
puede usar el método de almudena
.
La excepción viene cuando pedro
se pregunta a sí mismo la edad, por ser un método protegido, esto no será posible. self no puede ser el receptor de un método protegido.
Por ejemplo:
puts Pedro.edad #da error