Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.ruby > #2578 > unrolled thread
| Started by | Kaye Ng <sbstn26@yahoo.com> |
|---|---|
| First post | 2011-04-09 05:24 -0500 |
| Last post | 2011-04-09 17:11 -0500 |
| Articles | 4 — 2 participants |
Back to article view | Back to comp.lang.ruby
private vs. protected question Kaye Ng <sbstn26@yahoo.com> - 2011-04-09 05:24 -0500
Re: private vs. protected question 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-09 14:35 -0500
Re: private vs. protected question 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-09 16:37 -0500
Re: private vs. protected question 7stud -- <bbxx789_05ss@yahoo.com> - 2011-04-09 17:11 -0500
| From | Kaye Ng <sbstn26@yahoo.com> |
|---|---|
| Date | 2011-04-09 05:24 -0500 |
| Subject | private vs. protected question |
| Message-ID | <bd7050a7923405894788738f2712f45b@ruby-forum.com> |
From a book I'm reading:
------------------------------------------------------------------------
class Person
def initialize(age)
@age = age
end
def age
@age
end
def age_difference_with(other_person)
(self.age - other_person.age).abs
end
protected :age
end
fred = Person.new(34)
chris = Person.new(25)
puts chris.age_difference_with(fred)
puts chris.age
-------------------------------------------------------------------------
results in:
9
:20: protected method 'age' called for #<Person:0x1e5f28 @age=25>
(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=25> (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’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!!
--
Posted via http://www.ruby-forum.com/.
[toc] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-09 14:35 -0500 |
| Message-ID | <87c34e7d5a641032304e1f716a3d831e@ruby-forum.com> |
| In reply to | #2578 |
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.
--
Posted via http://www.ruby-forum.com/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-09 16:37 -0500 |
| Message-ID | <d4c1ef1496fe2233a1355c7812e11a19@ruby-forum.com> |
| In reply to | #2584 |
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/.
[toc] | [prev] | [next] | [standalone]
| From | 7stud -- <bbxx789_05ss@yahoo.com> |
|---|---|
| Date | 2011-04-09 17:11 -0500 |
| Message-ID | <ed6be527beec0f1d92a0ea94d3b9f658@ruby-forum.com> |
| In reply to | #2578 |
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/.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.ruby
csiph-web