[#115244] [Ruby master Feature#19987] add sample method to Range — "horv77@... (Andras Horvath) via ruby-core" <ruby-core@...>
Issue #19987 has been reported by horv77@protonmail.com (Andras Horvath).
6 messages
2023/11/05
[#115247] [Ruby master Feature#19988] AI for inner code behavior analysis at runtime — "horv77@... (Andras Horvath) via ruby-core" <ruby-core@...>
Issue #19988 has been reported by horv77@protonmail.com (Andras Horvath).
3 messages
2023/11/05
[#115404] Ruby 3.2.2 - rbconfig.rb's MAKEFILE_CONFIG — Jay Mav via ruby-core <ruby-core@...>
Hello Ruby Dev Team,
4 messages
2023/11/17
[ruby-core:115223] [Ruby master Feature#19979] Allow methods to declare that they don't accept a block via `&nil`
From:
"ufuk (Ufuk Kayserilioglu) via ruby-core" <ruby-core@...>
Date:
2023-11-01 15:33:25 UTC
List:
ruby-core #115223
Issue #19979 has been updated by ufuk (Ufuk Kayserilioglu).
Eregon (Benoit Daloze) wrote in #note-7:
> A static analyzer could detect a `raise ... if block_given?` if at the start of a method/not under any other control flow.
I understand your position and respect it, but I can't help but feel like this workaround is similar to if the language said "We don't have required keywords, all keywords are optional. In order to have required keywords, you need to check if the keyword is supplied or not, and raise". We have the concept of required keywords since they communicate intent and make it easier for the VM and developers to reason about the code as it is written. That's why I think the addition of `&nil` would be a good thing, even if the benefits can only be unlocked 3 years into the future.
> We'd want to solve it for these particular mock library methods before Ruby 3.6, no?
Sure, and those libraries can start using the `raise ... if block_given?` workaround today, but move to using `&nil` a few years later. On the other hand, we at Shopify move our baseline Ruby across the company aggressively to the brand new version of Ruby every year. If the `&nil` syntax makes it to Ruby 3.3, we could start using it for a lot of our internal code by May 2024, for example. However, by delaying implementation, we would be making sure that no one gets to benefit from this useful language feature.
----------------------------------------
Feature #19979: Allow methods to declare that they don't accept a block via `&nil`
https://bugs.ruby-lang.org/issues/19979#change-105140
* Author: ufuk (Ufuk Kayserilioglu)
* Status: Open
* Priority: Normal
----------------------------------------
## Abstract
This feature proposes new syntax to allow methods to explicitly declare that they don't accept blocks, and makes passing of a block to such methods an error.
## Background
In #15554, it was proposed to automatically detect methods that do not use the block passed to them, and to error if a block was passed to such methods. As far as I can tell, it was later on closed since #10499 solved a large part of the problem.
That proposal has, as part of [a dev meeting discussion](https://github.com/ruby/dev-meeting-log/blob/b4357853c03dfe71b6eab320d5642d463854f50f/2019/DevMeeting-2019-01-10.md?plain=1#L110-L120), a proposal from @matz to allow methods to use `&nil` to explicitly declare that they don't accept a block. At the time, the proposal was trying to solve a bigger problem, so this sub-proposal was never considered seriously. However, notes in the proposal say:
> It is explicit, but it is tough to add this `&nil` parameter declaration to all of methods (do you want to add it to `def []=(i, e, &nil)`?). (I agree `&nil` is valuable on some situations)
This proposal extracts that sub-proposal to make this a new language feature.
## Proposal
In Ruby, it is always valid for the caller to pass a block to a method call, even if the callee is not expecting a block to be passed. This leads to subtle user errors, where the author of some code assumes a method call uses a block, but the block passed to the method call is silently ignored.
The proposal is to introduce `&nil` at method declaration sites to mean "This method does not accept a block". This is symmetric to the ability to pass `&nil` at call sites to mean "I am not passing a block to this method call", which is sometimes useful when making `super` calls (since blocks are always implicitly passed).
Explicitly, the proposal is to make the following behaviour be a part of Ruby:
```ruby
def find(item = nil, &nil)
# some implementation that doesn't call `yield` or `block_given?`
end
find { |i| i == 42 }
# => ArgumentError: passing block to the method `find' that does not accept a block.
```
## Implementation
I assume the implementation would be a grammar change to make `&nil` valid at method declaration sites, as well as raising an `ArgumentError` for methods that are called with a block but are declared with `&nil`.
## Evaluation
Since I don't have an implementation, I can't make a proper evaluation of the feature proposal. However, I would expect the language changes to be minimal with no runtime costs for methods that don't use the `&nil` syntax.
## Discussion
This proposal has much smaller scope than #15554 so that the Ruby language can start giving library authors the ability to explicitly mark their methods as not accepting a block. This is fully backward compatible, since it is an opt-in behaviour and not an opt-out one.
Future directions after this feature proposal could be a way to signal to the VM that any method in a file that doesn't explicitly use `yield`/`block_given?` or explicitly declared a block parameter should be treated as not accepting a block. This can be done via some kind of pragma similar to `frozen_string_literal`, or through other means. However, such future directions are beyond the scope of this proposal.
## Summary
Adding the ability for methods to declare that they don't accept a block will make writing code against such methods safer and more resilient, and will prevent silently ignored behaviour that is often hard to catch or troubleshoot.
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/