[ruby-core:94475] [Ruby master Feature#15864] Proposal: Add methods to determine if it is an infinite range

[email protected]
Newsgroups gmane.comp.lang.ruby.core
Message-ID <redmine.journal-80910.20190822073648.d6d6c574b7f3cb51@ruby-lang.org>
Issue #15864 has been updated by mame (Yusuke Endoh).


> Having `begin?` and `end?` instead of `beginless?` and `endless?` would be more natural, and easy to comprehend.

Agreed.  Moreover, `Range#begin` and `#end` just work.


----------------------------------------
Feature #15864: Proposal: Add methods to determine if it is an infinite range
https://bugs.ruby-lang.org/issues/15864#change-80910

* Author: osyo (manga osyo)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------

## Summary

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


## Current status

```ruby
# 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

```ruby
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

```ruby
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

```ruby
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




-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.