[ruby-core:120660] [Ruby master Bug#21036] Somewhat confusing behaviour between warning "block passed may be ignored", versus the responsible method triggering this warning already being faulty and can never be run successfully due to errors such as "wrong number of arguments" and/or recursive cal

Issue #21036 has been reported by rubyFeedback (robert heiler). ---------------------------------------- Bug #21036: Somewhat confusing behaviour between warning "block passed may be ignored", versus the responsible method triggering this warning already being faulty and can never be run successfully due to errors such as "wrong number of arguments" and/or recursive cal https://bugs.ruby-lang.org/issues/21036 * Author: rubyFeedback (robert heiler) * Status: Open * ruby -v: ruby 3.4.1 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Today I was updating / porting some legacy code, to ruby 3.4.1. Ruby 3.4.1 changed a few things, including some warnings, which is actually quite useful in the long run, in my opinion - although right now requiring some changes, which takes time. One new warning or notification is this: warning: the block passed to 'Object#xyz' defined at bla.rb:5 may be ignored So ruby now warns the developer that a block argument may be ignored. This is new information, which is useful. However had, while it takes the brain to adjust to this slowly, I actually encountered a small situation where the ruby warning reported here is a little bit awkward. Let me show a minimal script that reproduces this issue, so you can copy / paste it quickly: #!/usr/bin/ruby -w # Encoding: UTF-8 # frozen_string_literal: true # =========================================================================== # def is_recursive_but_wrong abc = is_recursive_but_wrong(abc) { :automatic } return '' end is_recursive_but_wrong Don't worry about this example being nonsensical, I actually had two bugs in one go. :D When you run the above ruby code, from a .rb file, it will report something like this: huh.rb:6: warning: the block passed to 'Object#is_recursive_but_wrong' defined at huh.rb:5 may be ignored huh.rb:5:in 'is_recursive_but_wrong': wrong number of arguments (given 1, expected 0) (ArgumentError) from huh.rb:6:in 'Object#is_recursive_but_wrong' from huh.rb:10:in '<main>' In this aptly named file called huh.rb (capturing my surprise as filename), you can see two things: 1) the warning about the block being ignored, and 2) the wrong number of arguments given I actually accidentally copy/pasted code, and in another .rb file I had a method called "created_scrolled_window" to return a scrolled-window widget from ruby-gtk3, but I first focused on the block warning given. So the first focus I made was on the "ignored block parameter", as I tend to fix these quickly, first, due to them being fairly simple. I then realised I recursively called that method. So why do I think that behaviour is strange? Well - the to me surprising part has been that I get BOTH the warning AND the issue of a wrong number of arguments. In such a situation I would prefer the wrong number of arguments reported, but not the warning about "ignored block parameter given", as that latter is less problematic (which is ok as a warning, but it still takes my attention to it, since it is reported first). Only after the "wrong number of arguments" would I think is that warning ok, as ruby can not know whether the intent truly was to ignore the block, or whether prior to that, the method is already wrong. Interestingly when I changed the above code to this variant: #!/usr/bin/ruby -w # Encoding: UTF-8 # frozen_string_literal: true # =========================================================================== # def is_recursive_but_wrong abc = is_recursive_but_wrong(def) { :automatic } return '' end is_recursive_but_wrong Aka changing the second "abc" to "def", all not defined, I get a totally different error, which is even more confusing: huh.rb:6: warning: assigned but unused variable - abc huh.rb: --> huh.rb Unmatched keyword, missing `end' ? 5 def is_recursive_but_wrong > 6 abc = is_recursive_but_wrong(def) { :automatic } > 7 return '' 8 end huh.rb:6: syntax errors found (SyntaxError) 4 | # =========================================================================== # 5 | def is_recursive_but_wrong > 6 | ... ) { :automatic } | ^ unexpected ')', ignoring it | ^ expected a delimiter to close the parameters | ^ unexpected ')'; expected a method name | ^ expected a `=>` between the hash key and value | ^ unexpected '}'; expected a value in the hash literal 7 | return '' 8 | end 9 | > 10 | is_recursive_but_wrong | ^~~~~~~~~~~~~~~~~~~~~~ unexpected local variable or method, expecting end-of-input | ^~~~~~~~~~~~~~~~~~~~~~ unexpected local variable or method; expected a `)` to close the arguments | ^ expected an `end` to close the `def` statement | ^ unexpected end-of-input, assuming it is closing the parent top level context By the way I like the change to use a red arrows there, that is quite helpful. Now, the above error makes sense I suppose because the ruby parser has to be kept in a "flexible" state, to evaluate ruby code (the old parse versus prism), but to me all of the above is a bit confusing nonetheless. Or perhaps the priorities are different. It may be difficult for ruby and the parsers to evaluate the intent of the programmer, I get it, and people may write odd code and also odd-but-valid code, but at the least in example 1, I would reason that the "ignored block warning" should not be shown if the underlying error, within that same method, means it can never be truly evaluated. I think in such a case, perhaps say 99% of the situations, whether the block is evaluated or not, is irrelevant, because the method itself is faulty and can never be correct (in my case, both as recursive call to itself, and also wrong arguments actually). I have no good suggestion to fix this as perhaps this may be intended behaviour, but perhaps I am not the only one who may be confused about the above, so I'll report it just in case. Please feel free to close this issue at any moment in time; it may not be a bug, but I found it better to file it under "Bug" rather than issue request or misc. (Perhaps in the long run we may improve on the warnings-versus-error issue a little bit. I also don't have a good suggestion here, but I remember from issues in the past that warnings can be both helpful but also confusing or spammy to some users. Any simple but effective solution here in the long run may be useful for ruby developers in general.) -- https://bugs.ruby-lang.org/

Issue #21036 has been updated by jeremyevans0 (Jeremy Evans). Status changed from Open to Closed rubyFeedback (robert heiler) wrote:
Please feel free to close this issue at any moment in time; it may not be a bug, but I found it better to file it under "Bug" rather than issue request or misc.
This does not appear to be a bug. The ignored block warning is correct. The fact that you get a warning and an error in the `abc = is_recursive_but_wrong(abc) { :automatic }` case is correct because the incorrect argument is a run-time error while the ignored block is a compile-time warning. The different error in the `abc = is_recursive_but_wrong(def) { :automatic }` case is because `def` is a keyword. ---------------------------------------- Bug #21036: Somewhat confusing behaviour between warning "block passed may be ignored", versus the responsible method triggering this warning already being faulty and can never be run successfully due to errors such as "wrong number of arguments" and/or recursive cal https://bugs.ruby-lang.org/issues/21036#change-112014 * Author: rubyFeedback (robert heiler) * Status: Closed * ruby -v: ruby 3.4.1 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Today I was updating / porting some legacy code, to ruby 3.4.1. Ruby 3.4.1 changed a few things, including some warnings, which is actually quite useful in the long run, in my opinion - although right now requiring some changes, which takes time. One new warning or notification is this: warning: the block passed to 'Object#xyz' defined at bla.rb:5 may be ignored So ruby now warns the developer that a block argument may be ignored. This is new information, which is useful. However had, while it takes the brain to adjust to this slowly, I actually encountered a small situation where the ruby warning reported here is a little bit awkward. Let me show a minimal script that reproduces this issue, so you can copy / paste it quickly: #!/usr/bin/ruby -w # Encoding: UTF-8 # frozen_string_literal: true # =========================================================================== # def is_recursive_but_wrong abc = is_recursive_but_wrong(abc) { :automatic } return '' end is_recursive_but_wrong Don't worry about this example being nonsensical, I actually had two bugs in one go. :D When you run the above ruby code, from a .rb file, it will report something like this: huh.rb:6: warning: the block passed to 'Object#is_recursive_but_wrong' defined at huh.rb:5 may be ignored huh.rb:5:in 'is_recursive_but_wrong': wrong number of arguments (given 1, expected 0) (ArgumentError) from huh.rb:6:in 'Object#is_recursive_but_wrong' from huh.rb:10:in '<main>' In this aptly named file called huh.rb (capturing my surprise as filename), you can see two things: 1) the warning about the block being ignored, and 2) the wrong number of arguments given I actually accidentally copy/pasted code, and in another .rb file I had a method called "created_scrolled_window" to return a scrolled-window widget from ruby-gtk3, but I first focused on the block warning given. So the first focus I made was on the "ignored block parameter", as I tend to fix these quickly, first, due to them being fairly simple. I then realised I recursively called that method. So why do I think that behaviour is strange? Well - the to me surprising part has been that I get BOTH the warning AND the issue of a wrong number of arguments. In such a situation I would prefer the wrong number of arguments reported, but not the warning about "ignored block parameter given", as that latter is less problematic (which is ok as a warning, but it still takes my attention to it, since it is reported first). Only after the "wrong number of arguments" would I think is that warning ok, as ruby can not know whether the intent truly was to ignore the block, or whether prior to that, the method is already wrong. Interestingly when I changed the above code to this variant: #!/usr/bin/ruby -w # Encoding: UTF-8 # frozen_string_literal: true # =========================================================================== # def is_recursive_but_wrong abc = is_recursive_but_wrong(def) { :automatic } return '' end is_recursive_but_wrong Aka changing the second "abc" to "def", all not defined, I get a totally different error, which is even more confusing: huh.rb:6: warning: assigned but unused variable - abc huh.rb: --> huh.rb Unmatched keyword, missing `end' ? 5 def is_recursive_but_wrong > 6 abc = is_recursive_but_wrong(def) { :automatic } > 7 return '' 8 end huh.rb:6: syntax errors found (SyntaxError) 4 | # =========================================================================== # 5 | def is_recursive_but_wrong > 6 | ... ) { :automatic } | ^ unexpected ')', ignoring it | ^ expected a delimiter to close the parameters | ^ unexpected ')'; expected a method name | ^ expected a `=>` between the hash key and value | ^ unexpected '}'; expected a value in the hash literal 7 | return '' 8 | end 9 | > 10 | is_recursive_but_wrong | ^~~~~~~~~~~~~~~~~~~~~~ unexpected local variable or method, expecting end-of-input | ^~~~~~~~~~~~~~~~~~~~~~ unexpected local variable or method; expected a `)` to close the arguments | ^ expected an `end` to close the `def` statement | ^ unexpected end-of-input, assuming it is closing the parent top level context By the way I like the change to use a red arrows there, that is quite helpful. Now, the above error makes sense I suppose because the ruby parser has to be kept in a "flexible" state, to evaluate ruby code (the old parse versus prism), but to me all of the above is a bit confusing nonetheless. Or perhaps the priorities are different. It may be difficult for ruby and the parsers to evaluate the intent of the programmer, I get it, and people may write odd code and also odd-but-valid code, but at the least in example 1, I would reason that the "ignored block warning" should not be shown if the underlying error, within that same method, means it can never be truly evaluated. I think in such a case, perhaps say 99% of the situations, whether the block is evaluated or not, is irrelevant, because the method itself is faulty and can never be correct (in my case, both as recursive call to itself, and also wrong arguments actually). I have no good suggestion to fix this as perhaps this may be intended behaviour, but perhaps I am not the only one who may be confused about the above, so I'll report it just in case. Please feel free to close this issue at any moment in time; it may not be a bug, but I found it better to file it under "Bug" rather than issue request or misc. (Perhaps in the long run we may improve on the warnings-versus-error issue a little bit. I also don't have a good suggestion here, but I remember from issues in the past that warnings can be both helpful but also confusing or spammy to some users. Any simple but effective solution here in the long run may be useful for ruby developers in general.) -- https://bugs.ruby-lang.org/
participants (2)
-
jeremyevans0 (Jeremy Evans)
-
rubyFeedback (robert heiler)