Project

General

Profile

Bug #4537

Incorrectly creating private method via attr_accessor

Added by Ryan LeCompte over 5 years ago. Updated 27 days ago.

Status:
Assigned
Priority:
Normal
ruby -v:
ruby 1.9.2p180 (2011-02-18 revision 30907) [x86_64-darwin10.7.0]
[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 about 5 years ago

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

#3 [ruby-core:37490] Updated by Koichi Sasada about 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 almost 4 years ago

  • Target version changed from 2.0.0 to next minor

No discussion.

#5 [ruby-core:77024] Updated by bug hit about 1 month 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 about 1 month 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 27 days ago

  • Assignee changed from Koichi Sasada to Nobuyoshi Nakada

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

Also available in: Atom PDF