Project

General

Profile

Feature #15113

Show warnings on unused blocks with Enumerable#all? any? one? none?

Added by fursich (Onishi Koji) 2 months ago. Updated about 1 month ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:88977]

Description

Let Array#any? (and related enumerable methods alike) to express warnings in case blocks are left unused.

Background
Certain methods in Array silently ignore the given blocks without any warnings, which sometimes causes 'invisible' bugs that are a bit hard to detect.

>> [1,2,3].any?(2) {|it| it > 10}
=> true

On the other hand, Array#index warns you (kindly enough!) when your blocks are left unused.

>> [1,2,3].index(2) {|it| it > 10}
(irb):3: warning: given block not used
=> 1

Proposal

This PR is to let Enumerable#all?, #any?, #one, #none? (including similar methods with Array and Hash) to show warning messages so as that it behaves in consistent manner with what we see with Array#index.

Implementation

https://github.com/ruby/ruby/pull/1953

Adding one conditional branch per one method call, which would cost very low in terms of computational cost. (benchmark-driver suggested somewhere around 1.00x-1.01x slower with Enumurator#any?)

Hopefully it would help reduce some of the unnecessary source of pain, and help us code happily;)

History

#1 [ruby-core:88996] Updated by shevegen (Robert A. Heiler) 2 months ago

I think nobu committed it already (if it is the same one)

https://git.ruby-lang.org/ruby.git/commit/?id=384fda18b885872aacf225ac6ad7805fb101e497

I guess it is a useful change; reminds me a bit of the did-you-mean gem, in spirit at
least (both sort of look at possible errors made by humans; and I guess in most or all
cases, where there is no block for these methods, the human user may indeed just have
forgotten it).

#2 [ruby-core:89363] Updated by fursich (Onishi Koji) about 1 month ago

Thank you for letting me know robert-san
Yes, looks like this has been quickly merged by nobu-san. (thanksfully enough!)

To your point on human errors, yes, that's actually my intent, so your positive feedback is really encouraging.

This is just an off-topic, side note, but it would have been nicer if such warnings were given with ANY methods when they accidentally receive unused blocks, but that turned out to require quite an unrealistic thorough rework on how blocks are handled internally in ruby (I happened to have an opportunity to have great advises from matz and Endo san on that agenda)

This example is shown by Endo-san, that illustrates fundamental difficulty to detect if/how given blocks are used.

def foo
  Proc.new
end

foo { puts 'this is a valid block, no warnings are needed.' }.call
# this is a valid block, no warnings are needed.

So back to the topic here, I started with these frequently used core methods (which have trapped myself once before).
Hope that saves other developers' days at some point :)

(btw I'm wondering how to close this ticket.. maybe asking somebody in ruby core team might make sense?)

#3 [ruby-core:89381] Updated by duerst (Martin Dürst) about 1 month ago

  • Status changed from Open to Closed

Closed at proposer's request.

Also available in: Atom PDF