Bug #18289
closedEnumerable#to_a should delegate keyword arguments to #each
Description
Enumerable#to_a
has always delegated its arguments to #each
, but it does not handle keyword arguments. This seems like an oversight.
My project uses keyword arguments to an #each method, and this has broken Enumerable#to_a as of ruby 3 (and generates a warning on ruby 2.7).
class Foo
include Enumerable
def each(opt: )
yield 'foo'
end
end
pp Foo.new.to_a(opt: 4)
ruby 2.4
["foo"]
ruby 2.7
to_a_kw_arg_delegation.rb:8: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
to_a_kw_arg_delegation.rb:3: warning: The called method `each' is defined here
["foo"]
ruby 3
to_a_kw_arg_delegation.rb:3:in `each': wrong number of arguments (given 1, expected 0; required keyword: opt) (ArgumentError)
from to_a_kw_arg_delegation.rb:8:in `to_a'
from to_a_kw_arg_delegation.rb:8:in `<main>'
Files
Updated by jeremyevans0 (Jeremy Evans) about 3 years ago
I've submitted a pull request to fix this: https://github.com/ruby/ruby/pull/5086
Updated by jeremyevans0 (Jeremy Evans) about 3 years ago
- Backport changed from 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN to 2.6: DONTNEED, 2.7: REQUIRED, 3.0: REQUIRED
Updated by jeremyevans (Jeremy Evans) about 3 years ago
- Status changed from Open to Closed
Applied in changeset git|e83c02a768af61cd0890a75e90bcae1119d8bd93.
Delegate keywords from Enumerable#to_a to #each
Fixes [Bug #18289]
Updated by nobu (Nobuyoshi Nakada) about 3 years ago
Recently I've encountered similar issue with grep(regexp, chomp: true)
.
And IO#each
has the separator and limit arguments, I wonder how to pass them.
Updated by jeremyevans0 (Jeremy Evans) about 3 years ago
nobu (Nobuyoshi Nakada) wrote in #note-4:
Recently I've encountered similar issue with
grep(regexp, chomp: true)
.
What's the issue with grep
? If it is a keyword issue, we can probably fix it.
And
IO#each
has the separator and limit arguments, I wonder how to pass them.
IO#each
doesn't use keywords, so to_a
should pass the arguments even before e83c02a768af61cd0890a75e90bcae1119d8bd93:
$ echo 'aaa\nbbb\nccc' | ruby -ve 'p $stdin.to_a("\n", 2)'
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-openbsd]
["aa", "a\n", "bb", "b\n", "cc", "c\n"]
Updated by nobu (Nobuyoshi Nakada) about 3 years ago
jeremyevans0 (Jeremy Evans) wrote in #note-5:
nobu (Nobuyoshi Nakada) wrote in #note-4:
Recently I've encountered similar issue with
grep(regexp, chomp: true)
.What's the issue with
grep
? If it is a keyword issue, we can probably fix it.
Same as this issue.
And
IO#each
has the separator and limit arguments, I wonder how to pass them.
IO#each
doesn't use keywords, soto_a
should pass the arguments even before e83c02a768af61cd0890a75e90bcae1119d8bd93:
As the number of arguments of #grep
is fixed, it won't be a problem in this case.
And #to_a
has delegated all arguments to #each
, so it didn't have problems.
But what about methods which have optional parameters, e.g. Enumerable#count
?
Although it's possible to make the first argument mandatory when passing arguments for #each
, it doesn't feel very nice.
Updated by jeremyevans0 (Jeremy Evans) about 3 years ago
grep
doesn't appear to have the same issue as to_a
, since it explicitly calls each
with no arguments (unlike to_a
, which delegates arguments to each
). Same thing with count
. So I'm not sure what the issue is in the grep
or count
cases. Could you give an example in code showing the problem?
Updated by nagachika (Tomoyuki Chikanaga) about 3 years ago
- Backport changed from 2.6: DONTNEED, 2.7: REQUIRED, 3.0: REQUIRED to 2.6: DONTNEED, 2.7: REQUIRED, 3.0: DONE
ruby_3_0 aadb8cad563ca23e54a775d4fee936a07466112f merged revision(s) e83c02a768af61cd0890a75e90bcae1119d8bd93.
Updated by usa (Usaku NAKAMURA) about 3 years ago
- Backport changed from 2.6: DONTNEED, 2.7: REQUIRED, 3.0: DONE to 2.6: DONTNEED, 2.7: DONE, 3.0: DONE
ruby_2_7 b1985629565c3c54b1a64d6faf213e8144857515 merged revision(s) e83c02a768af61cd0890a75e90bcae1119d8bd93.