* [ruby-core:119606] [Ruby master Feature#20812] Proposal for Safe Include Method in Ruby
@ 2024-10-24 12:57 rogerconsul (Roger Consul) via ruby-core
2024-10-24 13:10 ` [ruby-core:119607] " jeremyevans0 (Jeremy Evans) via ruby-core
2024-10-24 13:19 ` [ruby-core:119608] " rogerconsul (Roger Consul) via ruby-core
0 siblings, 2 replies; 3+ messages in thread
From: rogerconsul (Roger Consul) via ruby-core @ 2024-10-24 12:57 UTC (permalink / raw)
To: ruby-core; +Cc: rogerconsul (Roger Consul)
Issue #20812 has been reported by rogerconsul (Roger Consul).
----------------------------------------
Feature #20812: Proposal for Safe Include Method in Ruby
https://bugs.ruby-lang.org/issues/20812
* Author: rogerconsul (Roger Consul)
* Status: Open
----------------------------------------
# Proposal for Safe Include Method in Ruby
## Description
Add a new method `include_safe?` to Ruby's `Enumerable` module that safely handles nil arguments in inclusion checks.
## Problem Statement
The current `include?` method raises an error when passed `nil` as an argument. This requires developers to write defensive code with explicit nil checks, leading to less readable and more error-prone code.
```ruby
# Current problematic scenarios:
collection.include?(nil) # Works, checks for nil in collection
collection.include?(value) # Raises error if value is nil
# Current workarounds:
value && collection.include?(value)
collection.include?(value.to_s)
```
## Proposed Solution
Add `include_safe?` method that returns `false` when the argument is `nil`:
```ruby
module Enumerable
def include_safe?(obj)
return false if obj.nil?
include?(obj)
end
end
```
### Usage Examples
```ruby
numbers = [1, 2, 3]
document_id = nil
# Current approach
document_id && numbers.include?(document_id) # false
# Proposed approach
numbers.include_safe?(document_id) # false
# Works normally for non-nil values
numbers.include_safe?(2) # true
numbers.include_safe?(4) # false
# Edge cases handled
[nil].include_safe?(nil) # false
[].include_safe?(nil) # false
```
## Benefits
1. **Improved Safety**: Eliminates a common source of runtime errors
2. **Better Readability**: Removes need for explicit nil checks
3. **Consistent Behavior**: Provides predictable handling of nil values
4. **Rails Alignment**: Similar to Rails' safe navigation patterns
5. **Reduced Boilerplate**: Eliminates common defensive coding patterns
## Implementation Notes
This would be implemented in C as part of Ruby's core, but here's a Ruby reference implementation:
```ruby
module Enumerable
def include_safe?(obj)
return false if obj.nil?
include?(obj)
end
end
```
## Testing Strategy
```ruby
require 'minitest/autorun'
class TestIncludeSafe < Minitest::Test
def setup
@array = [1, 2, 3]
@array_with_nil = [1, nil, 3]
end
def test_basic_inclusion
assert @array.include_safe?(1)
refute @array.include_safe?(4)
end
def test_nil_handling
refute @array.include_safe?(nil)
refute @array_with_nil.include_safe?(nil)
end
def test_empty_collection
refute [].include_safe?(nil)
refute [].include_safe?(1)
end
end
```
## Alternative Considerations
1. **Name Alternatives**:
- `try_include?`
- `safe_include?`
- `includes_safely?`
2. **Alternative Approaches**:
- Modify existing `include?` behavior (rejected due to backward compatibility)
- Add parameter to existing `include?` (rejected for clarity)
## Impact Analysis
### Positive Impact
- Reduces runtime errors
- Improves code readability
- Follows principle of least surprise
### Potential Concerns
- Another method to learn
- Possible confusion with regular `include?`
## Similar Features in Ruby
- Safe navigation operator (`&.`)
- `try` method in Rails
- `fetch` method with default value
## Backward Compatibility
This change is fully backward compatible as it introduces a new method without modifying existing behavior.
## Reference Implementation
A gem implementing this feature is available at: [Link to gem if created]
## Questions for Core Team
1. Is `include_safe?` the best name for this method?
2. Should this be added to `Array` specifically rather than `Enumerable`?
3. Should we consider any additional edge cases?
--
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/lists/ruby-core.ml.ruby-lang.org/
^ permalink raw reply [flat|nested] 3+ messages in thread
* [ruby-core:119607] [Ruby master Feature#20812] Proposal for Safe Include Method in Ruby
2024-10-24 12:57 [ruby-core:119606] [Ruby master Feature#20812] Proposal for Safe Include Method in Ruby rogerconsul (Roger Consul) via ruby-core
@ 2024-10-24 13:10 ` jeremyevans0 (Jeremy Evans) via ruby-core
2024-10-24 13:19 ` [ruby-core:119608] " rogerconsul (Roger Consul) via ruby-core
1 sibling, 0 replies; 3+ messages in thread
From: jeremyevans0 (Jeremy Evans) via ruby-core @ 2024-10-24 13:10 UTC (permalink / raw)
To: ruby-core; +Cc: jeremyevans0 (Jeremy Evans)
Issue #20812 has been updated by jeremyevans0 (Jeremy Evans).
rogerconsul (Roger Consul) wrote:
> The current `include?` method raises an error when passed `nil` as an argument.
Are you sure?
```ruby
# No Error
[1, 2].include?(nil)
[Object.new].include?(nil)
# Error, but due to custom ==, not include?
o = Object.new
def o.==(v) = (raise unless v)
[o].include?(nil)
```
Maybe you are using some core extension that causes `include?` to raise an error if given `nil`? Can you provide a self-contained reproducible example that shows `include?` raising if the argument is `nil`?
----------------------------------------
Feature #20812: Proposal for Safe Include Method in Ruby
https://bugs.ruby-lang.org/issues/20812#change-110228
* Author: rogerconsul (Roger Consul)
* Status: Open
----------------------------------------
# Proposal for Safe Include Method in Ruby
## Description
Add a new method `include_safe?` to Ruby's `Enumerable` module that safely handles nil arguments in inclusion checks.
## Problem Statement
The current `include?` method raises an error when passed `nil` as an argument. This requires developers to write defensive code with explicit nil checks, leading to less readable and more error-prone code.
```ruby
# Current problematic scenarios:
collection.include?(nil) # Works, checks for nil in collection
collection.include?(value) # Raises error if value is nil
# Current workarounds:
value && collection.include?(value)
collection.include?(value.to_s)
```
## Proposed Solution
Add `include_safe?` method that returns `false` when the argument is `nil`:
```ruby
module Enumerable
def include_safe?(obj)
return false if obj.nil?
include?(obj)
end
end
```
### Usage Examples
```ruby
numbers = [1, 2, 3]
document_id = nil
# Current approach
document_id && numbers.include?(document_id) # false
# Proposed approach
numbers.include_safe?(document_id) # false
# Works normally for non-nil values
numbers.include_safe?(2) # true
numbers.include_safe?(4) # false
# Edge cases handled
[nil].include_safe?(nil) # false
[].include_safe?(nil) # false
```
## Benefits
1. **Improved Safety**: Eliminates a common source of runtime errors
2. **Better Readability**: Removes need for explicit nil checks
3. **Consistent Behavior**: Provides predictable handling of nil values
4. **Rails Alignment**: Similar to Rails' safe navigation patterns
5. **Reduced Boilerplate**: Eliminates common defensive coding patterns
## Implementation Notes
This would be implemented in C as part of Ruby's core, but here's a Ruby reference implementation:
```ruby
module Enumerable
def include_safe?(obj)
return false if obj.nil?
include?(obj)
end
end
```
## Testing Strategy
```ruby
require 'minitest/autorun'
class TestIncludeSafe < Minitest::Test
def setup
@array = [1, 2, 3]
@array_with_nil = [1, nil, 3]
end
def test_basic_inclusion
assert @array.include_safe?(1)
refute @array.include_safe?(4)
end
def test_nil_handling
refute @array.include_safe?(nil)
refute @array_with_nil.include_safe?(nil)
end
def test_empty_collection
refute [].include_safe?(nil)
refute [].include_safe?(1)
end
end
```
## Alternative Considerations
1. **Name Alternatives**:
- `try_include?`
- `safe_include?`
- `includes_safely?`
2. **Alternative Approaches**:
- Modify existing `include?` behavior (rejected due to backward compatibility)
- Add parameter to existing `include?` (rejected for clarity)
## Impact Analysis
### Positive Impact
- Reduces runtime errors
- Improves code readability
- Follows principle of least surprise
### Potential Concerns
- Another method to learn
- Possible confusion with regular `include?`
## Similar Features in Ruby
- Safe navigation operator (`&.`)
- `try` method in Rails
- `fetch` method with default value
## Backward Compatibility
This change is fully backward compatible as it introduces a new method without modifying existing behavior.
## Reference Implementation
A gem implementing this feature is available at: [Link to gem if created]
## Questions for Core Team
1. Is `include_safe?` the best name for this method?
2. Should this be added to `Array` specifically rather than `Enumerable`?
3. Should we consider any additional edge cases?
--
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/lists/ruby-core.ml.ruby-lang.org/
^ permalink raw reply [flat|nested] 3+ messages in thread
* [ruby-core:119608] [Ruby master Feature#20812] Proposal for Safe Include Method in Ruby
2024-10-24 12:57 [ruby-core:119606] [Ruby master Feature#20812] Proposal for Safe Include Method in Ruby rogerconsul (Roger Consul) via ruby-core
2024-10-24 13:10 ` [ruby-core:119607] " jeremyevans0 (Jeremy Evans) via ruby-core
@ 2024-10-24 13:19 ` rogerconsul (Roger Consul) via ruby-core
1 sibling, 0 replies; 3+ messages in thread
From: rogerconsul (Roger Consul) via ruby-core @ 2024-10-24 13:19 UTC (permalink / raw)
To: ruby-core; +Cc: rogerconsul (Roger Consul)
Issue #20812 has been updated by rogerconsul (Roger Consul).
jeremyevans0 (Jeremy Evans) wrote in #note-1:
> rogerconsul (Roger Consul) wrote:
> > The current `include?` method raises an error when passed `nil` as an argument.
>
> Are you sure?
>
> ```ruby
> # No Error
> [1, 2].include?(nil)
> [Object.new].include?(nil)
>
> # Error, but due to custom ==, not include?
> o = Object.new
> def o.==(v) = (raise unless v)
> [o].include?(nil)
> ```
>
> Maybe you are using some core extension that causes `include?` to raise an error if given `nil`? Can you provide a self-contained reproducible example that shows `include?` raising if the argument is `nil`?
Well... After you mentioned it, I realized we were using version 2.7.5 🥲
Error didn't reproduce on newer versions. We can close this thread.
Thanks for your time, Jeremy <3
----------------------------------------
Feature #20812: Proposal for Safe Include Method in Ruby
https://bugs.ruby-lang.org/issues/20812#change-110229
* Author: rogerconsul (Roger Consul)
* Status: Open
----------------------------------------
# Proposal for Safe Include Method in Ruby
## Description
Add a new method `include_safe?` to Ruby's `Enumerable` module that safely handles nil arguments in inclusion checks.
## Problem Statement
The current `include?` method raises an error when passed `nil` as an argument. This requires developers to write defensive code with explicit nil checks, leading to less readable and more error-prone code.
```ruby
# Current problematic scenarios:
collection.include?(nil) # Works, checks for nil in collection
collection.include?(value) # Raises error if value is nil
# Current workarounds:
value && collection.include?(value)
collection.include?(value.to_s)
```
## Proposed Solution
Add `include_safe?` method that returns `false` when the argument is `nil`:
```ruby
module Enumerable
def include_safe?(obj)
return false if obj.nil?
include?(obj)
end
end
```
### Usage Examples
```ruby
numbers = [1, 2, 3]
document_id = nil
# Current approach
document_id && numbers.include?(document_id) # false
# Proposed approach
numbers.include_safe?(document_id) # false
# Works normally for non-nil values
numbers.include_safe?(2) # true
numbers.include_safe?(4) # false
# Edge cases handled
[nil].include_safe?(nil) # false
[].include_safe?(nil) # false
```
## Benefits
1. **Improved Safety**: Eliminates a common source of runtime errors
2. **Better Readability**: Removes need for explicit nil checks
3. **Consistent Behavior**: Provides predictable handling of nil values
4. **Rails Alignment**: Similar to Rails' safe navigation patterns
5. **Reduced Boilerplate**: Eliminates common defensive coding patterns
## Implementation Notes
This would be implemented in C as part of Ruby's core, but here's a Ruby reference implementation:
```ruby
module Enumerable
def include_safe?(obj)
return false if obj.nil?
include?(obj)
end
end
```
## Testing Strategy
```ruby
require 'minitest/autorun'
class TestIncludeSafe < Minitest::Test
def setup
@array = [1, 2, 3]
@array_with_nil = [1, nil, 3]
end
def test_basic_inclusion
assert @array.include_safe?(1)
refute @array.include_safe?(4)
end
def test_nil_handling
refute @array.include_safe?(nil)
refute @array_with_nil.include_safe?(nil)
end
def test_empty_collection
refute [].include_safe?(nil)
refute [].include_safe?(1)
end
end
```
## Alternative Considerations
1. **Name Alternatives**:
- `try_include?`
- `safe_include?`
- `includes_safely?`
2. **Alternative Approaches**:
- Modify existing `include?` behavior (rejected due to backward compatibility)
- Add parameter to existing `include?` (rejected for clarity)
## Impact Analysis
### Positive Impact
- Reduces runtime errors
- Improves code readability
- Follows principle of least surprise
### Potential Concerns
- Another method to learn
- Possible confusion with regular `include?`
## Similar Features in Ruby
- Safe navigation operator (`&.`)
- `try` method in Rails
- `fetch` method with default value
## Backward Compatibility
This change is fully backward compatible as it introduces a new method without modifying existing behavior.
## Reference Implementation
A gem implementing this feature is available at: [Link to gem if created]
## Questions for Core Team
1. Is `include_safe?` the best name for this method?
2. Should this be added to `Array` specifically rather than `Enumerable`?
3. Should we consider any additional edge cases?
--
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/lists/ruby-core.ml.ruby-lang.org/
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-10-24 13:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-24 12:57 [ruby-core:119606] [Ruby master Feature#20812] Proposal for Safe Include Method in Ruby rogerconsul (Roger Consul) via ruby-core
2024-10-24 13:10 ` [ruby-core:119607] " jeremyevans0 (Jeremy Evans) via ruby-core
2024-10-24 13:19 ` [ruby-core:119608] " rogerconsul (Roger Consul) via ruby-core
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).