Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > why can't an instance instantiated within a class method access aprotected instance method?

Reply
Thread Tools

why can't an instance instantiated within a class method access aprotected instance method?

 
 
Greg Hauptmann
Guest
Posts: n/a
 
      06-15-2008
[Note: parts of this message were removed to make it a legal post.]

Hi,
Why can't an instance instantiated within a class method access a protected
instance method?

e.g.

class Recurring < ActiveRecord::Base
def self.reconcile t = Transaction.find(:first)

 
Reply With Quote
 
 
 
 
Greg Hauptmann
Guest
Posts: n/a
 
      06-15-2008
[Note: parts of this message were removed to make it a legal post.]

(complete email)Hi,

Why can't an instance instantiated within a class method access a protected
instance method?

e.g.

class Recurring < ActiveRecord::Base

def self.reconcile rs = Recurring.find(:all)
rs.each do |r|
r.reconcile_one
end
end

protected

def reconcile_one
# do something
end

end

 
Reply With Quote
 
 
 
 
Florian Gilcher
Guest
Posts: n/a
 
      06-15-2008
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


On Jun 15, 2008, at 12:37 PM, Greg Hauptmann wrote:

> (complete email)Hi,
>
> Why can't an instance instantiated within a class method access a
> protected
> instance method?
>
> e.g.
>
> class Recurring < ActiveRecord::Base
>
> def self.reconcile rs = Recurring.find(:all)
> rs.each do |r|
> r.reconcile_one
> end
> end
>
> protected
>
> def reconcile_one
> # do something
> end
>
> end


Because calling a Method with an explicit receiver is like "calling
from the outside".

Regards,
Florian Gilcher
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)

iEYEARECAAYFAkhVCkAACgkQJA/zY0IIRZafKQCghgHXBhTmfp3eCYVWTbQempIp
EwcAoJqNwn9FkHgTZjt9/jc14+PeD0A5
=nITW
-----END PGP SIGNATURE-----

 
Reply With Quote
 
David A. Black
Guest
Posts: n/a
 
      06-15-2008
Hi --

On Sun, 15 Jun 2008, Florian Gilcher wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
>
> On Jun 15, 2008, at 12:37 PM, Greg Hauptmann wrote:
>
>> (complete email)Hi,
>>
>> Why can't an instance instantiated within a class method access a protected
>> instance method?
>>
>> e.g.
>>
>> class Recurring < ActiveRecord::Base
>>
>> def self.reconcile rs = Recurring.find(:all)
>> rs.each do |r|
>> r.reconcile_one
>> end
>> end
>>
>> protected
>>
>> def reconcile_one
>> # do something
>> end
>>
>> end

>
> Because calling a Method with an explicit receiver is like "calling from the
> outside".


It's not quite that. Protected methods can be called with an explicit
receiver, but they can only be called on objects that are of the same
class as self (or a subclass thereof). In self.reconcile, self is
Recurring, and therefore of class Class, while rs is of class
Recurring.


David

--
Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS June 16-19 Berlin
ADVANCING WITH RAILS July 21-24 Edison, NJ
See http://www.rubypal.com for details and updates!

 
Reply With Quote
 
Greg Hauptmann
Guest
Posts: n/a
 
      06-15-2008
[Note: parts of this message were removed to make it a legal post.]

On Sun, Jun 15, 2008 at 11:03 PM, David A. Black <(E-Mail Removed)> wrote:

> Hi --
> On Sun, 15 Jun 2008, Florian Gilcher wrote:
>
> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>>
>> On Jun 15, 2008, at 12:37 PM, Greg Hauptmann wrote:
>>
>> (complete email)Hi,
>>>
>>> Why can't an instance instantiated within a class method access a
>>> protected
>>> instance method?
>>>
>>> e.g.
>>>
>>> class Recurring < ActiveRecord::Base
>>>
>>> def self.reconcile rs = Recurring.find(:all)
>>> rs.each do |r|
>>> r.reconcile_one
>>> end
>>> end
>>>
>>> protected
>>>
>>> def reconcile_one
>>> # do something
>>> end
>>>
>>> end
>>>

>>
>> Because calling a Method with an explicit receiver is like "calling from
>> the outside".
>>

>
> It's not quite that. Protected methods can be called with an explicit
> receiver, but they can only be called on objects that are of the same
> class as self (or a subclass thereof). In self.reconcile, self is
> Recurring, and therefore of class Class, while rs is of class
> Recurring.
>
>
> David



Thanks - can I ask:
(a) what do you mean by "explicit" - just to understand
(b) is there a way I can adjust my code so that I can leave methods like
"reconcile_one" private or protected, i.e. not really to be available to the
outside world (except in this case where I'm calling it from with an
instance of the class really, but it's just the logistics of Ruby that isn't
allowing it to work...if I've understood things correctly)

Greg

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      06-15-2008
On 15.06.2008 15:17, Greg Hauptmann wrote:
> Thanks - can I ask:


Guess so.

> (a) what do you mean by "explicit" - just to understand


no_explicit_receiver()
self.has_explicit_receiver()

> (b) is there a way I can adjust my code so that I can leave methods like
> "reconcile_one" private or protected, i.e. not really to be available to the
> outside world (except in this case where I'm calling it from with an
> instance of the class really, but it's just the logistics of Ruby that isn't
> allowing it to work...if I've understood things correctly)


You can use #send or #instance_eval, e.g.

irb(main):001:0> class F
irb(main):002:1> protected
irb(main):003:1> def x;1 end
irb(main):004:1> end
=> nil
irb(main):005:0> f=F.new
=> #<F:0x7ff94460>
irb(main):006:0> f.x
NoMethodError: protected method `x' called for #<F:0x7ff94460>
from (irb):6
from :0
irb(main):007:0> f.instance_eval { x }
=> 1
irb(main):008:0> f.send
=> 1
irb(main):009:0>

Cheers

robert
 
Reply With Quote
 
Greg Hauptmann
Guest
Posts: n/a
 
      06-15-2008
[Note: parts of this message were removed to make it a legal post.]

On Sun, Jun 15, 2008 at 11:29 PM, Robert Klemme <(E-Mail Removed)>
wrote:

> On 15.06.2008 15:17, Greg Hauptmann wrote:
>
>> Thanks - can I ask:
>>

>
> Guess so.
>
> (a) what do you mean by "explicit" - just to understand
>>

>
> no_explicit_receiver()
> self.has_explicit_receiver()
>
> (b) is there a way I can adjust my code so that I can leave methods like
>> "reconcile_one" private or protected, i.e. not really to be available to
>> the
>> outside world (except in this case where I'm calling it from with an
>> instance of the class really, but it's just the logistics of Ruby that
>> isn't
>> allowing it to work...if I've understood things correctly)
>>

>
> You can use #send or #instance_eval, e.g.
>
> irb(main):001:0> class F
> irb(main):002:1> protected
> irb(main):003:1> def x;1 end
> irb(main):004:1> end
> => nil
> irb(main):005:0> f=F.new
> => #<F:0x7ff94460>
> irb(main):006:0> f.x
> NoMethodError: protected method `x' called for #<F:0x7ff94460>
> from (irb):6
> from :0
> irb(main):007:0> f.instance_eval { x }
> => 1
> irb(main):008:0> f.send
> => 1
> irb(main):009:0>
>
> Cheers
>
> robert
>


Thanks Robert - do you understand why Ruby allows the "send " method to
work here, but not the ".x" out of curiosity? Does this make sense to
people it should do this?
Greg

 
Reply With Quote
 
David A. Black
Guest
Posts: n/a
 
      06-15-2008
Hi --

On Sun, 15 Jun 2008, Greg Hauptmann wrote:

> On Sun, Jun 15, 2008 at 11:29 PM, Robert Klemme <(E-Mail Removed)>
> wrote:
>
>> On 15.06.2008 15:17, Greg Hauptmann wrote:
>>
>>> Thanks - can I ask:
>>>

>>
>> Guess so.
>>
>> (a) what do you mean by "explicit" - just to understand
>>>

>>
>> no_explicit_receiver()
>> self.has_explicit_receiver()
>>
>> (b) is there a way I can adjust my code so that I can leave methods like
>>> "reconcile_one" private or protected, i.e. not really to be available to
>>> the
>>> outside world (except in this case where I'm calling it from with an
>>> instance of the class really, but it's just the logistics of Ruby that
>>> isn't
>>> allowing it to work...if I've understood things correctly)
>>>

>>
>> You can use #send or #instance_eval, e.g.
>>
>> irb(main):001:0> class F
>> irb(main):002:1> protected
>> irb(main):003:1> def x;1 end
>> irb(main):004:1> end
>> => nil
>> irb(main):005:0> f=F.new
>> => #<F:0x7ff94460>
>> irb(main):006:0> f.x
>> NoMethodError: protected method `x' called for #<F:0x7ff94460>
>> from (irb):6
>> from :0
>> irb(main):007:0> f.instance_eval { x }
>> => 1
>> irb(main):008:0> f.send
>> => 1
>> irb(main):009:0>
>>
>> Cheers
>>
>> robert
>>

>
> Thanks Robert - do you understand why Ruby allows the "send " method to
> work here, but not the ".x" out of curiosity? Does this make sense to
> people it should do this?


Private and protected are really only advisory, since you can in fact
always get around them. The idea is to have the most common
method-calling technique (the dot) respect them, so that if you want
to get around them, you have to make a point of using one of the other
techniques.


David

--
Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS June 16-19 Berlin
ADVANCING WITH RAILS July 21-24 Edison, NJ
See http://www.rubypal.com for details and updates!

 
Reply With Quote
 
J. Cooper
Guest
Posts: n/a
 
      06-15-2008

>> Thanks Robert - do you understand why Ruby allows the "send " method to
>> work here, but not the ".x" out of curiosity? Does this make sense to
>> people it should do this?


The whole point of the private/protected method deal is to prevent what
you are trying to do Ruby, having lots of metaprogramming
capabilities, lets you get around this "if you really know what you are
doing" -- as you can see, it's a bit more of a pain then just the
standard way of calling a method. It's to help keep you honest.

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Loren Segal
Guest
Posts: n/a
 
      06-16-2008
> Does this make sense to people it should do this?

Should people use send() to get around protected method visibility? No.

Do they? Yes.

Is it justified? Sometimes it is, sometimes it isn't.

Having to send() to get around a visibility issue usually implies that
there's some API design problem in the code you're using. The reason its
usage is sometimes justified is simply because you don't own everybody
else's code and you can't be held liable for their mistakes. There's
also the case where you simply have no other choice.

I think in this scenario you really need to ask yourself why the method
is protected to begin with. I see nothing in your code that would have
me believe that your `self.reconcile` method *must* come from the
metaclass of the object. In fact, it looks like a factory method that
could ideally be called from anywhere. That to me constitutes public
method, especially since what's really happening is: "grab a bunch of
objects and call `reconcile_once` on them"... I see no reason why some
fictional `MyOtherClass` wouldn't be able to do the same thing with your
objects.

Loren
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
instance method adding another instance method to the class Raj Singh Ruby 2 05-29-2008 10:09 PM
why a class can't access protected method from another class in thesame package,the method is interited from the ohtner class from differntpackage? junzhang1983@gmail.com Java 3 01-28-2008 02:09 AM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
Why an Abstract Base Class cannot be instantiated ? Dev C++ 8 10-09-2005 08:29 PM
Cannot refer to an instance member of a class from within a shared method or shared member initializer without an explicit instance of the class. DJ Dev ASP .Net 3 02-08-2004 04:19 PM



Advertisments