Visibilidad de los métodos en Ruby

posted on 10 Mar 2010 | Ruby

Algo que no queda del todo claro a la mayoria de gente que aprende Ruby, incluso a los que ya tienen cierta experiencia es como funciona exactamente la visibilidad de los métodos en Ruby. Según sus definiciones:

  • public: pueden ser invocado por cualquiera. Los métodos son public por defecto, excepto el método initialize que es privado.

  • protected: pueden ser invocados por cualquier objeto de la clase o cualquier objeto de las clases heredadas.

  • private: solo se pueden invocar desde el contexto del objecto actual. No se pueden invocar métodos private de otros objetos aunque sean de la misma clase.

La diferencia entre protected y private es sútil, pero es importante tenerla clara. Vamos a intentar aclararlo con un ejemplo.

# person.rb
class Person  
  def es_mayor_que?(p)
    self.age > p.age
  end
  
  protected
  def age
    calculate_age
  end
  
  private
  def calculate_age
    rand(99)
  end
end

El método es_mayor_que? es público y nos va a servir para comparar la edad de dos personas a ver cual es mayor.

El método age está declarado como protected ya que en principio no lo necesitamos fuera del contexto del objeto, únicamente necesitamos acceder al método age para comparar las edades de dos personas.

El método calculate_age es privado ya que nos genera una edad para un objeto determinado y necesitamos que sea únicamente accesible desde el objeto en cuestión.

>> require 'person'
>> quentin = Person.new
>> aaron = Person.new
>> quentin.es_mayor_que? aaron
=> true
>> aaron.es_mayor_que? quentin
=> false

Uso de self

  • Los métodos public pueden ser invocados con self o sin él, o dicho de una manera más técnica, el receptor puede ser cualquiera.
  • Los métodos protected pueden ser invocados por self o por otro objeto. Cuando invocamos un método protected, self puede ser ignorado.
  • Los métodos private no se invocan nunca con self ya que está implicito y por definición no pueden ser invocados por nadie más.

Referencias

weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby
blog.zerosum.org/2007/11/22/ruby-method-visibility