Actions
Feature #20812
closedProposal for Safe Include Method in Ruby
Status:
Closed
Assignee:
-
Target version:
-
Description
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.
# 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
:
module Enumerable
def include_safe?(obj)
return false if obj.nil?
include?(obj)
end
end
Usage Examples¶
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¶
- Improved Safety: Eliminates a common source of runtime errors
- Better Readability: Removes need for explicit nil checks
- Consistent Behavior: Provides predictable handling of nil values
- Rails Alignment: Similar to Rails' safe navigation patterns
- 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:
module Enumerable
def include_safe?(obj)
return false if obj.nil?
include?(obj)
end
end
Testing Strategy¶
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¶
-
Name Alternatives:
try_include?
safe_include?
includes_safely?
-
Alternative Approaches:
- Modify existing
include?
behavior (rejected due to backward compatibility) - Add parameter to existing
include?
(rejected for clarity)
- Modify existing
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¶
- Is
include_safe?
the best name for this method? - Should this be added to
Array
specifically rather thanEnumerable
? - Should we consider any additional edge cases?
Actions
Like0
Like0Like0Like0