Project

General

Profile

Feature #11541

Let attr_accessor, _reader & _writer return symbols of the defined methods

Added by iGEL (Johannes Barre) about 5 years ago. Updated almost 2 years ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:<unknown>]

Description

Since Ruby 2.1, def returns a symbol with the name of the just defined method, so you can easily pass it to visibility modifiers like private, protected, and public. Why not let attr_reader & friends return an array with the names of the defined methods, so we can easily write:

private attr_reader :method1, :method2

To fully support the example above, private would be required to accept also arrays with method names. Without it, it would require the star syntax, which would already be an improvement:

private *attr_reader :method1, :method2

I wrote two test cases to better illustrate the impact:

test/ruby/test_module.rb:

  def test_attr_return_value
    c = Class.new

    assert_equal(%i(reader1 reader2), c.class_eval { attr_reader(:reader1, :reader2) })
    assert_equal(%i(writer1= writer2=), c.class_eval { attr_writer(:writer1, :writer2) })
    assert_equal(%i(accessor1 accessor1= accessor2 accessor2=), c.class_eval { attr_accessor(:accessor1, :accessor2) })
  end

test/ruby/test_method.rb:

  def test_visibility_modifier_with_array
    c = Class.new do
      def m1; end
      def m2; end
    end

    c.class_eval { private %i(m1 m2) }
    assert(c.private_method_defined?(:m1))
    assert(c.private_method_defined?(:m2))

    c.class_eval { protected %w(m1 m2) }
    assert(c.protected_method_defined?(:m1))
    assert(c.protected_method_defined?(:m2))

    c.class_eval { public :m1, [:m2] } # Not sure if this should be allowed.
    assert(c.public_method_defined?(:m1))
    assert(c.public_method_defined?(:m2))

    assert_raise(NameError) do
      c.class_eval { private %i(m1 m2 m3) }
    end
    assert(c.private_method_defined?(:m1))
    assert(c.private_method_defined?(:m2))

    assert_raise(TypeError) do
      c.class_eval { protected [:m1, 2] }
    end
    assert(c.private_method_defined?(:m1))

    assert_raise(TypeError) do
      c.class_eval { public [:m1, [:m2]] } # Not sure about this case. Should it be allowed?
    end
    assert(c.public_method_defined?(:m1))
  end

WDYT? Thank you!


Related issues

Related to CommonRuby - Feature #12019: Better low-level support for writing concurrent librariesOpenmatz (Yukihiro Matsumoto)Actions
Related to Ruby master - Feature #14397: public, protected and private should return their arguments instead of selfAssignedmatz (Yukihiro Matsumoto)Actions
Related to Ruby master - Feature #6470: Make attr_accessor return the list of generated methodOpenmatz (Yukihiro Matsumoto)Actions
Related to Ruby master - Feature #9453: Return symbols of defined methods for `attr` and friendsRejectedmatz (Yukihiro Matsumoto)Actions
Related to Ruby master - Feature #13560: Module#attr_ methods return reasonable valuesOpenActions

Also available in: Atom PDF