private vs. protected question

Discussion in 'Ruby' started by Kaye Ng, Apr 9, 2011.

  1. Kaye Ng

    Kaye Ng Guest

    From a book I'm reading:
    ------------------------------------------------------------------------
    class Person
    def initialize(age)
    @age =3D age
    end

    def age
    @age
    end

    def age_difference_with(other_person)
    (self.age - other_person.age).abs
    end

    protected :age
    end

    fred =3D Person.new(34)
    chris =3D Person.new(25)
    puts chris.age_difference_with(fred)
    puts chris.age
    -------------------------------------------------------------------------=

    results in:

    9
    :20: protected method 'age' called for #<Person:0x1e5f28 @age=3D25>
    (NoMethodError)
    ------------------------------------------------------------------------
    The first 'puts' line printed '9' on the screen, while the second
    resulted
    in error. This is because, like 'private', I cannot use a specific
    receiver to call a protected method, correct?

    Now I'm going to replace 'protected' with 'private' (and omit the last
    line (puts chris.age) ). This would result in:

    -------------------------------------------------------------------------=

    H:/Ruby/Practice/six.rb:9:in `age_difference_with': private method `age'
    called for
    #<Person:0x19ccf68 @age=3D25> (NoMethodError)from
    H:/Ruby/Practice/six.rb:16:in `<main>'
    ------------------------------------------------------------------------

    Explanation from the book:
    " if
    age were made private, the preceding example would fail because
    other_person.age would
    be invalid. That=E2=80=99s 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!!

    -- =

    Posted via http://www.ruby-forum.com/.=
     
    Kaye Ng, Apr 9, 2011
    #1
    1. Advertising

  2. Kaye Ng

    7stud -- Guest

    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=E2=80=99s because private makes methods accessible onl=

    y by
    > methods of a specific
    > object."
    >
    > From the statement, "...because private makes methods accessible only b=

    y
    > methods of a specific
    > object.", I'm assuming that it also means 'accessible only by methods o=

    f
    > 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 =3D 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 =3D 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 =3D 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 =3D 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.

    -- =

    Posted via http://www.ruby-forum.com/.=
     
    7stud --, Apr 9, 2011
    #2
    1. Advertising

  3. Kaye Ng

    7stud -- Guest

    7stud -- wrote in post #991945:
    >
    > 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 (or a parent or subclass).


    I think we need to scratch '(or parent...' off the list:

    class Animal
    def meth(obj)
    obj.bark #self=anim whose class is Animal,
    end #and Animal is a parent class of obj=dog
    end

    class Dog < Animal
    protected
    def bark
    puts 'woof'
    end
    end

    dog = Dog.new
    anim = Animal.new
    anim.meth(dog)

    --output:--
    prog.rb:3:in `meth': protected method `bark' called for #<Dog:0x9f8948c>
    (NoMethodError)
    from prog.rb:22:in `<main>'

    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, Apr 9, 2011
    #3
  4. Kaye Ng

    7stud -- Guest

    In case all that was too confusing, to sum up:

    private:
    You can call private methods from inside public methods.

    protected:
    Protected methods act mostly like private methods, but in some cases you
    are allowed to specify a receiver; those cases occur when self is equal
    to a member of the same class as the receiver or a subclass of the
    receiver.

    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, Apr 9, 2011
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andreas Klemt
    Replies:
    2
    Views:
    586
    Andreas Klemt
    Jul 5, 2003
  2. yurps

    protected and private

    yurps, Apr 15, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    430
    Karl Seguin
    Apr 15, 2005
  3. Shapper

    Public, Private, Protected? Thanks.

    Shapper, May 31, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    21,070
    clintonG
    May 31, 2005
  4. =?Utf-8?B?TmFk?=

    private vs protected declaration of User Controls

    =?Utf-8?B?TmFk?=, Jun 7, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    2,742
    =?Utf-8?B?TmFk?=
    Jun 7, 2005
  5. Fasun Lau
    Replies:
    4
    Views:
    110
    7stud --
    May 1, 2009
Loading...

Share This Page