Project

General

Profile

Bug #11048

blocks raise on missing and extra keyword args

Added by bughit (bug hit) about 4 years ago. Updated almost 4 years ago.

Status:
Rejected
Priority:
Normal
Target version:
-
ruby -v:
ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-linux]
[ruby-core:<unknown>]

Description

blocks intentionally tolerate arity mismatches

irb(main):001:0> proc{|a, b| [a, b]}.(1)
[
  [0] 1,
  [1] nil
]

irb(main):003:0> proc{|a, b|[a, b]}.(1, 2, 3)
[
  [0] 1,
  [1] 2
]


so why not missing keyword args?

irb(main):002:0> proc{|a:, b:|[a, b]}.(a: 1)
ArgumentError: missing keyword: b


irb(main):004:0> proc{|a:, b:|[a, b]}.(a: 1, b: 1, c: 1)
ArgumentError: unknown keyword: c

History

#1

Updated by ko1 (Koichi Sasada) about 4 years ago

  • Assignee set to matz (Yukihiro Matsumoto)

Updated by matz (Yukihiro Matsumoto) about 4 years ago

We don't care about consistency here. Block does not report ArgumentError for reasons, so if you have any real-world use case that require keyword argument tolerance, just tell me. Otherwise I reject.

Matz.

Updated by bughit (bug hit) about 4 years ago

Yukihiro Matsumoto wrote:

We don't care about consistency here. Block does not report ArgumentError for reasons,

What are those reasons? And why do they not apply to keyword arguments?

so if you have any real-world use case that require keyword argument tolerance, just tell me.

The real-world use case is that anyone who has learned that blocks intentionally tolerate arity mismatches, would expect the same for keyword args and will therefore be unpleasantly surprised and be more likely to introduce a bug.

And that's the value of consistency (or least surprise), behavior that is logically consistent, that can be inferred without having to remember countless of arbitrary special case rules, avoids surprise and bugs.

Since you value programmer joy, there is little joy in having to keep track of incoherent, inconsistent special case rules.

Updated by bughit (bug hit) about 4 years ago

Yukihiro Matsumoto wrote:

so if you have any real-world use case that require keyword argument tolerance, just tell me.

The way I discovered this, as far as I remember, is:
I encountered a method I needed to call that yielded keyword args
In my case I only cared about one arg so I passed a block taking one keyarg, expecting it to just quietly drop the others as with positional args
Instead it raised

Updated by matz (Yukihiro Matsumoto) about 4 years ago

For example, loop method passes loop counter to the block. You can safely ignore this by arity tolerance. This is a reason behind it. But there's no benefit for keyword arguments tolerance, as far as I see, but demerit of late error detection.

Matz.

Updated by bughit (bug hit) about 4 years ago

Yukihiro Matsumoto wrote:

For example, loop method passes loop counter to the block. You can safely ignore this by arity tolerance. This is a reason behind it. But there's no benefit for keyword arguments tolerance, as far as I see, but demerit of late error detection.

Matz.

If you believe there's value in being able to ignore args you don't care about, I don't see why it would not apply to keyargs. The difference is not so fundamental, both are used to pass data to the block. One might switch to keyargs for yield, to make the code clearer, but there would be no expectation of this difference in behavior.

Updated by matz (Yukihiro Matsumoto) about 4 years ago

  • Status changed from Open to Closed

OK, you value consistency, where I value pragratic trade-off. That's the difference in view points.
Let's agree to disagree.

Matz.

#8

Updated by usa (Usaku NAKAMURA) almost 4 years ago

  • Status changed from Closed to Rejected

Updated by bughit (bug hit) almost 4 years ago

another use case for this is hash destructuring

array_of_hashes.each do |key1:, key2:|
end

it would be much better if this code did not raise on extra or missing keys, otherwise this type of destructuring is almost completely impractical

Updated by bughit (bug hit) almost 4 years ago

bug hit wrote:

another use case for this is hash destructuring

array_of_hashes.each do |key1:, key2:|
end

it would be much better if this code did not raise on extra or missing keys, otherwise this type of destructuring is almost completely impractical

Please comment on the use case of hash destructuring via block keyword args.

Also available in: Atom PDF