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?
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:
class C
Does anyone understand this warning? Is ‘private’ (without an argument)
deprecated?
Rein H. 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.
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 H. 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.
On 2010-06-05 17:02:17 -0700, Joel VanderWerf said:
Anyway, attr_accessor is already a private module method in ruby, but
the instance methods it creates are not, by default.
I stand corrected. Interesting.
On Jun 5, 6:25 pm, Joel VanderWerf [email protected] wrote:
attr_accessor :x
$ 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?
Maybe is because you’re setting private for all the following methods,
including the ones that attr_accessor defines moving forward after the
“extending”?
if you change the private to ‘private :attr_accessor’ there is no
warning and things works.
Luis L. wrote:
extend M
noticed that there is a warning reported with the -v switch:
Maybe is because you’re setting private for all the following methods,
including the ones that attr_accessor defines moving forward after the
“extending”?
if you change the private to ‘private :attr_accessor’ there is no
warning and things works.
True. However:
$ cat t.rb
module M
private
def attr_accessor(*args); super; end
public # <-- added this line
end
class C
extend M
attr_accessor :x
end
C.new.x = 1
$ ruby t.rb
$ ruby19 t.rb
t.rb:12:in <main>': private method
x=’ called for
#<C:0x00000001e40858> (NoMethodError)
Luis L. wrote:
Maybe is because you’re setting private for all the following methods,
including the ones that attr_accessor defines moving forward after the
“extending”?
That’s probably true in some sense (some state is getting set and
affecting the methods defined by attr_accessor), but it’s not setting
other methods private:
$ cat t.rb
module M
private
def attr_accessor(*args); super; end
end
class C
extend M
def m; puts “m”; end
attr_accessor :x
end
C.new.m
C.new.x = 1
$ ruby19 t.rb
m
t.rb:13:in <main>': private method
x=’ called for
#<C:0x00000002442148> (NoMethodError)