Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

accessing protected methods in Ruby

Tags:

protected

ruby

I am trying to work our for myself access modifiers in Ruby. I have:

class Person
  def initialize (first_name, last_name, age)
        @first_name=first_name
        @last_name=last_name
        @age=age
    end


    def show()
        puts @first_name
        puts @last_name
        puts @age
    end

protected
  def compare(other)
    self.instance_variable_get(:@age)<=>other.instance_variable_get(:@age)
  end

end

p1=Person.new("Some", "Body", "99")
p1.show
puts "\n"

p2=Person.new("Who", "Ever", "21")
p2.show
puts "\n"

p1.compare(p2)

I am getting the error "protected method `compare' called for # (NoMethodError)" I have tried calling from within the class and without. I pasted the without version here. I thought that protected methods could be called on other objects of the same class. What does this error mean and how would I properly use a protected method here? Thank you for your help.

like image 985
e_n Avatar asked Sep 07 '14 11:09

e_n


Video Answer


1 Answers

You got the wrong view of the protected visibility. The Ruby doc says:

The second visibility is protected. When calling a protected method the sender must be a subclass of the receiver or the receiver must be a subclass of the sender. Otherwise a NoMethodError will be raised.

So the restriction of the visibility is applied to the sender, not the receiver as what you thought.

If you want to call compare outside of the instance methods, you need to use public visibility. You need to remove the protected modifier if you can. This is the recommended way.

If the code is fixed and you cannot modify that piece of code, you can use the Object#send method. Object#send will bypass the visibility constraint and can access even private methods.

p1.send(:compare, p2)

Or you can reopen the class and change the visibility of the compare class:

# you code here

# reopen and modify visibility
class Person
  public :compare
end

p1.compare(p2)
like image 70
Arie Xiao Avatar answered Dec 10 '22 08:12

Arie Xiao