Reputation: 9053
If I type ('a'..'z').each { |a| puts a}
, what exactly is going on at the datatype level? I know that when it's printed, it's individual strings but what is 'a'..'z'
on its own? Is it an array?
Upvotes: 0
Views: 306
Reputation: 1367
To answer the second part of your question, 'a'..'z'
is a Range
. Like others have said:
('a'..'z').class # => Range
To answer the first part of your question about what is happening at the data type level, a range is like an array in several ways. When you use letters as your range endpoints, the range contains discrete elements, just like an array would. In other words, it contains all the letters from 'a'
to 'z'
, inclusively. The same goes for when you use integers. 1..5
contains 1
, 2
, 3
, 4
, and 5
. Like the Array
class, Range
includes the Enumerable
module, so it has a bunch of methods like each
. In your example, each
is iterating over the members of your range.
Ranges differ from arrays in a few important ways.
First, you can use Float
values as endpoints. For example, 1.1..5
is a valid range:
(1.1..5).class # => Range
When you try to iterate over a range like that, it will raise an error:
(1.1..5).each { |a| puts a } # => TypeError: can't iterate from Float
This is because the elements of that range are not discrete. The range is continuous.
Ranges also differ from arrays in that you can define them in a way that excludes the second endpoint by using ...
instead of ..
. For example, 'a'...'z'
contains the letters 'a' through 'y'. 'z' is not in this range. You can try ('a'...'z').each { |a| puts a }
to demonstrate this.
Upvotes: 0