[#100689] [Ruby master Feature#17303] Make webrick to bundled gems or remove from stdlib — hsbt@...
Issue #17303 has been reported by hsbt (Hiroshi SHIBATA).
11 messages
2020/11/02
[#100852] [Ruby master Feature#17326] Add Kernel#must! to the standard library — zimmerman.jake@...
Issue #17326 has been reported by jez (Jake Zimmerman).
24 messages
2020/11/14
[#100930] [Ruby master Feature#17333] Enumerable#many? — masafumi.o1988@...
Issue #17333 has been reported by okuramasafumi (Masafumi OKURA).
10 messages
2020/11/18
[#101071] [Ruby master Feature#17342] Hash#fetch_set — hunter_spawn@...
Issue #17342 has been reported by MaxLap (Maxime Lapointe).
26 messages
2020/11/25
[ruby-core:100775] [Ruby master Feature#17314] Provide a way to declare visibility of attributes defined by attr* methods in a single expression
From:
zverok.offline@...
Date:
2020-11-11 07:56:02 UTC
List:
ruby-core #100775
Issue #17314 has been updated by zverok (Victor Shepelev).
> Private attribute methods defeat the purpose of attribute methods. If you want to access them within the class, you can directly access the instance variables.
The idea behind private attribute methods (which I've seen used in a lot of codebases, and use myself) is uniformity of the call-sequence of different values. I believe Avdi Grimm had a nice article on this point of view (will try to find it).
Basically, if in some "service" (command, operation) class we have a code like this:
```ruby
class MyCommand
def initialize(name)
@name = name
end
def call
path = File.join(BASE_PATH, @name)
# a lot of processing done with path
data = File.read(path)
end
private
# some helper methods
end
```
Now, there are several ways this code may evolve:
For example (1), `path` calculation more complicated and extracted to its own method
```ruby
def path
File.join(BASE_PATH, @name)
end
def call
# a lot of processing done with path
data = File.read(path)
end
```
...or, if the calculation is heavy, it is also memoized (2)
```ruby
def path
@path ||= File.join(BASE_PATH, @name)
end
def call
# a lot of processing done with path
data = File.read(path)
end
```
Or -- to the point to this ticket -- suddenly we have a refactoring when the whole path is passed by class' client (3):
```ruby
class MyCommand
def initialize(path)
@path = path
end
def call
# a lot of processing done with path
data = File.read(path)
end
private
attr_reader :path
# some helper methods
end
```
The important point here is: in either case, code working with just `path`, continues to work. There is no point in rewriting all relevant statements with `@path` in case (3).
More realistically, we might _start_ with instance variable, and then calculation of it will become more complicated -- but due to the same reasons, it is reasonable to immediately start using private `attr_reader`, not "naked" instance var.
----------------------------------------
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-88418
* Author: radarek (RadosナBw BuナBt)
* Status: Open
* 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: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>