Question about "protected" and "private"

Discussion in 'Ruby' started by Fasun Lau, May 1, 2009.

  1. Fasun Lau

    Fasun Lau Guest

    [Note: parts of this message were removed to make it a legal post.]

    Hi, all
    I'm reading "Programming Ruby", and have some questions about "protected"
    and "private" of class.

    In "Programming Ruby" :

    Protected methods can be invoked only by objects of the defining class and
    its subclasses. Access is kept within the family.
    Private methods cannot be called with an explicit receiver. Because you
    cannot specify an object when using them, private methods can be called only
    in the defining class and by direct descendents within that same object.

    The difference between "protected" and "private" is
    fairly subtle, *and is different in Ruby than in most common OO languages*. If
    a method is protected, it may be called by any instance of the defining
    class or its subclasses. If a method is private, it may be called only
    within the context of the calling object---it is never possible to access
    another object's private methods directly, even if the object is of the same
    class as the caller.

    I was tried it with the follow code:

    C:\Users\v-fsliu>ruby -v
    ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32]

    C:\Users\v-fsliu>irb
    irb(main):001:0> class Demo
    irb(main):002:1> def call1
    irb(main):003:2> method1 + "Object ID: " + self.object_id.to_s
    irb(main):004:2> end
    irb(main):005:1>
    irb(main):006:1* def call2
    irb(main):007:2> method2 + "Object ID: " + self.object_id.to_s
    irb(main):008:2> end
    irb(main):009:1>
    irb(main):010:1* protected
    irb(main):011:1> def method1
    irb(main):012:2> "Hello, Ruby! "
    irb(main):013:2> end
    irb(main):014:1>
    irb(main):015:1* private
    irb(main):016:1> def method2
    irb(main):017:2> "Hi, Ruby! "
    irb(main):018:2> end
    irb(main):019:1> end
    => nil
    irb(main):020:0>
    irb(main):021:0* class NewDemo < Demo
    irb(main):022:1> def newcall
    irb(main):023:2> newmethod + "Object ID: " + self.object_id.to_s
    irb(main):024:2> end
    irb(main):025:1>
    irb(main):026:1* protected
    irb(main):027:1> def newmethod
    irb(main):028:2> "Hello, new demo! "
    irb(main):029:2> end
    irb(main):030:1> end
    => nil
    irb(main):031:0> demo = Demo.new
    => #<Demo:0x3ae9284>
    irb(main):032:0> demo.call1
    => "Hello, Ruby! Object ID: 30886210"
    irb(main):033:0> demo.call2
    => "Hi, Ruby! Object ID: 30886210"
    irb(main):034:0> demo.method1
    NoMethodError: protected method `method1' called for #<Demo:0x3ae9284>
    from (irb):34
    from :0
    irb(main):035:0> newDemo = NewDemo.new
    => #<NewDemo:0x3ae2a24>
    irb(main):036:0> newDemo.newcall
    => "Hello, new demo! Object ID: 30872850"
    irb(main):037:0> newDemo.newmethod
    NoMethodError: protected method `newmethod' called for #<NewDemo:0x3ae2a24>
    from (irb):37
    from :0
    irb(main):038:0>

    My questions are:
    1. It seems that protected methodcalled by any instance of the defining
    class or its subclasses.
    2. what's the different in Ruby than in most common OO languages.

    Thanks and best regards!

    --
    Fasun
     
    Fasun Lau, May 1, 2009
    #1
    1. Advertising

  2. Fasun Lau

    Shaun Keller Guest

    In most OO languages, private methods can only be called from within the
    defining class.

    ie

    class MyClass

    def method1
    method2
    end

    private

    def method2
    end
    end

    A protected method can also be called from subclasses. So if method2 was
    protected, and MySubClass < Class, then method2 could be called from
    within MySubClass.


    In ruby, private and protected methods can be called by any instance of
    the defining class or its subclasses, but private methods cannot have an
    explicit receiver.

    In short, the difference is that protected methods can be called from
    within a class on ANY OBJECT of that class or its subclasses.

    See http://blog.zerosum.org/2007/11/22/ruby-method-visibility for more
    details
    --
    Posted via http://www.ruby-forum.com/.
     
    Shaun Keller, May 1, 2009
    #2
    1. Advertising

  3. Fasun Lau

    Fasun Lau Guest

    [Note: parts of this message were removed to make it a legal post.]

    Got it! Thanks very much!

    2009/5/1 Shaun Keller <>

    >
    > In most OO languages, private methods can only be called from within the
    > defining class.
    >
    > ie
    >
    > class MyClass
    >
    > def method1
    > method2
    > end
    >
    > private
    >
    > def method2
    > end
    > end
    >
    > A protected method can also be called from subclasses. So if method2 was
    > protected, and MySubClass < Class, then method2 could be called from
    > within MySubClass.
    >
    >
    > In ruby, private and protected methods can be called by any instance of
    > the defining class or its subclasses, but private methods cannot have an
    > explicit receiver.
    >
    > In short, the difference is that protected methods can be called from
    > within a class on ANY OBJECT of that class or its subclasses.
    >
    > See http://blog.zerosum.org/2007/11/22/ruby-method-visibility for more
    > details
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >



    --
    Fasun Lau
     
    Fasun Lau, May 1, 2009
    #3
  4. Fasun Lau

    7stud -- Guest

    Fasun Lau wrote:
    > irb(main):020:0>
    > irb(main):021:0* class NewDemo < Demo
    > irb(main):022:1> def newcall
    > irb(main):023:2> newmethod + "Object ID: " + self.object_id.to_s
    > irb(main):024:2> end
    > irb(main):025:1>
    > irb(main):026:1* protected
    > irb(main):027:1> def newmethod
    > irb(main):028:2> "Hello, new demo! "
    > irb(main):029:2> end
    > irb(main):030:1> end
    > => nil
    >
    > irb(main):035:0> newDemo = NewDemo.new
    > => #<NewDemo:0x3ae2a24>
    > irb(main):036:0> newDemo.newcall
    > => "Hello, new demo! Object ID: 30872850"
    > irb(main):037:0> newDemo.newmethod
    > NoMethodError: protected method `newmethod' called for


    Your second example would have worked the same if you hadn't inherited
    from Demo, so it doesn't demonstrate anything new.


    Here are some examples that may prove more illustrative:

    class Demo

    def democall(obj)
    protected_meth #d1 is calling this method
    private_meth #d1 is calling this method

    obj.protected_meth
    obj.private_meth
    end

    protected
    def protected_meth
    puts "hello from protected_meth"
    end

    private
    def private_meth
    puts "hello from private_meth"
    end
    end


    d1 = Demo.new
    d2 = Demo.new
    d1.democall(d2)

    --output:--
    hello from protected_meth
    hello from private_meth
    hello from protected_meth
    r1test.rb:7:in `call': private method `private_meth' called for
    #<Demo:0x24dec> (NoMethodError)
    from r1test.rb:23


    ==========


    Here is an example with some inheritance thrown in:


    class Demo
    protected
    def protected_meth
    puts "hello from protected_meth"
    end

    private
    def private_meth
    puts "hello from private_meth"
    end
    end


    class Bird < Demo
    def birdcall(obj)
    protected_meth #d1 is calling this method
    private_meth #d1 is calling this method

    obj.protected_meth
    end
    end

    b1 = Bird.new
    b2 = Bird.new
    b1.birdcall(b2)

    --output:--
    hello from protected_meth
    hello from private_meth
    hello from protected_meth

    In a language like C++, private methods are not accessible in a
    subclass, so the call to private_meth in Bird would cause an error.

    Note that self is always the object that called the method. For
    example, in this example b1 is calling the method 'call', so inside the
    call method self=b1. And when methods are not called with an object
    name in front of the method, the implicit caller is self. In ruby, they
    call the object that is calling the method "the receiver".







    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, May 1, 2009
    #4
  5. Fasun Lau

    7stud -- Guest

    7stud -- wrote:
    >
    > Here is an example with some inheritance thrown in:
    >
    >
    > class Demo
    > protected
    > def protected_meth
    > puts "hello from protected_meth"
    > end
    >
    > private
    > def private_meth
    > puts "hello from private_meth"
    > end
    > end
    >
    >
    > class Bird < Demo
    > def birdcall(obj)
    > protected_meth #d1 is calling this method
    > private_meth #d1 is calling this method
    >
    > obj.protected_meth
    > end
    > end
    >
    > b1 = Bird.new
    > b2 = Bird.new
    > b1.birdcall(b2)
    >
    > --output:--
    > hello from protected_meth
    > hello from private_meth
    > hello from protected_meth
    >
    > In a language like C++, private methods are not accessible in a
    > subclass, so the call to private_meth in Bird would cause an error.
    >
    > Note that self is always the object that called the method. For
    > example, in this example b1 is calling the method 'call', so inside the
    > call method self=b1. And when methods are not called with an object
    > name in front of the method, the implicit caller is self. In ruby, they
    > call the object that is calling the method "the receiver".


    Oh boy. Corrections:

    class Demo
    protected
    def protected_meth
    puts "hello from protected_meth"
    end

    private
    def private_meth
    puts "hello from private_meth"
    end
    end


    class Bird < Demo
    def birdcall(obj)
    protected_meth #b1 is calling this method
    private_meth #b1 is calling this method

    obj.protected_meth
    end
    end

    b1 = Bird.new
    b2 = Bird.new
    b1.birdcall(b2)

    --output:--
    hello from protected_meth
    hello from private_meth
    hello from protected_meth

    In a language like C++, private methods are not accessible in a
    subclass, so the call to private_meth in Bird would cause an error.

    Note that self is always the object that called the method. For
    example, in this example b1 is calling the method birdcall, so inside
    the
    birdcall method self=b1. And when methods are not called with an object
    name in front of the method, the implicit caller is self. In ruby, they
    call the object that is calling the method "the receiver".
    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, May 1, 2009
    #5
    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:
    569
    Andreas Klemt
    Jul 5, 2003
  2. yurps

    protected and private

    yurps, Apr 15, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    426
    Karl Seguin
    Apr 15, 2005
  3. bigbinc
    Replies:
    7
    Views:
    38,024
    Dale King
    Sep 22, 2003
  4. Chris Mantoulidis
    Replies:
    6
    Views:
    647
    Grimble Gromble
    Jan 3, 2004
  5. Kaye Ng

    private vs. protected question

    Kaye Ng, Apr 9, 2011, in forum: Ruby
    Replies:
    3
    Views:
    191
    7stud --
    Apr 9, 2011
Loading...

Share This Page