Mark Hubbart <discord / mac.com> writes:

> On Mar 6, 2004, at 10:29 AM, David A. Black wrote:
>
>> Hi --
>>
>> On Sun, 7 Mar 2004, Joel VanderWerf wrote:
>>
>>> Hal Fulton wrote:
>>>> Someone suggested allowing not just rand(Fixnum) and rand(Range)
>>>> but in general rand(Enumerable).
>>>
>>> Would be tricky for general Enumerables...
>>>
>>>    class Seq
>>>      include Enumerable
>>>      def each
>>>        i = 0
>>>        loop do
>>>          yield i
>>>          i += 1
>>>        end
>>>      end
>>>    end
>>
>> I'm not quite following (?) -- I think the original idea was
>> something like:
>>
>>   module Enumerable
>>     def rand
>>       to_a[Kernel.rand(size)]
>>     end
>>   end

No Enumerable#size.  Try:

module Enumerable
    ## Return a random element, or nil if empty.
    def rand
        i = 1
        ret = nil
        each do |el|
            if Kernel.rand(i) == 0
                ret = el
            end
            i += 1
        end
        return ret
    end
end

>
> Please don't redefine a Kernel method. I think that's a Bad Idea(tm). 
> Why not use #random instead?
>
>      >> module Enumerable
>      >>   def random
>      >>     to_a[rand(size)]
>      >>   end
>      >> end
>     => nil
>      >> [1,4,6].random
>     => 4
>      >> [1,4,6].random
>     => 6
>
> It would look like an attribute rather than a method... that is, it 
> would fit in with #first and #last.
>
> OTOH, I also like the other idea, using #pick and #pick!. #random! just 
> doens't make sense, and one method for plucking a random element out of 
> an array would be nice.

FWIW, I'm not really for #pick with no args meaning "pick a random
element".  There's no notion of randomness in "pick".  I'd expect it
to pick an _arbitrary_ element rather than a random one.  Perhaps
#rand and #pop_random or #delete_at(:random) or something.  (#pick!
wouldn't make sense in Enumerable anyway.)