Project

General

Profile

Bug #4537

Incorrectly creating private method via attr_accessor

Added by Ryan LeCompte over 5 years ago. Updated 2 months ago.

Status:
Assigned
Priority:
Normal
Assignee:
ruby -v:
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]
[ruby-core:<unknown>]

Description

The following fails with a failure to call "x=" private method

String.send(:attr_accessor, :x)
s = ""
s.x = 100

The following works:

class String
self.send(:attr_accessor, :x)
end
s = ""
s.x = 100

History

#1 Updated by Ryan LeCompte over 5 years ago

=begin
--- The following fails with a failure to call "x=" private method
String.send(:attr_accessor, :x)
s = ""
s.x = 100

-- The following works:
class String
self.send(:attr_accessor, :x)
end
s = ""
s.x = 100

=end

#2 [ruby-core:37480] Updated by Yui NARUSE over 5 years ago

  • Assignee set to Koichi Sasada
  • Status changed from Open to Assigned

#3 [ruby-core:37490] Updated by Koichi Sasada over 5 years ago

  • Target version set to 2.0.0
  • Category set to core

Behavior: It inherits current visibility (visibility of top-level is "private"). 1.8 also causes an exception. It seems to be a spec.

However, the following code:

::String.send(:define_method, :x=){|v|}
s = ''
s.x = 100

doesn't cause an exception. It seems to be an inconsistency.

The following code doesn't cause an exception on 1.9 and 1.8:

class C
private
::String.send(:define_method, :x=){|v|}
end
s = ''
s.x = 100

However, the following code causes an exception only on 1.8:

class C
private
define_method(:x=){|v|}
end
C.new.x = 10

I can't understand how should it be.

Possible solutions:

(1) Remain it as spec.

(2) All "attr_*" methods define all methods in public.

(3) others?

#4 [ruby-core:50123] Updated by Koichi Sasada about 4 years ago

  • Target version changed from 2.0.0 to next minor

No discussion.

#5 [ruby-core:77024] Updated by bug hit 4 months ago

why should top level visibility (which applies to methods defined in the Object class) have any effect on other classes?

this also applies to any other module which you might be in

class Class1
end

module SomeUnrelatedModule
  Class1.send(:attr_accessor, :public_attr)
  private
  Class1.send(:attr_accessor, :private_attr)
end

c1 = Class1.new
c1.public_attr
c1.private_attr

what does visibility in SomeUnrelatedModule have to do with methods defined in Class1?

methods defined on a given target module when the default definee at the point of definition is not the target module, should be public, since that's the default visibility

Class1.send(:define_method,  :foo) {}

defines a public method

Class1.send(:attr_accessor, :foo)

should too

#6 [ruby-core:77027] Updated by bug hit 4 months ago

define_method used to have the same (or similar) problem
https://bugs.ruby-lang.org/issues/9005

which was fixed, so why shouldn't this be?

#7 [ruby-core:77095] Updated by bug hit 3 months ago

  • Assignee changed from Koichi Sasada to Nobuyoshi Nakada

@nobu shouldn't this get the same treatment as #9005

#8 [ruby-core:77561] Updated by Shyouhei Urabe 2 months ago

  • Status changed from Assigned to Closed
  • ruby -v changed from ruby 1.9.2p180 (2011-02-18 revision 30907) [x86_64-darwin10.7.0] to ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]

#9 [ruby-core:77562] Updated by Shyouhei Urabe 2 months ago

  • Assignee changed from Nobuyoshi Nakada to Koichi Sasada
  • Status changed from Closed to Assigned

#10 [ruby-core:77575] Updated by Shyouhei Urabe 2 months ago

Just FYI we looked at it in developer meeting today and agreed this is a bug that have yet to be fixed.

Also available in: Atom PDF