Reputation: 1364
Let's say I want to access an element of an array at a random index this way:
[1, 2, 3, 4].at(rand(4))
Is there a way to pass the size of the array like the following?
[1, 2, 3, 4].at(rand(le_object.self.size))
Why would I do that?--A great man once said: Science isn't about why, it is about why not.
Upvotes: 4
Views: 230
Reputation: 114138
Not recommended, but instance_eval
would somehow work:
[1, 2, 3, 4].instance_eval { at(rand(size)) }
And you can also break
out of tap
:
[1, 2, 3, 4].tap { |a| break a.at(rand(a.size)) }
There's an open feature request to add a method that yields self
and returns the block's result. If that makes it into Ruby, you could write:
[1, 2, 3, 4].insert_method_name_here { |a| a.at(rand(a.size)) }
Upvotes: 4
Reputation: 18762
You can use instance_eval
to execute ruby code with the binding of the array variable
[1, 2, 3, 4].instance_eval { at(rand(size)) }
Assuming you are interested in a random element as Array#at
returns an element at given index, you can use Array#sample
to pick a random element from an array.
[1,2,3,4].sample
#=> 3
If you do not want to use instance_eval
(or any form of eval
), then, you can add a method to Array
class by monkey patching - generally speaking, I am not sure whether it's a wise idea to monkey patch though
class Array
def random_index
rand(size)
end
end
["a","b","c","d"].random_index
#=> 2
Upvotes: 2
Reputation: 230286
No, you can't do that. Receiver of a method (that array) is not accessible by some special name at the call site. Your best bet is assigning a name to that object.
ary = [1, 2, 3, 4]
ary.at(rand(ary.size))
Of course, if all you need is a random element, then .sample
should be used. Which does not require evaluation of any arguments at the call site and its self
is the array.
Upvotes: 4
Reputation: 2051
You could do something similar with lambda:
getrand = ->(x) { x[rand(x.count)] }
getrand.call [1,2,3]
# => 2
Upvotes: 1