Project

General

Profile

Feature #9453

Return symbols of defined methods for `attr` and friends

Added by jballanc (Joshua Ballanco) almost 4 years ago. Updated 8 months ago.

Status:
Rejected
Priority:
Normal
Target version:
-
[ruby-core:60112]

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 (3.23 KB) attr_rv.patch Patch to add return values to attr* methods jballanc (Joshua Ballanco), 01/26/2014 05:51 PM

Related issues

Has duplicate Ruby trunk - Feature #13560: Module#attr_ methods return reasonable valuesOpen

History

#1 [ruby-core:60425] Updated by jballanc (Joshua Ballanco) almost 4 years 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 [ruby-core:60426] Updated by Eregon (Benoit Daloze) almost 4 years 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 [ruby-core:60428] Updated by sawa (Tsuyoshi Sawada) almost 4 years ago

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

#4 [ruby-core:60440] Updated by avdi (Avdi Grimm) almost 4 years 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.

--
Avdi Grimm
http://avdi.org

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

#5 [ruby-core:60454] Updated by jballanc (Joshua Ballanco) almost 4 years 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 [ruby-core:61726] Updated by jballanc (Joshua Ballanco) over 3 years ago

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

#7 [ruby-core:61741] Updated by usa (Usaku NAKAMURA) over 3 years ago

  • Status changed from Open to Assigned
  • Assignee set to matz (Yukihiro Matsumoto)

#8 [ruby-core:61753] Updated by matz (Yukihiro Matsumoto) over 3 years 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 [ruby-core:61995] Updated by trans (Thomas Sawyer) over 3 years 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 [ruby-core:61997] Updated by matz (Yukihiro Matsumoto) over 3 years 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 [ruby-core:64276] Updated by nerdrew (Andrew Lazarus) over 3 years 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.

#12 [ruby-core:80009] Updated by vais (Vais Salikhov) 9 months ago

attr_* methods returning nil should be considered a bug at this point, since all other ways of defining methods return a symbol. This makes Ruby inconsistent, and violates its own Principle of Least Surprise.

#13 [ruby-core:80732] Updated by matz (Yukihiro Matsumoto) 8 months ago

Yes, def and define_method returns symbols now.
But it does not mean attr_* should return symbols. Since they can define multiple methods.
Considering there's no use for private attributes, I don't think the proposal creates real-world value.

Besides that, mention to the principle of least surprise gives you negative evaluation here (since the background varies from user to user, and it does not lead to constructive discussion).

Matz.

#14 Updated by shyouhei (Shyouhei Urabe) 7 months ago

  • Has duplicate Feature #13560: Module#attr_ methods return reasonable values added

Also available in: Atom PDF