Feature #9453

Return symbols of defined methods for `attr` and friends

Added by Joshua Ballanco about 1 year ago. Updated 9 months ago.

[ruby-core:60112]
Status:Rejected
Priority:Normal
Assignee:Yukihiro Matsumoto

Description

With Ruby 2.1 returning a symbol from def and define_method, that leaves attr, attr_reader, attr_writer, and attr_accessor as ways to define methods that still return nil. This is unfortunate, because it prevents the use of method decorators developed to work with def from also working with the attr* methods. Because these mechanisms can define more than one method, the return values would need to be arrays of symbols.

For an example of how this could be useful in real-world code, consider this sample from James Edward Gray II's Warehouse Keeper example (https://github.com/JEG2/warehouse_keeper):

attr_reader :images, :key_map, :window, :screen_manager, :animations
private     :images, :key_map, :window, :screen_manager, :animations

if attr_reader returned symbols, then this could be simplified to:

private *attr_reader(:images, :key_map, :window, :screen_manager, :animations)

I've attached a patch that implements this change and includes a few tests. For those who use git, I've also submitted this as a pull request here: https://github.com/ruby/ruby/pull/517

attr_rv.patch Magnifier - Patch to add return values to attr* methods (3.23 KB) Joshua Ballanco, 01/26/2014 05:51 PM

History

#1 Updated by Joshua Ballanco about 1 year ago

bump

Would be nice if we could get this in 2.2 (if someone could update the target version, I'd appreciate it).

#2 Updated by Benoit Daloze about 1 year ago

private *attr_reader(:images, :key_map, :window, :screen_manager, :animations)

does not look so nice to me (the parens and the explicit splat).
Maybe #private should accept an Array of Symbols so:

private attr_reader :images, :key_map, :window, :screen_manager, :animations

If there are so much ":", it might also be worth using %i:

private attr_reader %i[images key_map window screen_manager animations]

but then attr_reader would also need to accept an Array of Symbols.

#3 Updated by Tsuyoshi Sawada about 1 year ago

What is the point of defining a private accessor method? You can directly refer to the instance variables without using accessors.

#4 Updated by Avdi Grimm about 1 year ago

There are a number of reasons I use them, but the most obvious is that a
misspelled accessor method will raise NoMethod error, whereas a misspelled
@ivar reference will silently return nil.

On Mon, Feb 3, 2014 at 1:44 PM, sawadatsuyoshi@gmail.com wrote:

Issue #9453 has been updated by Tsuyoshi Sawada.

What is the point of defining a private accessor method? You can directly
refer to the instance variables without using accessors.


Feature #9453: Return symbols of defined methods for attr and friends
https://bugs.ruby-lang.org/issues/9453#change-44898

  • Author: Joshua Ballanco
  • Status: Open
  • Priority: Normal
  • Assignee:
  • Category: core

* Target version:

With Ruby 2.1 returning a symbol from def and define_method, that
leaves attr, attr_reader, attr_writer, and attr_accessor as ways to
define methods that still return nil. This is unfortunate, because it
prevents the use of method decorators developed to work with def from
also working with the attr* methods. Because these mechanisms can define
more than one method, the return values would need to be arrays of symbols.

For an example of how this could be useful in real-world code, consider
this sample from James Edward Gray II's Warehouse Keeper example (
https://github.com/JEG2/warehouse_keeper):

attr_reader :images, :key_map, :window, :screen_manager, :animations
private     :images, :key_map, :window, :screen_manager, :animations

if attr_reader returned symbols, then this could be simplified to:

private *attr_reader(:images, :key_map, :window, :screen_manager,

:animations)

I've attached a patch that implements this change and includes a few
tests. For those who use git, I've also submitted this as a pull request
here: https://github.com/ruby/ruby/pull/517

---Files--------------------------------
attr_rv.patch (3.23 KB)

http://bugs.ruby-lang.org/

--
Avdi Grimm
http://avdi.org

I only check email twice a day. to reach me sooner, go to
http://awayfind.com/avdi

#5 Updated by Joshua Ballanco about 1 year ago

Tsuyoshi Sawada wrote:

What is the point of defining a private accessor method? You can directly refer to the instance variables without using accessors.

The example I gave was just one case of "code in the wild" that would benefit from this change. Undoubtedly, as more people begin to take advantage of the ability to build method decorators (now that method definitions return something other than nil), having the attr* family of methods return something meaningful will mean that they can also benefit from these decorators.

#6 Updated by Joshua Ballanco about 1 year ago

It's been almost 2 months...any chance we could get a comment on this from the core team?

#7 Updated by Usaku NAKAMURA about 1 year ago

  • Status changed from Open to Assigned
  • Assignee set to Yukihiro Matsumoto

#8 Updated by Yukihiro Matsumoto about 1 year ago

  • Status changed from Assigned to Rejected

I am not positive. The example

private *attr_reader(:images, :key_map, :window, :screen_manager,:animations)

is not really intuitive. Besides that, you can define private_attr_reader, etc. by yourself.
In that case, the code will be

private_attr_reader :images, :key_map, :window, :screen_manager,:animations

and looks much better.

Matz

#9 Updated by Thomas Sawyer about 1 year ago

Letting #private accept an Array seems more preferable then adding yet another method slew of methods: private_attr_writer, private_attr_accessor, protected_attr_reader, protected_attr_writer, protected_attr_accessor, ...

#10 Updated by Yukihiro Matsumoto about 1 year ago

Thomas, private method that accept an array for methods names would be an interesting idea worth discussion.
But it is different issue.

Matz.

#11 Updated by Andrew Lazarus 9 months ago

Chaining the two suggestions leads to a nice syntax (in my opinion):

private attr_reader :name, :address, :etc

private needs to accept an array and attr_* needs to return its list (as an array) of arguments.

Also available in: Atom PDF