DEV Community

vamsi pavan mahesh gunturu
vamsi pavan mahesh gunturu

Posted on

Sample in a Range

I wanted to get a sample from 1 to 10, when I was writing a test case. So as a believer in ruby magic, I just did .sample on Range 1..10. It did not work! I got this

2.5.7 :005 > (1..10).sample
Traceback (most recent call last):
        1: from (irb):5
NoMethodError (undefined method `sample' for 1..10:Range)

Okay, cool! Maybe there is a random method. So I called .random on the Range. Nope, that did not work either

2.5.7 :004 > (1..10).random
Traceback (most recent call last):
        1: from (irb):4
NoMethodError (undefined method `random' for 1..10:Range)

What, are you serious? This should have been there right? Well, turns out the only way to get this working is by doing rand(1..10). But this is not very object-oriented, is it? So how can we make this object-oriented?

Enter Open Classes, In ruby .. you can open whatever the class the language provides and put your own methods in it, as long as you are not breaking the language

class Range
  def sample
    rand(self)
  end
end

Now things work as expected

2.5.7 :011 > (1..10).sample
 => 5

Explanation:

What did I just do there in the above example?

I opened Range class, declared an instance method called sample. Inside it, I am calling rand with self as an argument. When you use (1..10) it's just a syntactic sugar of the representation Range.new(1,10). So basically (1..10) is an instance of the Range class. Hence by defining an instance method sample, I made it available to be called on our object (1..10).

Hope, this cleared things up. Happy programming :)

Top comments (2)

Collapse
 
ben profile image
Ben Halpern

Nice explanation

Collapse
 
aaronc81 profile image
Aaron Christiansen

Awesome; I didn't know that the rand function could optionally take a range! Thanks for sharing this.