Project

General

Profile

Actions

Bug #18289

closed

Enumerable#to_a should delegate keyword arguments to #each

Added by Ethan (Ethan -) about 3 years ago. Updated almost 3 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]
[ruby-core:105944]

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

to_a_kw_arg_delegation.rb (101 Bytes) to_a_kw_arg_delegation.rb Ethan (Ethan -), 11/05/2021 11:04 AM

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

Actions #2

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
Actions #3

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, so to_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?

Actions #8

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) almost 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.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0