"Functional programming" can mean one of three things.
1. Higher-order programming: the use of higher-order functions to make code more general/compact. Since you know Ruby, you're already doing some higher-order programming, but you may not understand it well enough to take full advantage of it. The best way to learn higher-order programming is to read SICP.
2. The use of immutable (aka persistent, nondestructive) data structures, i.e. data structures that can be updated without mutation. For example, linked lists allow you to prepend an element without changing the original list. This makes code cleaner in some cases and has advantages for concurrency. For specifics, look up Clojure.
3. Functional purity, aka referential transparency: the property that, for any input x, a function must always produce the same output x'. That is, all functions must be functions in the mathematical sense of the word. In practice, this doesn't really mean eliminating impure functions, but rather partitioning your program into "provably pure functions" and "possibly impure functions," using a clever hack (monads) to ensure that the output of possibly-impure functions is invisible to the provably-pure ones.
So, supposing you had a pure function whose behavior you wanted to randomize, you couldn't just throw in a call to the random() function, but would also have to convert it and all the functions that depend on it into impure (monadic) functions, replacing all function calls with the bind operator (>>=). It's quite complicated and I have never found a reason to believe it's a good idea, other than some theoretical stuff about "safety" and compiler optimizations that make your program 2% faster. I suggest not wasting your time on it.