Prev: Processing (potentially) nil method without using nested if
Next: threads & mutex question (Rubyist book example)
From: Joel VanderWerf on 5 Jun 2010 18:25 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 5 Jun 2010 18:42 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 5 Jun 2010 18:55 > 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 5 Jun 2010 19:47 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 5 Jun 2010 20:02
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. |