megashigger
megashigger

Reputation: 9053

What kind of data type is ('a'..'z')?

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

Answers (3)

Michael Stalker
Michael Stalker

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

lurker
lurker

Reputation: 58284

It's a Range:

 ('a'..'z').class
 => Range

You can convert it to an array with ('a'..'z').to_a.

Upvotes: 6

Matt
Matt

Reputation: 20796

It's a Range:

irb(main):001:0> ('a'..'z').class
=> Range

Upvotes: 3

Related Questions