My strategy has been to fork a codebase that utilizes whatever framework or language I'm trying to learn and work backwards. It's often enough a feat in itself just to get the thing to run locally. Once I've got it running, I just start breaking things to learn how all of the pieces work. I've always liked employing a "top-down" approach, where I start with something complex and then figure out how it works.
The dissection, vivisection approach is great paring for doing micro experiments with the technology. As the act of creation and scientific exploration are different, they require different thinking patterns that give the other parts of your brain a rest.
I just got a program in racket up and running, and not knowing the program or Racket, I hooked up http://docs.racket-lang.org/reference/debugging.html and started to map out the transform and flow of data through the system.