From: mame@... Date: 2020-12-23T15:25:57+00:00 Subject: [ruby-core:101649] [Ruby master Feature#17314] Provide a way to declare visibility of attributes defined by attr* methods in a single expression Issue #17314 has been updated by mame (Yusuke Endoh). Hi, I've just noticed that this changeset allows not only `Module#private` but also `Module#private_class_method` to accept an array of symbols. `Module#public_class_method` too. ``` class Foo def self.foo; end def self.bar; end private_class_method [:foo, :bar] # No error end ``` And toplevel `Kernel#private` and `Kernel#public` do too. ``` def foo = nil def bar = nil private [:foo, :bar] public [:foo, :bar] ``` I cannot think of a case where we want to pass an array of symbols to `public_class_method` and toplevel `public`. (Note that there is no toplevel `attr_reader`.) So I believe these changes are not intentional. But it may be more consistent for the methods to allow a symbol array. I have no opinion whether the additional methods should allow or deny an array. What do you think? Anyway, I've added a rdoc, tests, and NEWS for the extra methods at 3a81daaf8dc037057d96b8e8cdc6ab1691e7e9d9. ---------------------------------------- Feature #17314: Provide a way to declare visibility of attributes defined by attr* methods in a single expression https://bugs.ruby-lang.org/issues/17314#change-89439 * Author: radarek (Rados��aw Bu��at) * Status: Closed * Priority: Normal ---------------------------------------- **Description** Many of us (me included) declare class attributes, even if they are private, on the top of class definition. When reading source code it's convinient to see what kind of attributes class has. To declare private attributes we can: * declare them with one of `attr*` methods and later change visiblity calling `private` * call `private` without argument, then declare attributes and finally call (in most cases) `public` to keep defining public methods * declare attribute on top of the class but make them private in private section later in a file ``` ruby clsss Foo attr_accessor :foo private :foo, :foo= # we have to remember about :foo= too private attr_accessor :bar public # rest of the code end ``` To simplify it and create other possibilites I propose to: * change `attr*` methods so as they return array of defined methods names * allow `public/protected/private` methods to receive array of methods names (single argument) With requested feature we could write code like this: ``` ruby class Foo private attr_accessor :foo, :bar end ``` Additionaly you could use `attr*` with your own methods. Something like this: ``` ruby class Module def traceable(names) # ... names end end class Foo traceable attr_accessor :foo # it can be mixed with public/protected/private too protected traceable attr_accessor :bar end ``` **Backward compatibility** * `attr*` methods currently return `nil` so there should be no problem with changing them * `public/protected/private` methods receive multiple positional arguments and convert all non symbol/string objects to strings. I can imagine only one case where compatibility would be broken: ``` ruby class Foo def foo; end def bar; end arr = [:foo] def arr.to_str 'bar' end private arr end p [Foo.public_instance_methods(false), Foo.private_instance_methods(false)] ``` Currently `[[:foo], [:bar]]` would be displayed, `[[:bar], [:foo]]` after requested feature is implemented. **Implementation** You can view my implementation in this (draft) PR: https://github.com/ruby/ruby/pull/3757 -- https://bugs.ruby-lang.org/ Unsubscribe: