Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New Concept]: Range #1569

Merged
merged 8 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions concepts/ranges/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ They can be used for many things like quickly creating a collection, slicing str
They are created using the range operator `..` or `...` (inclusive and exclusive respectively).

```ruby
1..5 # => 1, 2, 3, 4, 5
1...5 # => 1, 2, 3, 4
1..5 # => 1..5
1...5 # => 1...5

(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]
```

The reason for having two range operators is to allow to create ranges that are inclusive or exclusive of the end value, which can be useful when for example working with indexes, that are zero based.
Expand All @@ -31,7 +34,7 @@ This is because the otherwise will the method be called on the 2nd argument of t
## Getting substrings

When wanting to slice a string, you can use the range operator to get a substring.
That is by creating a range with the start and end index of the substring.
That is, by creating a range with the start and end index of the sub-string.

```ruby
"Hello World"[0..4] # => "Hello"
Expand All @@ -54,15 +57,15 @@ These methods when for example want to get the sum of all the values in the rang
| ----------------------- | ----------------------------------------------------------------------- | ------------------------------- |
| [`sum`][sum] | Returns the sum of all the values in the range | `(1..5).sum # => 15` |
| [`size`][size] | Returns the size of the range | `(1..5).size # => 5` |
| [`include?`][indlude] | Returns `true` if the range includes the given value, otherwise `false` | `(1..5).include?(3) # => true` |
| [`include?`][indlude] | Returns `true` if the range includes the given value, otherwise `false` | `(1..5).include?(3) # => true` |

## Endless & Beginless ranges

There are two special types of ranges, the endless and beginless ranges.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if they are really special ranges, or if this is more "syntactic sugar" that lets us express the normal ranges like this.

This means that the range has no beginning or end.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we terminate them with negative infinity and positive infinity, then we can see that they do have a beginning or end.

The endless or beginless range has there start or end value being `nil`, but when defining the range so can nil be omitted.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

irb(main):004:0> Range.new(nil, 5)
ArgumentError: bad value for range
        from (irb):4:in `initialize'
        from (irb):4:in `new'
        from (irb):4
        from :0
irb(main):005:0> (nil..5)
ArgumentError: bad value for range
        from (irb):5
        from :0
irb(main):006:0> 

I do not think this is true, demonstrably.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Looking in the docs are there also mention of nil: https://rubyapi.org/3.2/o/range.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. That is why I said think... and did it in an REPL, to verify. Seems like it has changed for newer versions of Ruby.

So I would then expect it to no longer be a terminated by infinity anything, and perhaps "undefined" in behavior. I will definitely look at the source code. Pretty sure the use will not change from 1..infinity as 1..nil though. (That would be surprising, but nil evaluates as 0 if we do to_i and as 0.0 if we do nil.to_f so definitely worth investigating.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you sent a picture too. Whatever it is, I a sure it supports your statement. Not at a good device at the moment to get interpretations for pictures.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for information, I happened to have a Pry session open, where Pry has a bug that does not show this as it is supposed to. That was the reason it was broken as shown. Not the syntax itself. "Bad Pry!"

meatball133 marked this conversation as resolved.
Show resolved Hide resolved

Using beginless and endless ranges is useful when you want to for example slice a string from the beginning or to the end.
Using beginless and endless ranges is useful when you want to, for example, slice a string from the beginning or to the end.

```ruby
"Hello World"[0..] # => "Hello World"
Expand All @@ -71,17 +74,16 @@ Using beginless and endless ranges is useful when you want to for example slice
```

```exercism/caution
If not used on a collection, the endless range can cause an infinite loop, if not used with caution.
If not used on a collection, the endless range can cause an endless sequence, if not used with caution.
```

## String ranges

Strings can also be used in ranges and allow one to get an interval of strings between two strings.
But its behavior is a bit different than with chars, when using multiple characters in a string range.
Its behavior can become when doing more complex string ranges, so use it with caution.
Its behavior can be a bit unexpected when using certain strings, so use it with caution.

```ruby
"aa".."az" # => "aa", "ab", "ac", ..., "az"
"aa".."az".to_a # => ["aa", "ab", "ac", ..., "az"]
```

## Custom objects in ranges
Expand Down
20 changes: 11 additions & 9 deletions concepts/ranges/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ They can be used for many things like quickly creating a collection, slicing str
They are created using the range operator `..` or `...` (inclusive and exclusive respectively).

```ruby
1..5 # => 1, 2, 3, 4, 5
1...5 # => 1, 2, 3, 4
1..5 # => 1..5
1...5 # => 1...5

(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]
kotp marked this conversation as resolved.
Show resolved Hide resolved
```

The reason for having two range operators is to allow to create ranges that are inclusive or exclusive of the end value, which can be useful when for example working with indexes, that are zero based.
Expand All @@ -31,7 +34,7 @@ This is because the otherwise will the method be called on the 2nd argument of t
## Getting substrings

When wanting to slice a string, you can use the range operator to get a substring.
That is by creating a range with the start and end index of the substring.
That is, by creating a range with the start and end index of the sub-string.

```ruby
"Hello World"[0..4] # => "Hello"
Expand All @@ -54,15 +57,15 @@ These methods when for example want to get the sum of all the values in the rang
| ----------------------- | ----------------------------------------------------------------------- | ------------------------------- |
| [`sum`][sum] | Returns the sum of all the values in the range | `(1..5).sum # => 15` |
| [`size`][size] | Returns the size of the range | `(1..5).size # => 5` |
| [`include?`][indlude] | Returns `true` if the range includes the given value, otherwise `false` | `(1..5).include?(3) # => true` |
| [`include?`][indlude] | Returns `true` if the range includes the given value, otherwise `false` | `(1..5).include?(3) # => true` |

## Endless & Beginless ranges

There are two special types of ranges, the endless and beginless ranges.
This means that the range has no beginning or end.
The endless or beginless range has there start or end value being `nil`, but when defining the range so can nil be omitted.

Using beginless and endless ranges is useful when you want to for example slice a string from the beginning or to the end.
Using beginless and endless ranges is useful when you want to, for example, slice a string from the beginning or to the end.

```ruby
"Hello World"[0..] # => "Hello World"
Expand All @@ -71,17 +74,16 @@ Using beginless and endless ranges is useful when you want to for example slice
```

```exercism/caution
If not used on a collection, the endless range can cause an infinite loop, if not used with caution.
If not used on a collection, the endless range can cause an endless sequence, if not used with caution.
```

## String ranges

Strings can also be used in ranges and allow one to get an interval of strings between two strings.
But its behavior is a bit different than with chars, when using multiple characters in a string range.
Its behavior can become when doing more complex string ranges, so use it with caution.
Its behavior can be a bit unexpected when using certain strings, so use it with caution.

```ruby
"aa".."az" # => "aa", "ab", "ac", ..., "az"
"aa".."az".to_a # => ["aa", "ab", "ac", ..., "az"]
```

[range]: https://rubyapi.org/o/range
Expand Down
20 changes: 11 additions & 9 deletions exercises/concept/chess-game/.docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ They can be used for many things like quickly creating a collection, slicing str
They are created using the range operator `..` or `...` (inclusive and exclusive respectively).

```ruby
1..5 # => 1, 2, 3, 4, 5
1...5 # => 1, 2, 3, 4
1..5 # => 1..5
1...5 # => 1...5

(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]
```

The reason for having two range operators is to allow to create ranges that are inclusive or exclusive of the end value, which can be useful when for example working with indexes, that are zero based.
Expand All @@ -31,7 +34,7 @@ This is because the otherwise will the method be called on the 2nd argument of t
## Getting substrings

When wanting to slice a string, you can use the range operator to get a substring.
That is by creating a range with the start and end index of the substring.
That is, by creating a range with the start and end index of the sub-string.

```ruby
"Hello World"[0..4] # => "Hello"
Expand All @@ -54,15 +57,15 @@ These methods when for example want to get the sum of all the values in the rang
| ----------------------- | ----------------------------------------------------------------------- | ------------------------------- |
| [`sum`][sum] | Returns the sum of all the values in the range | `(1..5).sum # => 15` |
| [`size`][size] | Returns the size of the range | `(1..5).size # => 5` |
| [`include?`][indlude] | Returns `true` if the range includes the given value, otherwise `false` | `(1..5).include?(3) # => true` |
| [`include?`][indlude] | Returns `true` if the range includes the given value, otherwise `false` | `(1..5).include?(3) # => true` |

## Endless & Beginless ranges

There are two special types of ranges, the endless and beginless ranges.
This means that the range has no beginning or end.
The endless or beginless range has there start or end value being `nil`, but when defining the range so can nil be omitted.

Using beginless and endless ranges is useful when you want to for example slice a string from the beginning or to the end.
Using beginless and endless ranges is useful when you want to, for example, slice a string from the beginning or to the end.

```ruby
"Hello World"[0..] # => "Hello World"
Expand All @@ -71,17 +74,16 @@ Using beginless and endless ranges is useful when you want to for example slice
```

```exercism/caution
If not used on a collection, the endless range can cause an infinite loop, if not used with caution.
If not used on a collection, the endless range can cause an endless sequence, if not used with caution.
```

## String ranges

Strings can also be used in ranges and allow one to get an interval of strings between two strings.
But its behavior is a bit different than with chars, when using multiple characters in a string range.
Its behavior can become when doing more complex string ranges, so use it with caution.
Its behavior can be a bit unexpected when using certain strings, so use it with caution.

```ruby
"aa".."az" # => "aa", "ab", "ac", ..., "az"
"aa".."az".to_a # => ["aa", "ab", "ac", ..., "az"]
```

[range]: https://rubyapi.org/o/range
Expand Down