Project

General

Profile

Actions

Feature #15864

open

Proposal: Add methods to determine if it is an infinite range

Added by osyo (manga osyo) over 2 years ago. Updated over 2 years ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:92732]

Description

Summary

Proposal to add methods to determine if it is an infinite range.

Current status

# begin / end return nil
p (..10).begin  # => nil
p (1..).end     # => nil

# But, first / last raise an exception
p (..10).first  # Error: in `first': cannot get the first element of beginless range (RangeError)
p (1..).last    # Error: in `last': cannot get the last element of endless range (RangeError)

# Returns Infinity if it is a Numeric
p (1..10).size      # => 10
p (1..).size        # => Infinity
p (..1).size        # => Infinity

# Otherwise returns nil
p ("a".."z").size   # => nil
p ("a"..).size      # => nil
p (.."z").size      # => nil
  • (..10).begin return nil, but (..10).first raise an exception.
  • (1..).size return Infinity, but ("a"..).size return nil.
  • Behavior changes depending on the state of Range and the called method.
  • It is difficult to determine if it is an infinite range.

Proposal methods

  • Range#beginless?
    • return true if begin is nil
  • Range#endless?
    • return true if end is nil
  • Range#infinite?
    • return true if begin is nil or end is nil
  • Range#finite?
    • return true if begin is not nil and end is not nil

Example

p (1..10).beginless?  # => false
p (1..10).endless?    # => false
p (1..10).infinite?   # => false
p (1..10).finite?     # => true

p (..10).beginless?   # => true
p (..10).endless?     # => false
p (..10).infinite?    # => true
p (..10).finite?      # => false

p (1..).beginless?    # => false
p (1..).endless?      # => true
p (1..).infinite?     # => true
p (1..).finite?       # => false

# NOTE: Float::INFINITY is not support
p (1..Float::INFINITY).beginless?    # => false
p (1..Float::INFINITY).endless?      # => false
p (1..Float::INFINITY).infinite?     # => false
p (1..Float::INFINITY).finite?       # => true

Use case

before

def search_in(range)
  query = "/search"
  if !(range.begin.nil? || range.end.nil?)
    "#{query}?from=#{range.begin}&to=#{range.end}"
  elsif range.begin.nil?
    "#{query}?to=#{range.end}"
  elsif range.end.nil?
    "#{query}?from=#{range.begin}"
  else
    query
  end
end

p search_in("2019-1-1".."2019-4-30")
# => "/search?from=2019-1-1&to=2019-4-30"

p search_in(.."2019-4-30")
# => "/search?to=2019-4-30"

p search_in("2019-5-1"..)
# => "/search?from=2019-5-1"

after

def search_in(range)
  query = "/search"
  if range.finite?
    "#{query}?from=#{range.begin}&to=#{range.end}"
  elsif range.beginless?
    "#{query}?to=#{range.end}"
  elsif range.endless?
    "#{query}?from=#{range.begin}"
  else
    query
  end
end

p search_in("2019-1-1".."2019-4-30")
# => "/search?from=2019-1-1&to=2019-4-30"

p search_in(.."2019-4-30")
# => "/search?to=2019-4-30"

p search_in("2019-5-1"..)
# => "/search?from=2019-5-1"

Memo

  • Check whether the tip is infinite only with nil.
  • Float::INFINITY is not supported.
    • I think that there is no relation between Float::INFINITY and infinite Range.
  • I would like an opinion on how to determine if it is infinite.
    • see range.begin.infinite? ?
  • Uhether there is a better name for the method name.
    • e.g. #infinite? to #infinity?.

Thank you.

github pull request: https://github.com/ruby/ruby/pull/2196


Related issues

Related to Ruby master - Misc #16114: Naming of "beginless range"OpenActions
Actions

Also available in: Atom PDF