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"
- You need to convert range to array with
to_a
. - 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 aRange
object, andb
is anArray
object. The official(?) documentation for the Class Range does not document the methodto_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
Model Using Modules in Rails Application
Is Time.Zone.Now.To_Date Equivalent to Date.Today
How to Install 'Cocoapods' Gem from Rubygems.Org (Bad Response Backend Read Error)
Ruby on Rails: Yielding Specific Views in a Specific Places in the Layout
Accepts_Nested_Attributes_For Rails 4 Is Not Deleting
Differencebetween "Be_True" and "Be True" in Rspec
How to Use Rspec Expectations in Irb
Ruby: Creating a Hash Key and Value from a Variable in Ruby
Changing Active Model Serializers Default Adapter
Most Efficient Way to Calculate Hamming Distance in Ruby
What Is a Robust Installation Process for Nokogiri (On Ubuntu)
Define_Method: How to Dynamically Create Methods with Arguments
How to Generate PDF from Markdown Using Pure Ruby
What Is the Activemodel Method Attribute "_Was" Used For
Heroku: No Rakefile Found (But Works Locally)
What's the Difference Between Bundle.Setup and Bundle.Require
What's the Difference Between Ruby Core API and Standard Library API