![]() |
why can't an instance instantiated within a class method access aprotected instance method?
[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) |
Re: why can't an instance instantiated within a class method accessa protected instance method?
[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 |
Re: why can't an instance instantiated within a class method accessa protected instance method?
-----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----- |
Re: why can't an instance instantiated within a class method accessa protected instance method?
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! |
Re: why can't an instance instantiated within a class method accessa protected instance method?
[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 <dblack@rubypal.com> 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 |
Re: why can't an instance instantiated within a class method accessa protected instance method?
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 :x => 1 irb(main):009:0> Cheers robert |
Re: why can't an instance instantiated within a class method accessa protected instance method?
[Note: parts of this message were removed to make it a legal post.]
On Sun, Jun 15, 2008 at 11:29 PM, Robert Klemme <shortcutter@googlemail.com> 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 :x > => 1 > irb(main):009:0> > > Cheers > > robert > Thanks Robert - do you understand why Ruby allows the "send :x" method to work here, but not the ".x" out of curiosity? Does this make sense to people it should do this? Greg |
Re: why can't an instance instantiated within a class method accessa protected instance method?
Hi --
On Sun, 15 Jun 2008, Greg Hauptmann wrote: > On Sun, Jun 15, 2008 at 11:29 PM, Robert Klemme <shortcutter@googlemail.com> > 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 :x >> => 1 >> irb(main):009:0> >> >> Cheers >> >> robert >> > > Thanks Robert - do you understand why Ruby allows the "send :x" 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! |
Re: why can't an instance instantiated within a class method
>> Thanks Robert - do you understand why Ruby allows the "send :x" 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/. |
Re: why can't an instance instantiated within a class method accessa protected instance method?
> 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/. |
| All times are GMT. The time now is 10:12 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.