ActiveRecord::AttributeMethods #respond_to?

John, this is a _fantastic_ point. It's certainly true that there would be no way to use the "setter" half of a private attr_accessor in a regular Ruby object:

self.bar = 'baz' # violates private bar = 'baz' # sets a local variable

Well, no, that would be silly. Private methods in Ruby are fairly gimpy*, but mercifully not that gimpy. Ruby has a special case to allow the self.bar = 'baz' syntax with a private accessor for bar. Try it. However, this does cause problems with compound operators; for instance, this won't work:

class Foo   def initialize     self.bar ||= "bar" # calls self.bar under the covers; NoMethodError.     bar || = "bar" # sets a local variable.   end   private   attr_accessor :bar end

In any case, I've always been a fan of judicious use of access control, so I agree with Gaius that ActiveRecord attributes and association proxies should act in a consistent manner in this regard. I've submitted a patch for the issue brought up by acechase earlier in this thread (http://rails.lighthouseapp.com/projects/8994-ruby-on- rails/tickets/1083-calls-to-private-methods-via-association-proxies- should-act-consistently-with-ruby-method-dispatch). I hope to submit a second patch for the initial issue soon.

Interestingly, fixing the initial tests I wrote causes one unexpected test failure, which is the reason for the line change in has_one_association.rb. The method was calling #quote_value on the instance (which is private) rather than #quote_value on the class (which is public). All other calls to #quote_value in the nearby code used the class method, which makes me think this was perhaps an extremely minor bug; but, a bug exposed by proper access control.

*Incidentally, the fact that anyone can circumvent access control in Ruby via the #send method isn't what makes me think it gimped. The fact is, this still forces any consumers of my interface to make an explicit decision to ignore my suggested usage. At this point they know they've voided the warranty and proceed at their own peril. My concerns with private methods in Ruby center more on how difficult they are to use within the class that does have access to them; disallowing an explicit sender, even when that sender is self, can handicap readability in some cases, and leads to inconsistent usage patterns, like the example I gave above with the ||= operator.

I've submitted a patch with the behavior requested way back at the beginning of this thread:

http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/1084-activerecord-attributes-should-respect-access-control