How to Convert a Ruby String Range to a Range Object

What is the best way to convert a Ruby string range to a Range object

But then just do

ends = '20080201..20080229'.split('..').map{|d| Integer(d)}
ends[0]..ends[1]

anyway I don't recommend eval, for security reasons

Is it possible to convert range to string?

Yes, try:

("a".."z").to_a.join # => => "abcdefghijklmnopqrstuvwxyz"
  1. You need to convert range to array with to_a.
  2. You can join the elements of the array.

Hope that helps!

Correct way to populate an Array with a Range in Ruby

You can create an array with a range using splat,

>> a=*(1..10)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

using Kernel Array method,

Array (1..10)
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

or using to_a

(1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Why is the difference between the Range objects 'A'..'AB' and 'B'..'AB' in Ruby?

It's because of a discrepancy between String#succ and String#<=>:

'a'.succ       #=> 'b'
'a' < 'a'.succ #=> true

but:

'z'.succ       #=> 'aa'
'z' < 'z'.succ #=> false

Range utilizes both, succ and <=> when generating a sequence. It uses succ to generate each successive value and checks via <=> that the values are indeed successive (ending the sequence if not).1

Even String#upto behaves this way. I've recently filed a bug report, because I'm under the impression that it should handle this properly.


1 This is the behavior for iterating custom objects. Range behaves more oddly for the built-in String class, maybe because of optimizations.

Generating integer within range from unique string in ruby

Here's the problem - your range of numbers has only 3.6x10^9 possible values where as your sample unique string (which looks like a hex integer with 36 digits) has 16^32 possible values (i.e. many more). So when mapping your string into your integer range there will be collisions.

The mapping function itself can be pretty straightforward, I would do something such as below (also, consider using only a part of the input string for integer conversion, e.g. the first seven digits, if performance becomes critical):

def my_hash(str, min, max)
range = (max - min).abs
(str.to_i(16) % range) + min
end

my_hash(did, min_cid, max_cid) # => 2461595789

[Edit] If you are using Ruby 1.8 and your adjusted range can be represented as a Fixnum, just use the hash value of the input string object instead of parsing it as a big integer. Note that this strategy might not be safe in Ruby 1.9 (per the comment by @DataWraith) as object hash values may be randomized between invocations of the interpreter so you would not get the same hash number for the same input string when you restart your application:

def hash_range(obj, min, max)
(obj.hash % (max-min).abs) + [min, max].min
end

hash_range(did, min_cid, max_cid) # => 3886226395

And, of course, you'll have to decide what to do about collisions. You'll likely have to persist a bucket of input strings which map to the same value and decide how to resolve the conflicts if you are looking up by the mapped value.

to_a' is not a method in 'Range', yet, it works on 'Range'?

The following code is valid ruby:

b = (1..5).to_a

(1..5) is a Range object, and b is an Array object. The official(?) documentation for the Class Range does not document the method to_a, which appears to convert a range to an array.

So, how is the above legal Ruby?

Ruby has something called "inheritance". Inheritance is a method for differential code-reuse that actually does not only exist in Ruby, but is in fact quite popular in many languages such as Java, C♯, C++, Python, PHP, Scala, Kotlin, Ceylon, and so on and so forth.

Inheritance allows you to define methods in one place, and then inherit them in another place, overriding and defining only the methods whose behavior differs. Hence, "differential code re-use".

In this particular case, the method you are looking at is Enumerable#to_a.

Note: Ruby actually has two forms of inheritance, mixin inheritance and class inheritance. Mixin inheritance is like class inheritance where the mixin doesn't know its superclass. (The definitive resource about mixin inheritance is Gilad Bracha's PhD Thesis The Programming Language Jigsaw – Mixins, Modularity, and Multiple Inheritance.)

The official(?) documentation

Actually, ruby-doc is a third-party site. There is no official documentation site. (However, the documentation on ruby-doc is generated from documentation comments in YARV, one of the major Ruby implementations, and one that Yukihiro Matsumoto actively contributes to.)

Since this documentation is presumably autogenerated from the source with Yard,

It is actually autogenerated from the YARV source with RDoc, not YARD.

I'm confused how it could not be in the list of methods,

Note that the explanation I gave is the correct one, but there could be many other explanations. The most simple one: the reason why the method is not in the documentation is that it is not documented. Another reason could be a bug in the documentation generator that prevents the documentation for that method being displayed, a typo in the source code that prevents the documentation generator from recognizing the documentation, and many, many others.

so is there auto conversion going on?

No. Ruby does not have automatic conversions in the language. There are some methods which for reasons of efficiency are implemented in a non-object-oriented manner, and require an object to be an instance of a specific class (as opposed to the object-oriented manner, which would only require the object to conform to a specific protocol). Because it is a severe restriction to require an object to be an instance of a specific class, those methods will usually offer an "escape hatch" to the programmer, by sending a specific message and allowing the object to respond with an object of the required class.

For example, all methods printing something to the console, require an instance of String, but they will try sending to_s first, before rejecting the argument.

These are sometimes called "implicit conversions", but they have nothing to do with implicit conversions as in Scala or implicit casts as in C♯. They are in fact not even part of the language, they are just a convention for library writers.

Ruby How To Create Ranges From Custom Objects Docs?

The Pickaxe Book (AKA "Programming Ruby") has this to say about Range:

So far we've shown ranges of numbers and strings. However, as you'd expect from an object-oriented language, Ruby can create ranges based on objects that you define. The only constraints are that the objects must respond to succ by returning the next object in sequence and the objects must be comparable using <=>, the general comparison operator.

Emphasis mine. You have to be careful though, the Pickaxe that you'll find online is rather old and sometimes it doesn't agree with the current state of Ruby. There is an updated version for Ruby 1.9 but I don't think that one is freely available online so you'd have to buy a copy.

I usually end up digging through the Ruby source to figure out a lot of these things. That applies doubly so to Rails.

How can I convert a step-down range to array?

1000.downto(0).each { |i| ... }        


Related Topics



Leave a reply



Submit