Issue #19079 has been updated by Hanmac (Hans Mackowiak).
you can also try prepend instead of include:
```ruby
WithHelper = DelegateClass(Base) { prepend Helper }
```
----------------------------------------
Bug #19079: Modules included in a DelegateClass cannot override delegate methods
https://bugs.ruby-lang.org/issues/19079#change-100407
* Author: jonathanhefner (Jonathan Hefner)
* Status: Rejected
* Priority: Normal
* ruby -v: ruby 3.1.2p20
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Because `DelegateClass` defines delegate methods on the class itself, those delegate methods come first in the method lookup chain. This prevents included modules from overriding delegate methods:
```ruby
Base = Class.new do
def foo
"base"
end
end
Helper = Module.new do
def foo
"helper"
end
end
WithHelper = DelegateClass(Base) { include Helper }
WithHelper.new(Base.new).foo
# => "base"
```
One possible solution would be to define the delegate methods in a separate module. That way, other modules could come before it in the method lookup chain.
--
https://bugs.ruby-lang.org/
Issue #19047 has been updated by matz (Yukihiro Matsumoto).
For example, the example in #19079 does not give warning for overwriting the method `foo`.
Matz.
----------------------------------------
Bug #19047: DelegateClass displays "method redefined" warning when overriding methods
https://bugs.ruby-lang.org/issues/19047#change-100405
* Author: jonathanhefner (Jonathan Hefner)
* Status: Closed
* Priority: Normal
* ruby -v: ruby 3.1.2p20
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Perhaps this is not a bug, but it does seem unexpected.
When creating a `DelegateClass` class without an intervening ancestor, overriding a method displays "method redefined" warning:
```ruby
Base = Class.new do
def foo
"foo"
end
end
Delegate1 = DelegateClass(Base) do
def foo
super + "1"
end
end
# warning: method redefined; discarding old foo
Delegate2 = Class.new(DelegateClass(Base)) do
def foo
super + "2"
end
end
# no warning
Delegate1.new(Base.new).foo
# => "foo1"
Delegate2.new(Base.new).foo
# => "foo2"
```
One possible solution would be to evaluate the `DelegateClass` block in a separate module, and prepend that module to the returned class.
Another possible solution would be to silence warnings around [when the block is evaluated](https://github.com/ruby/delegate/blob/df2283b8d8874446086b80355c….
I would be happy to submit a PR to https://github.com/ruby/delegate if this is something we want to address.
--
https://bugs.ruby-lang.org/
Issue #19079 has been updated by matz (Yukihiro Matsumoto).
If you want to include a module to a delegated class, try the following:
```ruby
class WithHelper<DelegateClass(Base)
include Helper
end
```
Matz.
----------------------------------------
Bug #19079: Modules included in a DelegateClass cannot override delegate methods
https://bugs.ruby-lang.org/issues/19079#change-100404
* Author: jonathanhefner (Jonathan Hefner)
* Status: Rejected
* Priority: Normal
* ruby -v: ruby 3.1.2p20
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Because `DelegateClass` defines delegate methods on the class itself, those delegate methods come first in the method lookup chain. This prevents included modules from overriding delegate methods:
```ruby
Base = Class.new do
def foo
"base"
end
end
Helper = Module.new do
def foo
"helper"
end
end
WithHelper = DelegateClass(Base) { include Helper }
WithHelper.new(Base.new).foo
# => "base"
```
One possible solution would be to define the delegate methods in a separate module. That way, other modules could come before it in the method lookup chain.
--
https://bugs.ruby-lang.org/
Issue #19078 has been updated by ioquatix (Samuel Williams).
Status changed from Open to Closed
It was merged.
----------------------------------------
Feature #19078: Introduce `Fiber#storage` for inheritable fiber-scoped variables.
https://bugs.ruby-lang.org/issues/19078#change-100401
* Author: ioquatix (Samuel Williams)
* Status: Closed
* Priority: Normal
* Assignee: ioquatix (Samuel Williams)
----------------------------------------
Pull Request: https://github.com/ruby/ruby/pull/6612
This is an evolution of the previous ideas:
- https://bugs.ruby-lang.org/issues/19058
- https://bugs.ruby-lang.org/issues/19062
This PR introduces fiber scoped variables, and is a solution for problems like <https://github.com/ioquatix/ioquatix/discussions/17>.
The main interface is:
```ruby
Fiber[key] = value
Fiber[key] # => value
```
The variables are scoped (local to) a fiber and inherited into child fibers and threads.
```ruby
Fiber[:request_id] = SecureRandom.hex(16)
Fiber.new do
p Fiber[:request_id] # prints the above request id
end
```
The fiber scoped variables are stored and can be accessed:
```ruby
Fiber.current.storage # => returns a Hash (copy) of the internal storage.
Fiber.current.storage= # => assigns a Hash (copy) to the internal storage.
```
Fiber itself has one new keyword argument:
```
Fiber.new(..., storage: hash, false, undef, nil)
```
This can control how the fiber variables are setup in a child context.
To minimise the performance overhead of some of the implementation choices, we are also simultaneously implementing <https://bugs.ruby-lang.org/issues/19077>.
## Examples
### Request loop
```ruby
Thread.new do
while request = queue.pop
Fiber.new(storage: {id: SecureRandom.hex(16)}) do
handle_request.call(request)
end
end
end
```
OR
```ruby
Thread.new do
while request = queue.pop
Fiber.current.storage = {id: SecureRandom.hex(16)}
handle_request.call(request)
end
end
```
--
https://bugs.ruby-lang.org/
Issue #19047 has been updated by byroot (Jean Boussier).
> we missed the warnings from DelegateClass misuse
Do you have a reference to that?
----------------------------------------
Bug #19047: DelegateClass displays "method redefined" warning when overriding methods
https://bugs.ruby-lang.org/issues/19047#change-100397
* Author: jonathanhefner (Jonathan Hefner)
* Status: Closed
* Priority: Normal
* ruby -v: ruby 3.1.2p20
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Perhaps this is not a bug, but it does seem unexpected.
When creating a `DelegateClass` class without an intervening ancestor, overriding a method displays "method redefined" warning:
```ruby
Base = Class.new do
def foo
"foo"
end
end
Delegate1 = DelegateClass(Base) do
def foo
super + "1"
end
end
# warning: method redefined; discarding old foo
Delegate2 = Class.new(DelegateClass(Base)) do
def foo
super + "2"
end
end
# no warning
Delegate1.new(Base.new).foo
# => "foo1"
Delegate2.new(Base.new).foo
# => "foo2"
```
One possible solution would be to evaluate the `DelegateClass` block in a separate module, and prepend that module to the returned class.
Another possible solution would be to silence warnings around [when the block is evaluated](https://github.com/ruby/delegate/blob/df2283b8d8874446086b80355c….
I would be happy to submit a PR to https://github.com/ruby/delegate if this is something we want to address.
--
https://bugs.ruby-lang.org/
Issue #19107 has been updated by byroot (Jean Boussier).
> Is there an actual case where this proposal is convenient?
Yes, when replacing old APIs that took an "option hash" by explicit keyword arguments, it tend to create very large signature.
The last example I have in mind is `redis-client`: https://github.com/redis-rb/redis-client/blob/dcfe43abb83597bee129537464e20…
```ruby
def initialize(
username: nil,
password: nil,
db: nil,
id: nil,
timeout: DEFAULT_TIMEOUT,
read_timeout: timeout,
write_timeout: timeout,
connect_timeout: timeout,
ssl: nil,
custom: {},
ssl_params: nil,
driver: nil,
protocol: 3,
client_implementation: RedisClient,
command_builder: CommandBuilder,
inherit_socket: false,
reconnect_attempts: false,
middlewares: false,
circuit_breaker: nil
)
```
When adding a new argument, it cause these annoying diffs:
```diff
diff --git a/lib/redis_client/config.rb b/lib/redis_client/config.rb
index fc74367..6412171 100644
--- a/lib/redis_client/config.rb
+++ b/lib/redis_client/config.rb
@@ -36,7 +36,8 @@ class RedisClient
command_builder: CommandBuilder,
inherit_socket: false,
reconnect_attempts: false,
- middlewares: false
+ middlewares: false,
+ circuit_breaker: nil
)
@username = username
@password = password
```
Also this inconsistency is the reason why some popular styleguides reverted back to not using trailing comma for multi-line enumerations:
- https://github.com/testdouble/standard/pull/453#issuecomment-1234208705
- https://github.com/fables-tales/rubyfmt/issues/154
----------------------------------------
Feature #19107: Allow trailing comma in method signature
https://bugs.ruby-lang.org/issues/19107#change-100396
* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
A popular style for multiline arrays, hashes or method calls, is to use trailing commas:
```ruby
array = [
1,
2,
3,
]
hash = {
foo: 1,
bar: 2,
baz: 3,
}
Some.method(
1,
2,
foo: 3,
)
```
The main reason to do this is to avoid unnecessary noise when adding one extra element:
```diff
diff --git a/foo.rb b/foo.rb
index b2689a7e4f..ddb7dc3552 100644
--- a/foo.rb
+++ b/foo.rb
@@ -1,4 +1,5 @@
Foo.bar(
foo: 1,
- bar: 2
+ bar: 2,
+ baz: 3
)
```
However, this pattern doesn't work with method declarations:
```ruby
def foo(bar:,) # syntax error, unexpected ')'
```
### Proposal
For consistency and convenience I propose to allow trailing commas in method declarations.
--
https://bugs.ruby-lang.org/
Issue #19078 has been updated by ioquatix (Samuel Williams).
Thanks so much for your time and discussion @matz et al.
----------------------------------------
Feature #19078: Introduce `Fiber#storage` for inheritable fiber-scoped variables.
https://bugs.ruby-lang.org/issues/19078#change-100395
* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
* Assignee: ioquatix (Samuel Williams)
----------------------------------------
Pull Request: https://github.com/ruby/ruby/pull/6612
This is an evolution of the previous ideas:
- https://bugs.ruby-lang.org/issues/19058
- https://bugs.ruby-lang.org/issues/19062
This PR introduces fiber scoped variables, and is a solution for problems like <https://github.com/ioquatix/ioquatix/discussions/17>.
The main interface is:
```ruby
Fiber[key] = value
Fiber[key] # => value
```
The variables are scoped (local to) a fiber and inherited into child fibers and threads.
```ruby
Fiber[:request_id] = SecureRandom.hex(16)
Fiber.new do
p Fiber[:request_id] # prints the above request id
end
```
The fiber scoped variables are stored and can be accessed:
```ruby
Fiber.current.storage # => returns a Hash (copy) of the internal storage.
Fiber.current.storage= # => assigns a Hash (copy) to the internal storage.
```
Fiber itself has one new keyword argument:
```
Fiber.new(..., storage: hash, false, undef, nil)
```
This can control how the fiber variables are setup in a child context.
To minimise the performance overhead of some of the implementation choices, we are also simultaneously implementing <https://bugs.ruby-lang.org/issues/19077>.
## Examples
### Request loop
```ruby
Thread.new do
while request = queue.pop
Fiber.new(storage: {id: SecureRandom.hex(16)}) do
handle_request.call(request)
end
end
end
```
OR
```ruby
Thread.new do
while request = queue.pop
Fiber.current.storage = {id: SecureRandom.hex(16)}
handle_request.call(request)
end
end
```
--
https://bugs.ruby-lang.org/
Issue #19036 has been updated by matz (Yukihiro Matsumoto).
LGTM.
Matz.
----------------------------------------
Feature #19036: Provide a way to set path for File instances created with for_fd
https://bugs.ruby-lang.org/issues/19036#change-100393
* Author: headius (Charles Nutter)
* Status: Open
* Priority: Normal
----------------------------------------
Ruby provides `IO.for_fd` to instantiate an IO object from an existing file descriptor value. The logic for this simply calls the base `IO.new` logic, which for all IO and subtypes simply wraps the given file descriptor.
When called against File, or other subtypes of IO, this has the side effect of creating an IO instance with that type, e.g. `File.for_fd` will behave identically to `IO.for_fd` except that the class of the resulting object will be File.
Unfortunately, this results in a File object that does not have any `path` associated with it:
```
3.1.2 :001 > f = File.open('README.md')
=> #<File:README.md>
3.1.2 :002 > f.path
=> "README.md"
3.1.2 :003 > f2 = File.for_fd(f.fileno)
=> #<File:fd 5>
3.1.2 :004 > f2.path
(irb):4:in `path': File is unnamed (TMPFILE?) (IOError)
from (irb):4:in `<main>'
from /home/headius/.rvm/rubies/ruby-3.1.2/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
from /home/headius/.rvm/rubies/ruby-3.1.2/bin/irb:25:in `load'
from /home/headius/.rvm/rubies/ruby-3.1.2/bin/irb:25:in `<main>'
```
I propose that there should be a way, via an extra parameter or a keyword argument, to provide a path when constructing a new File via `for_fd`.
Possible forms:
* `File.for_fd(fileno, "my/path")`
* `File.for_fd(fileno, path: "my/path")`
This would necessitate a separate implementation for `File.for_fd` unless we want to make it possible to set a path for all `for_fd` calls (which may not make sense for many of them).
This came up while trying to implement a pure-Ruby (plus FFI) version of the "pty" library. Without overriding the `path` function, it is not possible for the File object returned by `PTY.open` to gain the "masterpty:<slavename>" filename, and therefore it does not clearly indicate it is from a PTY.
See https://github.com/jruby/jruby/pull/7391, an attempt to match inspect output for these return values using `define_singleton_method`. Providing a way to set the path would make this automatic without the singleton definition.
--
https://bugs.ruby-lang.org/
Issue #19108 has been updated by matz (Yukihiro Matsumoto).
Template strings should be ASCII compatible, exceptions otherwise.
Matz.
----------------------------------------
Bug #19108: Format routines like pack blindly treat a string as ASCII-encoded
https://bugs.ruby-lang.org/issues/19108#change-100391
* Author: chrisseaton (Chris Seaton)
* Status: Open
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Format routines like pack and unpack blindly treat a string as ASCII-encoded, even if they aren't ASCII or ASCII-compatible.
I tried to construct code that was misleading using ASCII-incompatible-encodings but couldn't do it in practice (no ASCII-incompatible encodings have a pack directive ASCII byte that is encoded as a printable character.)
But I could demonstrate at least some strange behaviour:
```
p ['foo'].pack('u').encoding # => #<Encoding:US-ASCII>
p ['foo'].pack('u'.encode('UTF-32BE')).encoding # => #<Encoding:ASCII-8BIT>
```
This is because the NUL characters in the second one (which aren't really NUL characters - they're part of the directive characters) explicitly trigger the encoding to change to binary.
There is a warning, but the warning is only for unexpected directives. How about disallowing or warning for non-ascii compatible format strings?
--
https://bugs.ruby-lang.org/
Issue #19164 has been reported by byroot (Jean Boussier).
----------------------------------------
Bug #19164: [3.2.0dev] Freezing an object can prevent removing methods on its class
https://bugs.ruby-lang.org/issues/19164
* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
* Target version: 3.2
* ruby -v: ruby 3.2.0dev (2022-11-30T08:20:38Z master c8bfbbc25e) [arm64-darwin22]
* Backport: 2.7: DONTNEED, 3.0: DONTNEED, 3.1: DONTNEED
----------------------------------------
The following snippet showcase the bug. It passes on 3.1 and older, but fails on 3.2.0
```ruby
klass = Class.new
klass.prepend(Module.new)
klass.new.freeze
klass.class_eval do
define_method(:bar) {} # works
remove_method(:bar) # raise FrozenError
end
```
Bisecting with this script points me to [e7b1ff984fde859a7778dec564731eb79392406f](https://github.com/ruby/ruby/comm…, which suggest some part of the codebase might be misusing some user flags.
I have a patch that fix this script but I doubt it's the right fix, I'll be working with @jemmai and @tenderlovemaking to find a proper fix.
I'm opening this ticket to make sure it's addressed before the 3.2.0 final release.
--
https://bugs.ruby-lang.org/