Aprende a programar con Ruby

Control de Acceso y Accesores

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.

Los tres niveles de acceso

  • public - los métodos públicos (public) pueden ser usados por cualquiera; no hay un control de acceso.
  • protected - los métodos protegidos (protected) pueden ser usados únicamente por objetos de la misma clase y subclases, a las que pertenece el método; pero nunca por el propio objeto. Por así decirlo, el método sólo lo pueden usar los otros miembro de la familia.
  • private - los métodos privados (private) sólo pueden ser usado por el propio objeto. Técnicamente, se dice que el receptor del método siempre es el mismo: self. El control de acceso se determina dinámicamente, a medida que el programa transcurre. Se obtiene una violación de acceso siempre que se intenta ejecutar un método no público.
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

protected

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