Kaye Ng wrote in post #991911:
>
> Explanation from the book:
> " if
> age were made private, the preceding example would fail because
> other_person.age would
> be invalid. That”Ēs because private makes methods accessible only by
> methods of a specific
> object."
>
> From the statement, "...because private makes methods accessible only by
> methods of a specific
> object.", I'm assuming that it also means 'accessible only by methods of
> a single and CURRENT object', and that current object is 'chris', not
> 'fred', and that is why it resulted in error.
>
> Am I wrong??
> Help please! Thank you!!

That explanation is about as clear as mud.  The rule for private methods is simple:  you cannot call private methods with an explicit receiver. Here is an example:

class Dog
  def bark
    puts 'woof'
  end
end

dog = Dog.new
dog.bark

--output:--
woof

In the last line, dog is the 'receiver'.  If bark() is a private method, you can't call it with a receiver, so that line would produce an error:

class Dog
  private
  def bark
    puts 'woof'
  end

end

dog = Dog.new
dog.bark

--output:--
prog.rb:10:in `<main>': private method `bark' called for #<Dog:0xa1acde0> (NoMethodError)


The implications of the private method rule are a little bit tougher to understand.  How can you call bark() on an object if you are not allowed to specify the object as the receiver?  Well, in ruby if you call a method without a receiver, then something called self becomes the receiver by default--self is the implicit receiver.

Therefore, you must understand what object self is equal to in various parts of your code:

puts self  #main

class Dog
  puts self  #Dog

  def bark
    puts self  #<Dog:0x8e05c10>,
    puts 'woof'
  end

end

dog = Dog.new
puts dog  #<Dog:0x8e05c10>

dog.bark  #woof

ruby's notation for a dog object is the name of the class plus an id number:

#<Dog:0x8e05c10>

Note what self is inside the bark method: it's the same object that called the method(compare the id numbers), which is dog.   That means you can call private instance methods from inside public instance methods:

class Dog
  def do_stuff
    bark
  end

  private
  def bark
    puts 'woof'
  end

end

dog = Dog.new
dog.do_stuff

--output:--
woof

The code works like this:  dog calls do_stuff, so inside do_stuff self is equal to dog.  Because the private method bark() is called without a receiver, the implicit receiver is self, which in this case is equal to dog.  And that is how you call a private method on an object like dog.

The protected method rule states that you can use a receiver to call the method--so long as whatever object is self at that time is also an object of the same class as the receiver.