From: Joel VanderWerf on

Consider this error:

$ cat t.rb
module M
private
def attr_accessor(*args); super; end
end

class C
extend M
attr_accessor :x
end

C.new.x = 1

$ ruby19 t.rb
t.rb:11:in `<main>': private method `x=' called for
#<C:0x0000000091c670> (NoMethodError)


That looks very suspect, so I was about to file a bug report. But then I
noticed that there is a warning reported with the -v switch:

$ ruby19 -v t.rb
ruby 1.9.2dev (2010-05-31) [x86_64-linux]
t.rb:3: warning: private attribute?
t.rb:11:in `<main>': private method `x=' called for
#<C:0x000000012e5670> (NoMethodError)


Does anyone understand this warning? Is 'private' (without an argument)
deprecated?


From: Rein Henrichs on
This behavior seems consistent with, for instance:

class PrivateAccessor
private
attr_accessor :foo
end

PrivateAccessor.new.foo
# => NoMethodError: private method `foo' called for
#<PrivateAccessor:0x1017bbce8>

On 2010-06-05 15:25:59 -0700, Joel VanderWerf said:

> Consider this error:
>
> $ cat t.rb
> module M
> private
> def attr_accessor(*args); super; end
> end
>
> class C
> extend M
> attr_accessor :x
> end
>
> C.new.x = 1
>
> $ ruby19 t.rb
> t.rb:11:in `<main>': private method `x=' called for
> #<C:0x0000000091c670> (NoMethodError)
>
>
> That looks very suspect, so I was about to file a bug report. But then I
> noticed that there is a warning reported with the -v switch:
>
> $ ruby19 -v t.rb
> ruby 1.9.2dev (2010-05-31) [x86_64-linux]
> t.rb:3: warning: private attribute?
> t.rb:11:in `<main>': private method `x=' called for
> #<C:0x000000012e5670> (NoMethodError)
>
>
> Does anyone understand this warning? Is 'private' (without an argument)
> deprecated?


--
Rein Henrichs
http://puppetlabs.com
http://reinh.com

From: Joel VanderWerf on
> On 2010-06-05 15:25:59 -0700, Joel VanderWerf said:
>
>> Consider this error:
>>
>> $ cat t.rb
>> module M
>> private
>> def attr_accessor(*args); super; end
>> end
>>
>> class C
>> extend M
>> attr_accessor :x
>> end
>>
>> C.new.x = 1
>>
>> $ ruby19 t.rb
>> t.rb:11:in `<main>': private method `x=' called for
>> #<C:0x0000000091c670> (NoMethodError)
>>
>>
>> That looks very suspect, so I was about to file a bug report. But then I
>> noticed that there is a warning reported with the -v switch:
>>
>> $ ruby19 -v t.rb
>> ruby 1.9.2dev (2010-05-31) [x86_64-linux]
>> t.rb:3: warning: private attribute?
>> t.rb:11:in `<main>': private method `x=' called for
>> #<C:0x000000012e5670> (NoMethodError)
>>
>>
>> Does anyone understand this warning? Is 'private' (without an argument)
>> deprecated?
>
>

Rein Henrichs wrote:
> This behavior seems consistent with, for instance:
>
> class PrivateAccessor
> private
> attr_accessor :foo
> end
>
> PrivateAccessor.new.foo
> # => NoMethodError: private method `foo' called for
> #<PrivateAccessor:0x1017bbce8>


No. The original code is controlling access to the method
Module#attr_accessor. Your code is controlling access to
PrivateAccessor#foo.

From: Rein Henrichs on
On 2010-06-05 15:55:20 -0700, Joel VanderWerf said:
>
> No. The original code is controlling access to the method
> Module#attr_accessor. Your code is controlling access to
> PrivateAccessor#foo.

Not exactly. Methods created by attr_accessor will have its visibility.
Your code makes attr_accessor private, which is why accessors created
with it are also private. You can also demonstrate by writing your own
attr_accessor from scratch.

--
Rein Henrichs
http://puppetlabs.com
http://reinh.com

From: Joel VanderWerf on
Rein Henrichs wrote:
> On 2010-06-05 15:55:20 -0700, Joel VanderWerf said:
>>
>> No. The original code is controlling access to the method
>> Module#attr_accessor. Your code is controlling access to
>> PrivateAccessor#foo.
>
> Not exactly. Methods created by attr_accessor will have its visibility.
> Your code makes attr_accessor private, which is why accessors created
> with it are also private. You can also demonstrate by writing your own
> attr_accessor from scratch.

Did you try that? The following code runs the same in 1.8 and 1.9:

class C
class << self
def my_attr_accessor(name)
define_method name do
puts "foo"
end
end
private :my_attr_accessor
end

my_attr_accessor :bar
end

C.new.bar # => foo


Anyway, attr_accessor is already a private module method in ruby, but
the instance methods it creates are not, by default.